Merge branch 'fixes-roundup3' into 'develop'

Fixes Roundup 3

See merge request pleroma/pleroma-fe!2013
This commit is contained in:
HJ 2025-01-28 14:54:05 +00:00
commit 753f5fa65d
43 changed files with 314 additions and 269 deletions

View file

@ -9,7 +9,7 @@ var ora = require('ora')
var webpack = require('webpack')
var webpackConfig = require('./webpack.prod.conf')
console.log(
console.info(
' Tip:\n' +
' Built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'

View file

@ -27,14 +27,12 @@ module.exports = function () {
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
console.warn(chalk.yellow('\nTo use this template, you must update following to modules:\n'))
for (var i = 0; i < warnings.length; i++) {
var warning = warnings[i]
console.log(' ' + warning)
console.warn(' ' + warning)
}
console.log()
console.warn()
process.exit(1)
}
}

View file

@ -72,10 +72,10 @@ app.use(staticPath, express.static('./static'))
module.exports = app.listen(port, function (err) {
if (err) {
console.log(err)
console.error(err)
return
}
var uri = 'http://localhost:' + port
console.log('Listening at ' + uri + '\n')
console.info('Listening at ' + uri + '\n')
// opn(uri)
})

View file

@ -23,7 +23,8 @@ module.exports = merge(baseWebpackConfig, {
'COMMIT_HASH': JSON.stringify('DEV'),
'DEV_OVERRIDES': JSON.stringify(config.dev.settings),
'__VUE_OPTIONS_API__': true,
'__VUE_PROD_DEVTOOLS__': false
'__VUE_PROD_DEVTOOLS__': false,
'__VUE_PROD_HYDRATION_MISMATCH_DETAILS__': false
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.HotModuleReplacementPlugin(),

View file

@ -50,7 +50,8 @@ var webpackConfig = merge(baseWebpackConfig, {
'COMMIT_HASH': JSON.stringify(commitHash),
'DEV_OVERRIDES': JSON.stringify(undefined),
'__VUE_OPTIONS_API__': true,
'__VUE_PROD_DEVTOOLS__': false
'__VUE_PROD_DEVTOOLS__': false,
'__VUE_PROD_HYDRATION_MISMATCH_DETAILS__': false
}),
// extract css into its own file
new MiniCssExtractPlugin({

View file

View file

@ -8,10 +8,10 @@ try {
// and that's how actual BE reports its url
settings.target = settings.target.replace(/\/$/, '')
}
console.log('Using local dev server settings (/config/local.json):')
console.log(JSON.stringify(settings, null, 2))
console.info('Using local dev server settings (/config/local.json):')
console.info(JSON.stringify(settings, null, 2))
} catch (e) {
console.log('Local dev server settings not found (/config/local.json)')
console.info('Local dev server settings not found (/config/local.json)')
}
const target = settings.target || 'http://localhost:4000/'

View file

@ -174,8 +174,7 @@ const getTOS = async ({ store }) => {
throw (res)
}
} catch (e) {
console.warn("Can't load TOS")
console.warn(e)
console.warn("Can't load TOS\n", e)
}
}
@ -189,8 +188,7 @@ const getInstancePanel = async ({ store }) => {
throw (res)
}
} catch (e) {
console.warn("Can't load instance panel")
console.warn(e)
console.warn("Can't load instance panel\n", e)
}
}
@ -220,8 +218,7 @@ const getStickers = async ({ store }) => {
throw (res)
}
} catch (e) {
console.warn("Can't load stickers")
console.warn(e)
console.warn("Can't load stickers\n", e)
}
}

View file

@ -3,6 +3,9 @@ import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
import { getBookmarkFolderEntries } from 'src/components/navigation/filter.js'
export const BookmarkFoldersMenuContent = {
props: [
'showPin'
],
components: {
NavigationEntry
},

View file

@ -7,10 +7,12 @@
label: 'nav.all_bookmarks',
icon: 'bookmark'
}"
:show-pin="showPin"
/>
<NavigationEntry
v-for="item in folders"
:key="item.id"
:show-pin="showPin"
:item="item"
/>
</ul>

View file

@ -5,7 +5,7 @@ import ConfirmModal from './confirm_modal.vue'
import Select from 'src/components/select/select.vue'
export default {
props: ['type', 'user'],
props: ['type', 'user', 'status'],
emits: ['hide', 'show', 'muted'],
data: () => ({
showing: false,
@ -61,9 +61,7 @@ export default {
},
methods: {
optionallyPrompt () {
console.log('Triggered')
if (this.shouldConfirm) {
console.log('SHAWN!!')
this.show()
} else {
this.doMute()

View file

@ -162,7 +162,6 @@ const EmojiPicker = {
} else {
emojiSizeReal = emojiSizeValue
}
console.log(emojiSizeReal)
const fullEmojiSize = emojiSizeReal + (2 * 0.2 * fontSizeMultiplier * 14)
this.emojiSize = fullEmojiSize
@ -319,7 +318,6 @@ const EmojiPicker = {
return this.emojiSize
},
itemPerRow () {
console.log('CALC', this.emojiSize, this.width)
return this.width ? Math.floor(this.width / this.emojiSize) : 6
},
activeGroupView () {

View file

@ -32,22 +32,24 @@
<p>{{ $t("about.mrf.simple.accept_desc") }}</p>
<table>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in acceptInstances"
:key="entry.instance + '_accept'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
<tbody>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in acceptInstances"
:key="entry.instance + '_accept'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
</tbody>
</table>
</div>
@ -57,22 +59,24 @@
<p>{{ $t("about.mrf.simple.reject_desc") }}</p>
<table>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in rejectInstances"
:key="entry.instance + '_reject'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
<tbody>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in rejectInstances"
:key="entry.instance + '_reject'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
</tbody>
</table>
</div>
@ -82,22 +86,24 @@
<p>{{ $t("about.mrf.simple.quarantine_desc") }}</p>
<table>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in quarantineInstances"
:key="entry.instance + '_quarantine'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
<tbody>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in quarantineInstances"
:key="entry.instance + '_quarantine'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
</tbody>
</table>
</div>
@ -107,22 +113,24 @@
<p>{{ $t("about.mrf.simple.ftl_removal_desc") }}</p>
<table>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in ftlRemovalInstances"
:key="entry.instance + '_ftl_removal'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
<tbody>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in ftlRemovalInstances"
:key="entry.instance + '_ftl_removal'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
</tbody>
</table>
</div>
@ -132,22 +140,24 @@
<p>{{ $t("about.mrf.simple.media_nsfw_desc") }}</p>
<table>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in mediaNsfwInstances"
:key="entry.instance + '_media_nsfw'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
<tbody>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in mediaNsfwInstances"
:key="entry.instance + '_media_nsfw'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
</tbody>
</table>
</div>
@ -157,22 +167,24 @@
<p>{{ $t("about.mrf.simple.media_removal_desc") }}</p>
<table>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in mediaRemovalInstances"
:key="entry.instance + '_media_removal'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
<tbody>
<tr>
<th>{{ $t("about.mrf.simple.instance") }}</th>
<th>{{ $t("about.mrf.simple.reason") }}</th>
</tr>
<tr
v-for="entry in mediaRemovalInstances"
:key="entry.instance + '_media_removal'"
>
<td>{{ entry.instance }}</td>
<td v-if="entry.reason === ''">
{{ $t("about.mrf.simple.not_applicable") }}
</td>
<td v-else>
{{ entry.reason }}
</td>
</tr>
</tbody>
</table>
</div>

View file

@ -113,6 +113,7 @@
:class="{ '-expanded': showBookmarkFolders }"
>
<BookmarkFoldersMenuContent
:show-pin="editMode || forceEditMode"
class="timelines"
/>
</div>

View file

@ -1,6 +1,8 @@
import { mapState } from 'vuex'
import { TIMELINES, ROOT_ITEMS, routeTo } from 'src/components/navigation/navigation.js'
import { getListEntries, filterNavigation } from 'src/components/navigation/filter.js'
import { getBookmarkFolderEntries, getListEntries, filterNavigation } from 'src/components/navigation/filter.js'
import StillImage from 'src/components/still-image/still-image.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
@ -34,12 +36,16 @@ const NavPanel = {
return routeTo(item, this.currentUser)
}
},
components: {
StillImage
},
computed: {
getters () {
return this.$store.getters
},
...mapState({
lists: getListEntries,
bookmarks: getBookmarkFolderEntries,
currentUser: state => state.users.currentUser,
followRequestCount: state => state.api.followRequests.length,
privateMode: state => state.instance.private,
@ -70,6 +76,7 @@ const NavPanel = {
.filter(([k]) => this.pinnedItems.has(k))
.map(([k, v]) => ({ ...v, name: k })),
...this.lists.filter((k) => this.pinnedItems.has(k.name)),
...this.bookmarks.filter((k) => this.pinnedItems.has(k.name)),
...Object
.entries({ ...ROOT_ITEMS })
.filter(([k]) => this.pinnedItems.has(k))

View file

@ -14,9 +14,14 @@
:icon="item.icon"
/>
<span
v-if="item.iconLetter"
v-if="item.iconLetter && !item.iconEmoji"
class="iconLetter fa-scale-110 fa-old-padding"
>{{ item.iconLetter }}</span>
<StillImage
v-if="item.iconEmoji"
class="bookmark-emoji"
:src="item.iconEmojiUrl"
/>
<div
v-if="item.badgeGetter && getters[item.badgeGetter]"
class="badge -dot"
@ -52,6 +57,13 @@
box-sizing: border-box;
height: 100%;
.bookmark-emoji {
height: 100%;
box-sizing: border-box;
padding: 0.5em;
}
& .bookmark-emoji,
& .svg-inline--fa,
& .iconLetter {
margin: 0;

View file

@ -3,7 +3,6 @@
trigger="click"
class="QuickViewSettings"
:bound-to="{ x: 'container' }"
:trigger-attrs="triggerAttrs"
>
<template #content>
<div

View file

@ -8,6 +8,10 @@
--funtextGreentext: var(--funtextGreentextFaint) !important;
--funtextCyantext: var(--funtextCyantextFaint) !important;
/* stylelint-enable declaration-no-important */
a {
color: var(--linkFaint);
}
}
blockquote {

View file

@ -30,6 +30,11 @@ const GeneralTab = {
value: mode,
label: this.$t(`settings.conversation_display_${mode}`)
})),
absoluteTime12hOptions: ['24h', '12h'].map(mode => ({
key: mode,
value: mode,
label: this.$t(`settings.absolute_time_format_12h_${mode}`)
})),
conversationOtherRepliesButtonOptions: ['below', 'inside'].map(mode => ({
key: mode,
value: mode,

View file

@ -249,6 +249,16 @@
{{ $t('settings.absolute_time_format_min_age') }}
</UnitSetting>
</li>
<li>
<ChoiceSetting
id="absoluteTime12h"
path="absoluteTime12h"
:options="absoluteTime12hOptions"
:expert="1"
>
{{ $t('settings.absolute_time_format_12h') }}
</ChoiceSetting>
</li>
</ul>
<h3>{{ $t('settings.attachments') }}</h3>
<li>
@ -462,22 +472,6 @@
{{ $t('settings.minimal_scopes_mode') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting
path="alwaysShowNewPostButton"
expert="1"
>
{{ $t('settings.always_show_post_button') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting
path="autohideFloatingPostButton"
expert="1"
>
{{ $t('settings.autohide_floating_post_button') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting
path="padEmoji"
@ -501,7 +495,7 @@
{{ $t('settings.auto_save_draft') }}
</BooleanSetting>
</li>
<li v-if="!autoSaveDraft">
<li v-if="!mergedConfig.autoSaveDraft">
<ChoiceSetting
id="unsavedPostAction"
path="unsavedPostAction"

View file

@ -130,7 +130,7 @@ export default {
const serialized = this.cValue.map(x => serializeShadow(x)).join(',')
serialized.split(/,/).map(deserializeShadow) // validate
const expandedShadow = flattenDeep(findShadow(this.cValue, { dynamicVars: {}, staticVars: this.staticVars }))
const fixedShadows = expandedShadow.map(x => ({ ...x, color: console.log(x) || rgb2hex(x.color) }))
const fixedShadows = expandedShadow.map(x => ({ ...x, color: rgb2hex(x.color) }))
if (this.separateInset) {
result = {

View file

@ -255,7 +255,7 @@ const Status = {
muteReasons () {
return [
this.userIsMuted ? 'user' : null,
status.thread_muted ? 'thread' : null,
this.status.thread_muted ? 'thread' : null,
(this.muteWordHits.length > 0) ? 'wordfilter' : null,
(this.muteBotStatuses && this.botStatus) ? 'bot' : null,
(this.muteSensitiveStatuses && this.sensitiveStatus) ? 'nsfw' : null
@ -280,14 +280,18 @@ const Status = {
case 'nsfw': return this.$t('status.sensitive_muted')
}
}
return this.$t(
'status.multi_reason_mute',
{
main: mainReason(),
numReasonsMore: this.muteReasons.length - 1
},
this.muteReasons.length - 1
)
if (this.muteReasons.length > 1) {
return this.$t(
'status.multi_reason_mute',
{
main: mainReason(),
numReasonsMore: this.muteReasons.length - 1
},
this.muteReasons.length - 1
)
} else {
return mainReason()
}
},
muted () {
if (this.statusoid.user.id === this.currentUser.id) return false
@ -299,9 +303,9 @@ const Status = {
const { reblog } = status
const relationship = this.$store.getters.relationship(status.user.id)
const relationshipReblog = reblog && this.$store.getters.relationship(reblog.user.id)
return status.muted ||
return (status.muted && !status.thread_muted) ||
// Reprööt of a muted post according to BE
(reblog && reblog.muted) ||
(reblog && reblog.muted && !reblog.thread_muted) ||
// Muted user
relationship.muting ||
// Muted user of a reprööt

View file

@ -92,6 +92,9 @@ export default {
threadIsMuted () {
return this.status.thread_muted
},
hideCustomEmoji () {
return !this.$store.state.instance.pleromaCustomEmojiReactionsAvailable
},
buttonInnerClass () {
return [
this.button.name + '-button',

View file

@ -2,9 +2,9 @@
/* stylelint-disable declaration-no-important */
.quick-action {
display: grid;
grid-template-columns: minmax(max-content, 1fr);
grid-gap: 0.25em;
justify-content: space-between;
display: flex;
align-items: baseline;
align-items: center;
height: 1.5em;
@ -12,6 +12,7 @@
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-left: 1em;
}
.action-button-inner,
@ -25,6 +26,7 @@
align-self: stretch;
width: 1px;
background-color: var(--icon);
margin-left: 1em;
margin-right: 0.5em;
}
@ -35,6 +37,7 @@
border-radius: var(--roundness);
grid-template-columns: minmax(max-content, 1fr) auto;
.chevron-icon,
.extra-button,
.separator {
display: none;
@ -44,10 +47,30 @@
.action-button-inner {
display: grid;
grid-gap: 1em;
grid-template-columns: max-content 1fr;
grid-template-columns: max-content;
grid-auto-flow: column;
grid-auto-columns: max-content;
align-items: center;
@include unfocused-style {
.focus-marker {
visibility: hidden;
}
.active-marker {
visibility: visible;
}
}
@include focused-style {
.focus-marker {
visibility: visible;
}
.active-marker {
visibility: hidden;
}
}
}
}
@ -79,24 +102,4 @@
}
}
}
@include unfocused-style {
.focus-marker {
visibility: hidden;
}
.active-marker {
visibility: visible;
}
}
@include focused-style {
.focus-marker {
visibility: visible;
}
.active-marker {
visibility: hidden;
}
}
}

View file

@ -9,6 +9,7 @@
:class="buttonInnerClass"
role="menuitem"
type="button"
:title="$t(button.label(funcArg))"
target="_blank"
:tabindex="0"
:disabled="buttonClass.disabled"
@ -50,12 +51,6 @@
>
{{ $t(button.label(funcArg)) }}
</span>
<span
v-if="!extra && button.counter?.(funcArg) > 0"
class="action-counter"
>
{{ button.counter?.(funcArg) }}
</span>
<FAIcon
v-if="button.dropdown?.()"
class="chevron-icon"
@ -64,15 +59,21 @@
fixed-width
/>
</component>
<span
v-if="!extra && button.counter?.(funcArg) > 0"
class="action-counter"
>
{{ button.counter?.(funcArg) }}
</span>
<span
v-if="!extra && button.name === 'bookmark'"
class="separator"
/>
<Popover
v-if="button.name === 'bookmark'"
trigger="hover"
:trigger="extra ? 'hover' : 'click'"
:placement="extra ? 'right' : 'top'"
:offset="{ y: 5 }"
:offset="extra ? { x: 10 } : { y: 10 }"
:trigger-attrs="{ class: 'extra-button' }"
>
<template #trigger>

View file

@ -58,8 +58,8 @@ export default {
unmuteUser () {
return this.$store.dispatch('unmuteUser', this.user.id)
},
unmuteThread () {
return this.$store.dispatch('unmuteConversation', this.user.id)
unmuteConversation () {
return this.$store.dispatch('unmuteConversation', { id: this.status.id })
},
unmuteDomain () {
return this.$store.dispatch('unmuteDomain', this.user.id)

View file

@ -2,7 +2,7 @@
<div>
<Popover
v-if="button.dropdown?.()"
trigger="hover"
:trigger="$attrs.extra ? 'hover' : 'click'"
:offset="{ y: 5 }"
:placement="$attrs.extra ? 'right' : 'top'"
>
@ -40,13 +40,13 @@
<div class="menu-item dropdown-item extra-action -icon">
<button
class="main-button"
@click="toggleUserMute"
@click="toggleConversationMute"
>
<FAIcon
icon="folder-tree"
fixed-width
/>
<template v-if="threadIsMuted">
<template v-if="conversationIsMuted">
{{ $t('status.unmute_conversation') }}
</template>
<template v-else>
@ -81,19 +81,22 @@
v-bind="$attrs"
/>
<teleport to="#modal">
<mute-confirm
<MuteConfirm
ref="confirmConversation"
type="conversation"
:status="status"
/>
<mute-confirm
ref="confirmDomain"
type="domain"
:user="user"
/>
<mute-confirm
<MuteConfirm
ref="confirmDomain"
type="domain"
:status="status"
:user="user"
/>
<MuteConfirm
ref="confirmUser"
type="user"
:status="status"
:user="user"
/>
</teleport>

View file

@ -51,9 +51,6 @@ const StatusActionButtons = {
currentUser () {
return this.$store.state.users.currentUser
},
hideCustomEmoji () {
return !this.$store.state.instance.pleromaCustomEmojiReactionsAvailable
},
funcArg () {
return {
status: this.status,
@ -71,7 +68,6 @@ const StatusActionButtons = {
return {
title: this.$t('status.more_actions'),
'aria-controls': `popup-menu-${this.randomSeed}`,
'aria-expanded': this.expanded,
'aria-haspopup': 'menu'
}
}

View file

@ -3,12 +3,11 @@
.StatusActionButtons {
.quick-action-buttons {
display: grid;
grid-template-columns: repeat(auto-fill, 5em);
grid-template-columns: repeat(auto-fill, 4em);
grid-auto-flow: row dense;
grid-auto-rows: 1fr;
grid-gap: 1.25em 1em;
margin-top: var(--status-margin);
align-items: baseline;
}
.pin-action-button {

View file

@ -28,6 +28,9 @@ export default {
}
return DateUtils.durationStrToMs(this.$store.getters.mergedConfig.absoluteTimeFormatMinAge) <= this.relativeTimeMs
},
time12hFormat () {
return this.$store.getters.mergedConfig.absoluteTimeFormat12h === '12h'
},
browserLocale () {
return localeService.internalToBrowserLocale(this.$i18n.locale)
},
@ -57,22 +60,26 @@ export default {
if (DateUtils.isSameDay(this.timeAsDate, now)) {
return new Intl.DateTimeFormat(this.browserLocale, {
minute: 'numeric',
hour: 'numeric'
hour: 'numeric',
hour12: this.time12hFormat
})
} else if (DateUtils.isSameMonth(this.timeAsDate, now)) {
return new Intl.DateTimeFormat(this.browserLocale, {
month: 'short',
day: 'numeric'
day: 'numeric',
hour12: this.time12hFormat
})
} else if (DateUtils.isSameYear(this.timeAsDate, now)) {
return new Intl.DateTimeFormat(this.browserLocale, {
month: 'short',
day: 'numeric'
day: 'numeric',
hour12: this.time12hFormat
})
} else {
return new Intl.DateTimeFormat(this.browserLocale, {
year: 'numeric',
month: 'short'
month: 'short',
hour12: this.time12hFormat
})
}
})()

View file

@ -311,7 +311,7 @@
/>
</div>
<teleport to="#modal">
<mute-confirm
<MuteConfirm
ref="confirmation"
type="user"
:user="user"

View file

@ -2,23 +2,23 @@
const arg = process.argv[2]
if (typeof arg === 'undefined') {
console.log('This is a very simple and tiny tool that checks en.json with any other language and')
console.log('outputs all the things present in english but missing in foreign language.')
console.log('')
console.log('Usage: ./compare.js <lang> ')
console.log(' or')
console.log(' node ./compare.js <lang>')
console.log('')
console.log('Where <lang> is name of .json file containing language. For ./fi.json it should be:')
console.log(' ./compare.js fi ')
console.log('')
console.log('Limitations: ')
console.log('* This program does not work with languages left over in messages.js')
console.log('* This program does not check for extra strings present in foreign language but missing')
console.log(' in english.js (for now)')
console.log('')
console.log('There are no other arguments or options. Make an issue if you encounter a bug or want')
console.log('some feature to be implemented. Merge requests are welcome as well.')
console.info('This is a very simple and tiny tool that checks en.json with any other language and')
console.info('outputs all the things present in english but missing in foreign language.')
console.info('')
console.info('Usage: ./compare.js <lang> ')
console.info(' or')
console.info(' node ./compare.js <lang>')
console.info('')
console.info('Where <lang> is name of .json file containing language. For ./fi.json it should be:')
console.info(' ./compare.js fi ')
console.info('')
console.info('Limitations: ')
console.info('* This program does not work with languages left over in messages.js')
console.info('* This program does not check for extra strings present in foreign language but missing')
console.info(' in english.js (for now)')
console.info('')
console.info('There are no other arguments or options. Make an issue if you encounter a bug or want')
console.info('some feature to be implemented. Merge requests are welcome as well.')
process.exit()
}
@ -35,10 +35,10 @@ function walker (a, b, path = []) {
const article = aType[0] === 'o' ? 'an' : 'a'
if (bType === 'undefined') {
console.log(`Foreign language is missing ${article} ${aType} at path ${currentPath.join('.')}`)
console.warn(`Foreign language is missing ${article} ${aType} at path ${currentPath.join('.')}`)
} else if (aType === 'object') {
if (bType !== 'object') {
console.log(`Type mismatch! English has ${aType} while foreign has ${bType} at path ${currentPath.join['.']}`)
console.warn(`Type mismatch! English has ${aType} while foreign has ${bType} at path ${currentPath.join['.']}`)
} else {
walker(aVal, bVal, currentPath)
}

View file

@ -532,6 +532,9 @@
"emoji_reactions_scale": "Reactions scale factor",
"absolute_time_format": "Use absolute time format",
"absolute_time_format_min_age": "Only use for time older than this amount of time",
"absolute_time_format_12h": "Time format",
"absolute_time_format_12h_12h": "12 hour format (i.e. 10:00 PM)",
"absolute_time_format_12h_24h": "24 hour format (i.e. 22:00)",
"export_theme": "Save preset",
"filtering": "Filtering",
"wordfilter": "Wordfilter",
@ -1256,7 +1259,7 @@
"copy_link": "Copy link to status",
"external_source": "External source",
"muted_words": "Wordfiltered: {word} | Wordfiltered: {word} and {numWordsMore} more words",
"multi_reason_mute": "{main} | {main} + one more reason | {main} + {numReasonsMore} more reasons",
"multi_reason_mute": "{main} + one more reason | {main} + {numReasonsMore} more reasons",
"muted_user": "User muted",
"thread_muted": "Thread muted",
"thread_muted_and_words": ", has words:",

View file

@ -193,6 +193,7 @@ export const defaultState = {
autoSaveDraft: undefined, // instance default
useAbsoluteTimeFormat: undefined, // instance default
absoluteTimeFormatMinAge: undefined, // instance default
absoluteTime12h: undefined, // instance default
imageCompression: true
}

View file

@ -131,6 +131,7 @@ const defaultState = {
autoSaveDraft: false,
useAbsoluteTimeFormat: false,
absoluteTimeFormatMinAge: '0d',
absoluteTime12h: '24h',
// Nasty stuff
customEmoji: [],
@ -314,8 +315,7 @@ const instance = {
}, {})
commit('setInstanceOption', { name: 'emoji', value: injectRegionalIndicators(emoji) })
} catch (e) {
console.warn("Can't load static emoji")
console.warn(e)
console.warn("Can't load static emoji\n", e)
}
},
@ -382,8 +382,7 @@ const instance = {
throw (res)
}
} catch (e) {
console.warn("Can't load custom emojis")
console.warn(e)
console.warn("Can't load custom emojis\n", e)
}
},
fetchEmoji ({ dispatch, state }) {
@ -404,8 +403,7 @@ const instance = {
})
commit('setKnownDomains', result)
} catch (e) {
console.warn("Can't load known domains")
console.warn(e)
console.warn("Can't load known domains\n", e)
}
}
}

View file

@ -9,7 +9,8 @@ import {
groupBy,
findLastIndex,
takeRight,
uniqWith
uniqWith,
merge as _merge
} from 'lodash'
import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js'
@ -127,14 +128,8 @@ export const _getRecentData = (cache, live, isTest) => {
_version: a._version ?? b._version,
_timestamp: a._timestamp ?? b._timestamp,
needUpload: b.needUpload ?? a.needUpload,
prefsStorage: {
...a.prefsStorage,
...b.prefsStorage
},
flagStorage: {
...a.flagStorage,
...b.flagStorage
}
prefsStorage: _merge(a.prefsStorage, b.prefsStorage),
flagStorage: _merge(a.flagStorage, b.flagStorage)
})
result.recent = isTest ? result.recent : (result.recent && merge(defaultState, result.recent))
result.stale = isTest ? result.stale : (result.stale && merge(defaultState, result.stale))
@ -315,7 +310,7 @@ export const mutations = {
state.raw = live
let cache = state.cache
if (cache && cache._user !== userData.fqn) {
console.warn('cache belongs to another user! reinitializing local cache!')
console.warn('Cache belongs to another user! reinitializing local cache!')
cache = null
}

View file

@ -276,8 +276,8 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
// NOOP, it is known status but we don't do anything about it for now
},
default: (unknown) => {
console.log('unknown status type')
console.log(unknown)
console.warn('unknown status type')
console.warn(unknown)
}
}
@ -549,11 +549,11 @@ const statuses = {
rootState.api.backendInteractor.unpinOwnStatus({ id: statusId })
.then((status) => dispatch('addNewStatuses', { statuses: [status] }))
},
muteConversation ({ rootState, commit }, statusId) {
muteConversation ({ rootState, commit }, { id: statusId }) {
return rootState.api.backendInteractor.muteConversation({ id: statusId })
.then((status) => commit('setMutedStatus', status))
},
unmuteConversation ({ rootState, commit }, statusId) {
unmuteConversation ({ rootState, commit }, { id: statusId }) {
return rootState.api.backendInteractor.unmuteConversation({ id: statusId })
.then((status) => commit('setMutedStatus', status))
},

View file

@ -1,7 +1,7 @@
import { invertLightness, contrastRatio, convert } from 'chromatism'
// useful for visualizing color when debugging
export const consoleColor = (color) => console.log('%c##########', 'background: ' + color + '; color: ' + color)
// const consoleColor = (color) => console.debug('%c##########', 'background: ' + color + '; color: ' + color)
/**
* Convert r, g, b values into hex notation. All components are [0-255]
@ -236,8 +236,8 @@ export const getTextColor = function (bg, text, preserve) {
let contrast = getContrastRatio(bg, text)
const result = convert(rgb2hex(workColor)).hsl
const delta = result.l > 50 ? 1 : -1
const multiplier = 10
const delta = result.l >= 50 ? 1 : -1
const multiplier = 1
while (contrast < 4.5 && result.l > 20 && result.l < 80) {
result.l += delta * multiplier
result.l = Math.min(100, Math.max(0, result.l))

View file

@ -3,7 +3,7 @@ import utf8 from 'utf8'
export const newExporter = ({
filename = 'data',
mime = 'application/json',
extension = '.json',
extension = 'json',
getExportedObject
}) => ({
exportData () {

View file

@ -95,9 +95,10 @@ export const tryLoadCache = async () => {
if (!data) return null
let cache
try {
const decoded = new TextDecoder().decode(pako.inflate(data))
const inflated = pako.inflate(data)
const decoded = new TextDecoder().decode(inflated)
cache = JSON.parse(decoded)
console.info(`Loaded theme from cache, size=${cache}`)
console.info(`Loaded theme from cache, compressed=${Math.ceil(data.length / 1024)}kiB size=${Math.ceil(inflated.length / 1024)}kiB`)
} catch (e) {
console.error('Failed to decode theme cache:', e)
return false

View file

@ -539,7 +539,6 @@ describe('RichContent', () => {
`,
props: ['handleLinks', 'attentions', 'vhtml']
}
console.log(1)
const ptest = (handleLinks, vhtml) => {
const t0 = performance.now()
@ -562,11 +561,11 @@ describe('RichContent', () => {
return `Mount: ${t1 - t0}ms, destroy: ${t2 - t1}ms, avg ${(t1 - t0) / amount}ms - ${(t2 - t1) / amount}ms per item`
}
console.log(`${amount} items with links handling:`)
console.log(ptest(true))
console.log(`${amount} items without links handling:`)
console.log(ptest(false))
console.log(`${amount} items plain v-html:`)
console.log(ptest(false, true))
console.debug(`${amount} items with links handling:`)
console.debug(ptest(true))
console.debug(`${amount} items without links handling:`)
console.debug(ptest(false))
console.debug(`${amount} items plain v-html:`)
console.debug(ptest(false, true))
})
})

View file

@ -21,17 +21,17 @@ describe('ISS (de)serialization', () => {
const onlyComponent = componentsContext('./components/panel_header.style.js').default
it.only(`(De)serialization of component ${onlyComponent.name} works`, () => {
const normalized = onlyComponent.defaultRules.map(x => ({ component: onlyComponent.name, ...x }))
console.log('BEGIN INPUT ================')
console.log(normalized)
console.log('END INPUT ==================')
console.debug('BEGIN INPUT ================')
console.debug(normalized)
console.debug('END INPUT ==================')
const serialized = serialize(normalized)
console.log('BEGIN SERIAL ===============')
console.log(serialized)
console.log('END SERIAL =================')
console.debug('BEGIN SERIAL ===============')
console.debug(serialized)
console.debug('END SERIAL =================')
const deserialized = deserialize(serialized)
console.log('BEGIN DESERIALIZED =========')
console.log(serialized)
console.log('END DESERIALIZED ===========')
console.debug('BEGIN DESERIALIZED =========')
console.debug(serialized)
console.debug('END DESERIALIZED ===========')
// for some reason comparing objects directly fails the assert
expect(JSON.stringify(deserialized, null, 2)).to.equal(JSON.stringify(normalized, null, 2))

View file

@ -60,7 +60,7 @@ const run = () => {
}, {})
fs.writeFile(outputFilename, JSON.stringify(sorted, null, 2), 'utf8', (err) => {
if (err) console.log('Error writing file', err)
if (err) console.error('Error writing file', err)
})
}