Merge branch 'fixes-batch' into 'develop'

Fixes batch

Closes #1321, #1286, and #1241

See merge request pleroma/pleroma-fe!1955
This commit is contained in:
HJ 2024-12-23 19:35:14 +00:00
commit 1cc9ff70e0
60 changed files with 286 additions and 144 deletions

View file

@ -0,0 +1 @@
fix emoji inconsistencies in notifications, fix some emoji not scaling with interface

View file

@ -0,0 +1 @@
proper sticky header for conversations on user page

View file

@ -0,0 +1 @@
reply-or-quote buttons now take less space

View file

@ -3,7 +3,6 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
<link rel="icon" type="image/png" href="/favicon.png">
<!-- putting styles here to avoid having to wait for styles to load up --> <!-- putting styles here to avoid having to wait for styles to load up -->
<style id="splashscreen"> <style id="splashscreen">
#splash { #splash {

View file

@ -86,6 +86,7 @@
<i18n-t <i18n-t
keypath="user_card.block_confirm" keypath="user_card.block_confirm"
tag="span" tag="span"
scope="global"
> >
<template #user> <template #user>
<span <span
@ -107,6 +108,7 @@
<i18n-t <i18n-t
keypath="user_card.remove_follower_confirm" keypath="user_card.remove_follower_confirm"
tag="span" tag="span"
scope="global"
> >
<template #user> <template #user>
<span <span

View file

@ -48,7 +48,7 @@
flex: 1 0; flex: 1 0;
margin: 0; margin: 0;
--emoji-size: 14px; --emoji-size: 1em;
&-collapsed-content { &-collapsed-content {
margin-left: 0.7em; margin-left: 0.7em;

View file

@ -17,6 +17,7 @@
<i18n-t <i18n-t
v-if="id" v-if="id"
keypath="bookmark_folders.editing_folder" keypath="bookmark_folders.editing_folder"
scope="global"
> >
<template #folderName> <template #folderName>
{{ name }} {{ name }}
@ -25,6 +26,7 @@
<i18n-t <i18n-t
v-else v-else
keypath="bookmark_folders.creating_folder" keypath="bookmark_folders.creating_folder"
scope="global"
/> />
</h1> </h1>
</div> </div>

View file

@ -32,7 +32,7 @@
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
--emoji-size: 14px; --emoji-size: 1em;
.username { .username {
max-width: 100%; max-width: 100%;

View file

@ -32,8 +32,8 @@
> >
</label> </label>
<label <label
class="y-shift-number"
v-show="shadowControl && !hideControls" v-show="shadowControl && !hideControls"
class="y-shift-number"
> >
{{ $t('settings.style.shadows.offset-y') }} {{ $t('settings.style.shadows.offset-y') }}
<input <input
@ -78,7 +78,10 @@
> >
{{ $t('settings.style.themes3.editor.test_string') }} {{ $t('settings.style.themes3.editor.test_string') }}
</div> </div>
<div v-if="invalid" class="invalid-container"> <div
v-if="invalid"
class="invalid-container"
>
<div class="alert error invalid-label"> <div class="alert error invalid-label">
{{ $t('settings.style.themes3.editor.invalid') }} {{ $t('settings.style.themes3.editor.invalid') }}
</div> </div>
@ -104,8 +107,8 @@
</div> </div>
<ColorInput <ColorInput
v-if="!noColorControl" v-if="!noColorControl"
class="input-color-input"
v-model="colorOverride" v-model="colorOverride"
class="input-color-input"
fallback="#606060" fallback="#606060"
:label="$t('settings.style.shadows.color_override')" :label="$t('settings.style.shadows.color_override')"
/> />

View file

@ -11,13 +11,22 @@
class="rating" class="rating"
> >
<span v-if="contrast.aaa"> <span v-if="contrast.aaa">
<FAIcon icon="thumbs-up" :size="showRatio ? 'lg' : ''" /> <FAIcon
icon="thumbs-up"
:size="showRatio ? 'lg' : ''"
/>
</span> </span>
<span v-if="!contrast.aaa && contrast.aa"> <span v-if="!contrast.aaa && contrast.aa">
<FAIcon icon="adjust" :size="showRatio ? 'lg' : ''" /> <FAIcon
icon="adjust"
:size="showRatio ? 'lg' : ''"
/>
</span> </span>
<span v-if="!contrast.aaa && !contrast.aa"> <span v-if="!contrast.aaa && !contrast.aa">
<FAIcon icon="exclamation-triangle" :size="showRatio ? 'lg' : ''" /> <FAIcon
icon="exclamation-triangle"
:size="showRatio ? 'lg' : ''"
/>
</span> </span>
</Tooltip> </Tooltip>
<Tooltip <Tooltip
@ -26,13 +35,22 @@
class="rating" class="rating"
> >
<span v-if="contrast.laaa"> <span v-if="contrast.laaa">
<FAIcon icon="thumbs-up" :size="showRatio ? 'large' : ''" /> <FAIcon
icon="thumbs-up"
:size="showRatio ? 'large' : ''"
/>
</span> </span>
<span v-if="!contrast.laaa && contrast.laa"> <span v-if="!contrast.laaa && contrast.laa">
<FAIcon icon="adjust" :size="showRatio ? 'lg' : ''" /> <FAIcon
icon="adjust"
:size="showRatio ? 'lg' : ''"
/>
</span> </span>
<span v-if="!contrast.laaa && !contrast.laa"> <span v-if="!contrast.laaa && !contrast.laa">
<FAIcon icon="exclamation-triangle" :size="showRatio ? 'lg' : ''" /> <FAIcon
icon="exclamation-triangle"
:size="showRatio ? 'lg' : ''"
/>
</span> </span>
</Tooltip> </Tooltip>
</span> </span>
@ -55,6 +73,9 @@ library.add(
) )
export default { export default {
components: {
Tooltip
},
props: { props: {
large: { large: {
required: false, required: false,
@ -74,9 +95,6 @@ export default {
default: false default: false
} }
}, },
components: {
Tooltip
},
computed: { computed: {
hint () { hint () {
const levelVal = this.contrast.aaa ? 'aaa' : (this.contrast.aa ? 'aa' : 'bad') const levelVal = this.contrast.aaa ? 'aaa' : (this.contrast.aa ? 'aa' : 'bad')

View file

@ -97,7 +97,7 @@ const EmojiPicker = {
enableStickerPicker: { enableStickerPicker: {
required: false, required: false,
type: Boolean, type: Boolean,
default: false default: true
}, },
hideCustomEmoji: { hideCustomEmoji: {
required: false, required: false,
@ -105,7 +105,11 @@ const EmojiPicker = {
default: false default: false
} }
}, },
inject: ['popoversZLayer'], inject: {
popoversZLayer: {
default: ''
}
},
data () { data () {
return { return {
keyword: '', keyword: '',

View file

@ -56,6 +56,7 @@
tag="span" tag="span"
class="notification tip extra-notification" class="notification tip extra-notification"
keypath="notifications.configuration_tip" keypath="notifications.configuration_tip"
scope="global"
> >
<template #theSettings> <template #theSettings>
<button <button

View file

@ -17,6 +17,7 @@
@cancelled="hideConfirmUnfollow" @cancelled="hideConfirmUnfollow"
> >
<i18n-t <i18n-t
scope="global"
keypath="user_card.unfollow_confirm" keypath="user_card.unfollow_confirm"
tag="span" tag="span"
> >

View file

@ -1,11 +1,8 @@
<template> <template>
<div <div class="font-control">
class="font-control"
:class="{ custom: isCustom }"
>
<label <label
:id="name + '-label'" :id="name + '-label'"
:for="preset === 'custom' ? name : name + '-font-switcher'" :for="manualEntry ? name : name + '-font-switcher'"
class="label" class="label"
> >
{{ label }} {{ label }}
@ -14,7 +11,7 @@
<Checkbox <Checkbox
v-if="typeof fallback !== 'undefined'" v-if="typeof fallback !== 'undefined'"
:id="name + '-o'" :id="name + '-o'"
:modelValue="present" :model-value="present"
@change="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)" @change="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)"
> >
{{ $t('settings.style.themes3.define') }} {{ $t('settings.style.themes3.define') }}
@ -23,12 +20,13 @@
<label <label
v-if="manualEntry" v-if="manualEntry"
:id="name + '-label'" :id="name + '-label'"
:for="preset === 'custom' ? name : name + '-font-switcher'" :for="manualEntry ? name : name + '-font-switcher'"
class="label" class="label"
> >
<i18n-t <i18n-t
keypath="settings.style.themes3.font.entry" keypath="settings.style.themes3.font.entry"
tag="span" tag="span"
scope="global"
> >
<template #fontFamily> <template #fontFamily>
<code>font-family</code> <code>font-family</code>
@ -38,7 +36,7 @@
<label <label
v-else v-else
:id="name + '-label'" :id="name + '-label'"
:for="preset === 'custom' ? name : name + '-font-switcher'" :for="manualEntry ? name : name + '-font-switcher'"
class="label" class="label"
> >
{{ $t('settings.style.themes3.font.select') }} {{ $t('settings.style.themes3.font.select') }}
@ -50,8 +48,8 @@
> >
<button <button
class="btn button-default" class="btn button-default"
@click="toggleManualEntry"
:title="$t('settings.style.themes3.font.lookup_local_fonts')" :title="$t('settings.style.themes3.font.lookup_local_fonts')"
@click="toggleManualEntry"
> >
<FAIcon <FAIcon
fixed-width fixed-width
@ -72,8 +70,8 @@
> >
<button <button
class="btn button-default" class="btn button-default"
@click="toggleManualEntry"
:title="$t('settings.style.themes3.font.enter_manually')" :title="$t('settings.style.themes3.font.enter_manually')"
@click="toggleManualEntry"
> >
<FAIcon <FAIcon
fixed-width fixed-width

View file

@ -17,6 +17,7 @@
<i18n-t <i18n-t
v-if="id" v-if="id"
keypath="lists.editing_list" keypath="lists.editing_list"
scope="global"
> >
<template #listTitle> <template #listTitle>
{{ title }} {{ title }}
@ -25,6 +26,7 @@
<i18n-t <i18n-t
v-else v-else
keypath="lists.creating_list" keypath="lists.creating_list"
scope="global"
/> />
</div> </div>
</div> </div>

View file

@ -3,7 +3,9 @@
<!-- Default panel contents --> <!-- Default panel contents -->
<div class="panel-heading"> <div class="panel-heading">
<h1 class="title">{{ $t('login.login') }}</h1> <h1 class="title">
{{ $t('login.login') }}
</h1>
</div> </div>
<div class="panel-body"> <div class="panel-body">

View file

@ -53,8 +53,10 @@ const MentionLink = {
this.$router.push(link) this.$router.push(link)
}, },
handleSelection () { handleSelection () {
if (this.$refs.full) {
this.hasSelection = document.getSelection().containsNode(this.$refs.full, true) this.hasSelection = document.getSelection().containsNode(this.$refs.full, true)
} }
}
}, },
mounted () { mounted () {
document.addEventListener('selectionchange', this.handleSelection) document.addEventListener('selectionchange', this.handleSelection)

View file

@ -125,7 +125,7 @@
<NavigationEntry <NavigationEntry
v-if="!forceEditMode && currentUser" v-if="!forceEditMode && currentUser"
:show-pin="false" :show-pin="false"
:item="{ label: editMode ? $t('nav.edit_finish') : $t('nav.edit_pinned'), icon: editMode ? 'check' : 'wrench' }" :item="{ labelRaw: editMode ? $t('nav.edit_finish') : $t('nav.edit_pinned'), icon: editMode ? 'check' : 'wrench' }"
@click="toggleEditMode" @click="toggleEditMode"
/> />
</ul> </ul>

View file

@ -1,11 +1,16 @@
// routes that take :username property
export const USERNAME_ROUTES = new Set([ export const USERNAME_ROUTES = new Set([
'bookmarks',
'dms', 'dms',
'interactions', 'interactions',
'notifications', 'notifications',
'chat', 'chat',
'chats', 'chats'
'user-profile' ])
// routes that take :name property
export const NAME_ROUTES = new Set([
'user-profile',
'legacy-user-profile'
]) ])
export const TIMELINES = { export const TIMELINES = {
@ -94,7 +99,9 @@ export function routeTo (item, currentUser) {
} }
if (USERNAME_ROUTES.has(route.name)) { if (USERNAME_ROUTES.has(route.name)) {
route.params = { username: currentUser.screen_name, name: currentUser.screen_name } route.params = { username: currentUser.screen_name }
} else if (NAME_ROUTES.has(route.name)) {
route.params = { name: currentUser.screen_name }
} }
return route return route

View file

@ -10,7 +10,7 @@
background-color: transparent !important; background-color: transparent !important;
} }
--emoji-size: 14px; --emoji-size: 1em;
&:hover { &:hover {
--_still-image-img-visibility: visible; --_still-image-img-visibility: visible;

View file

@ -47,7 +47,6 @@
> >
<UserAvatar <UserAvatar
class="post-avatar" class="post-avatar"
:bot="botIndicator"
:compact="true" :compact="true"
:better-shadow="betterShadow" :better-shadow="betterShadow"
:user="notification.from_profile" :user="notification.from_profile"

View file

@ -6,6 +6,7 @@
<ColorInput <ColorInput
v-for="key in paletteKeys" v-for="key in paletteKeys"
:key="key" :key="key"
:name="key"
:model-value="props.modelValue[key]" :model-value="props.modelValue[key]"
:fallback="fallback(key)" :fallback="fallback(key)"
:label="$t('settings.style.themes3.palette.' + key)" :label="$t('settings.style.themes3.palette.' + key)"

View file

@ -53,7 +53,11 @@ const Popover = {
default: {} default: {}
} }
}, },
inject: ['popoversZLayer'], // override popover z layer inject: { // override popover z layer
popoversZLayer: {
default: ''
}
},
data () { data () {
return { return {
// lockReEntry is a flag that is set when mouse cursor is leaving the popover's content // lockReEntry is a flag that is set when mouse cursor is leaving the popover's content

View file

@ -103,29 +103,6 @@
icon="circle-notch" icon="circle-notch"
/> />
</div> </div>
</div>
<div
v-if="showPreview"
class="preview-container"
>
<div
v-if="!preview"
class="preview-status"
>
{{ $t('general.loading') }}
</div>
<div
v-else-if="preview.error"
class="preview-status preview-error"
>
{{ preview.error }}
</div>
<StatusContent
v-else
:status="preview"
class="preview-status"
/>
</div>
<div <div
v-if="quotable" v-if="quotable"
role="radiogroup" role="radiogroup"
@ -156,6 +133,29 @@
{{ $t('post_status.quote_option') }} {{ $t('post_status.quote_option') }}
</button> </button>
</div> </div>
</div>
<div
v-if="showPreview"
class="preview-container"
>
<div
v-if="!preview"
class="preview-status"
>
{{ $t('general.loading') }}
</div>
<div
v-else-if="preview.error"
class="preview-status preview-error"
>
{{ preview.error }}
</div>
<StatusContent
v-else
:status="preview"
class="preview-status"
/>
</div>
<EmojiInput <EmojiInput
v-if="!disableSubject && (newStatus.spoilerText || alwaysShowSubject)" v-if="!disableSubject && (newStatus.spoilerText || alwaysShowSubject)"
v-model="newStatus.spoilerText" v-model="newStatus.spoilerText"
@ -181,10 +181,10 @@
:suggest="emojiUserSuggestor" :suggest="emojiUserSuggestor"
:placement="emojiPickerPlacement" :placement="emojiPickerPlacement"
class="input form-control main-input" class="input form-control main-input"
enable-sticker-picker
enable-emoji-picker enable-emoji-picker
hide-emoji-button hide-emoji-button
:newline-on-ctrl-enter="submitOnEnter" :newline-on-ctrl-enter="submitOnEnter"
enable-sticker-picker
@input="onEmojiInputInput" @input="onEmojiInputInput"
@sticker-uploaded="addMediaFile" @sticker-uploaded="addMediaFile"
@sticker-upload-failed="uploadFailed" @sticker-upload-failed="uploadFailed"
@ -235,7 +235,6 @@
class="text-format" class="text-format"
> >
<Select <Select
id="post-content-type"
v-model="newStatus.contentType" v-model="newStatus.contentType"
class="input form-control" class="input form-control"
:attrs="{ 'aria-label': $t('post_status.content_type_selection') }" :attrs="{ 'aria-label': $t('post_status.content_type_selection') }"
@ -409,13 +408,14 @@
.preview-heading { .preview-heading {
display: flex; display: flex;
padding-left: 0.5em; flex-wrap: wrap;
} }
.preview-toggle { .preview-toggle {
flex: 1; flex: 10 0 auto;
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
padding-left: 0.5em;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
@ -446,7 +446,10 @@
} }
.reply-or-quote-selector { .reply-or-quote-selector {
flex: 1 0 auto;
margin-bottom: 0.5em; margin-bottom: 0.5em;
display: grid;
grid-template-columns: 1fr 1fr;
} }
.text-format { .text-format {

View file

@ -2,7 +2,7 @@
<span class="ReactButton"> <span class="ReactButton">
<EmojiPicker <EmojiPicker
ref="picker" ref="picker"
:enable-sticker-picker="enableStickerPicker" :enable-sticker-picker="false"
:hide-custom-emoji="hideCustomEmoji" :hide-custom-emoji="hideCustomEmoji"
class="emoji-picker-panel" class="emoji-picker-panel"
@emoji="addReaction" @emoji="addReaction"

View file

@ -17,6 +17,7 @@
@cancelled="hideConfirmRemoveUserFromFollowers" @cancelled="hideConfirmRemoveUserFromFollowers"
> >
<i18n-t <i18n-t
scope="global"
keypath="user_card.remove_follower_confirm" keypath="user_card.remove_follower_confirm"
tag="span" tag="span"
> >

View file

@ -84,7 +84,7 @@ label.Select {
width: 0.875em; width: 0.875em;
font-family: var(--font); font-family: var(--font);
line-height: 2; line-height: 2;
z-index: 0; z-index: 1;
pointer-events: none; pointer-events: none;
} }
} }

View file

@ -49,11 +49,13 @@
<span v-if="adminDraft && adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name"> <span v-if="adminDraft && adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name">
<i18n-t <i18n-t
v-if="adminDraft && adminDraft[':pleroma'][':frontends'][':primary']?.ref === frontend.refs[0]" v-if="adminDraft && adminDraft[':pleroma'][':frontends'][':primary']?.ref === frontend.refs[0]"
scope="global"
keypath="admin_dash.frontend.is_default" keypath="admin_dash.frontend.is_default"
/> />
<i18n-t <i18n-t
v-else v-else
keypath="admin_dash.frontend.is_default_custom" keypath="admin_dash.frontend.is_default_custom"
scope="global"
> >
<template #version> <template #version>
<code>{{ adminDraft && adminDraft[':pleroma'][':frontends'][':primary'].ref }}</code> <code>{{ adminDraft && adminDraft[':pleroma'][':frontends'][':primary'].ref }}</code>
@ -120,7 +122,10 @@
@click.prevent="update(frontend, ref)" @click.prevent="update(frontend, ref)"
@click="close" @click="close"
> >
<i18n-t keypath="admin_dash.frontend.install_version"> <i18n-t
keypath="admin_dash.frontend.install_version"
scope="global"
>
<template #version> <template #version>
<code>{{ ref }}</code> <code>{{ ref }}</code>
</template> </template>
@ -177,7 +182,10 @@
@click.prevent="setDefault(frontend, ref)" @click.prevent="setDefault(frontend, ref)"
@click="close" @click="close"
> >
<i18n-t keypath="admin_dash.frontend.set_default_version"> <i18n-t
keypath="admin_dash.frontend.set_default_version"
scope="global"
>
<template #version> <template #version>
<code>{{ ref }}</code> <code>{{ ref }}</code>
</template> </template>

View file

@ -14,7 +14,6 @@ library.add(
) )
const LimitsTab = { const LimitsTab = {
data () {},
components: { components: {
BooleanSetting, BooleanSetting,
ChoiceSetting, ChoiceSetting,

View file

@ -48,18 +48,14 @@
:attachment="attachment" :attachment="attachment"
size="small" size="small"
hide-description hide-description
@setMedia="onMedia"
@naturalSizeLoad="onNaturalSizeLoad"
/> />
<div class="controls control-upload"> <div class="controls control-upload">
<MediaUpload <MediaUpload
ref="mediaUpload" ref="mediaUpload"
class="media-upload-icon" class="media-upload-icon"
:drop-files="dropFiles"
normal-button normal-button
:accept-types="acceptTypes" :accept-types="acceptTypes"
@uploaded="setMediaFile" @uploaded="setMediaFile"
@upload-failed="uploadFailed"
/> />
</div> </div>
</div> </div>

View file

@ -112,7 +112,10 @@ export default {
components: { Popover, ConfirmModal, StillImage }, components: { Popover, ConfirmModal, StillImage },
inject: ['emojiAddr'], inject: ['emojiAddr'],
props: { props: {
placement: String, placement: {
type: String,
required: true
},
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false default: false
@ -120,8 +123,14 @@ export default {
newUpload: Boolean, newUpload: Boolean,
title: String, title: {
packName: String, type: String,
required: true
},
packName: {
type: String,
required: true
},
shortcode: { shortcode: {
type: String, type: String,
// Only exists when this is not a new upload // Only exists when this is not a new upload

View file

@ -1,7 +1,7 @@
<template> <template>
<NumberSetting <NumberSetting
v-bind="$attrs" v-bind="$attrs"
truncate="1" :truncate="1"
> >
<slot /> <slot />
</NumberSetting> </NumberSetting>

View file

@ -4,6 +4,21 @@ export default {
...Setting, ...Setting,
props: { props: {
...Setting.props, ...Setting.props,
min: {
type: Number,
required: false,
default: 1
},
max: {
type: Number,
required: false,
default: 1
},
step: {
type: Number,
required: false,
default: 1
},
truncate: { truncate: {
type: Number, type: Number,
required: false, required: false,

View file

@ -167,7 +167,6 @@ const SettingsModal = {
}, },
computed: { computed: {
currentSaveStateNotice () { currentSaveStateNotice () {
console.log(this.$store.state.interface.settings.currentSaveStateNotice)
return this.$store.state.interface.settings.currentSaveStateNotice return this.$store.state.interface.settings.currentSaveStateNotice
}, },
modalActivated () { modalActivated () {

View file

@ -110,7 +110,10 @@
{{ $t("settings.expert_mode") }} {{ $t("settings.expert_mode") }}
</Checkbox> </Checkbox>
<span v-if="modalMode === 'admin'"> <span v-if="modalMode === 'admin'">
<i18n-t keypath="admin_dash.wip_notice"> <i18n-t
scope="global"
keypath="admin_dash.wip_notice"
>
<template #adminFeLink> <template #adminFeLink>
<a <a
href="/pleroma/admin/#/login-pleroma" href="/pleroma/admin/#/login-pleroma"

View file

@ -17,7 +17,10 @@
<div :label="$t('admin_dash.tabs.nodb')"> <div :label="$t('admin_dash.tabs.nodb')">
<div class="setting-item"> <div class="setting-item">
<h2>{{ $t('admin_dash.nodb.heading') }}</h2> <h2>{{ $t('admin_dash.nodb.heading') }}</h2>
<i18n-t keypath="admin_dash.nodb.text"> <i18n-t
scope="global"
keypath="admin_dash.nodb.text"
>
<template #documentation> <template #documentation>
<a <a
href="https://docs-develop.pleroma.social/backend/configuration/howto_database_config/" href="https://docs-develop.pleroma.social/backend/configuration/howto_database_config/"

View file

@ -17,6 +17,7 @@
:label="$t('settings.appearance')" :label="$t('settings.appearance')"
icon="window-restore" icon="window-restore"
data-tab-name="appearance" data-tab-name="appearance"
:delay-render="true"
> >
<AppearanceTab /> <AppearanceTab />
</div> </div>
@ -25,6 +26,7 @@
:label="$t('settings.style.themes3.editor.title')" :label="$t('settings.style.themes3.editor.title')"
icon="palette" icon="palette"
data-tab-name="style" data-tab-name="style"
:delay-render="true"
> >
<StyleTab /> <StyleTab />
</div> </div>
@ -33,6 +35,7 @@
:label="$t('settings.theme_old')" :label="$t('settings.theme_old')"
icon="paint-brush" icon="paint-brush"
data-tab-name="theme" data-tab-name="theme"
:delay-render="true"
> >
<ThemeTab /> <ThemeTab />
</div> </div>

View file

@ -119,7 +119,15 @@ const AppearanceTab = {
updateIndex('theme').then(themes => { updateIndex('theme').then(themes => {
themes.forEach(([key, themePromise]) => themePromise.then(data => { themes.forEach(([key, themePromise]) => themePromise.then(data => {
if (!data) {
console.warn(`Theme with key ${key} is empty or malformed`)
} else if (Array.isArray(data)) {
console.warn(`Theme with key ${key} is a v1 theme and should be moved to static/palettes/index.json`)
} else if (!data.source && !data.theme) {
console.warn(`Theme with key ${key} is malformed`)
} else {
this.availableThemesV2.push({ key, data, name: data.name, version: 'v2' }) this.availableThemesV2.push({ key, data, name: data.name, version: 'v2' })
}
})) }))
}) })
@ -251,12 +259,10 @@ const AppearanceTab = {
return ['sidebar', 'content', ...notif] return ['sidebar', 'content', ...notif]
} }
}, },
instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel },
instanceWallpaperUsed () { instanceWallpaperUsed () {
return this.$store.state.instance.background && return this.$store.state.instance.background &&
!this.$store.state.users.currentUser.background_image !this.$store.state.users.currentUser.background_image
}, },
instanceShoutboxPresent () { return this.$store.state.instance.shoutAvailable },
language: { language: {
get: function () { return this.$store.getters.mergedConfig.interfaceLanguage }, get: function () { return this.$store.getters.mergedConfig.interfaceLanguage },
set: function (val) { set: function (val) {

View file

@ -16,10 +16,12 @@
@click="resetTheming" @click="resetTheming"
> >
<!-- eslint-disable vue/no-v-text-v-html-on-component --> <!-- eslint-disable vue/no-v-text-v-html-on-component -->
<!-- eslint-disable vue/no-v-html -->
<component <component
:is="'style'" :is="'style'"
v-html="previewTheme('stock', 'v3')" v-html="previewTheme('stock', 'v3')"
/> />
<!-- eslint-enable vue/no-v-html -->
<!-- eslint-enable vue/no-v-text-v-html-on-component --> <!-- eslint-enable vue/no-v-text-v-html-on-component -->
<preview id="theme-preview-stock" /> <preview id="theme-preview-stock" />
<h4 class="theme-name"> <h4 class="theme-name">
@ -58,12 +60,14 @@
@click="style.version === 'v2' ? setTheme(style.key) : setStyle(style.key)" @click="style.version === 'v2' ? setTheme(style.key) : setStyle(style.key)"
> >
<!-- eslint-disable vue/no-v-text-v-html-on-component --> <!-- eslint-disable vue/no-v-text-v-html-on-component -->
<!-- eslint-disable vue/no-v-html -->
<div v-if="style.ready || noIntersectionObserver"> <div v-if="style.ready || noIntersectionObserver">
<component <component
:is="'style'" :is="'style'"
v-html="previewTheme(style.key, style.version, style.data)" v-html="previewTheme(style.key, style.version, style.data)"
/> />
</div> </div>
<!-- eslint-enable vue/no-v-html -->
<!-- eslint-enable vue/no-v-text-v-html-on-component --> <!-- eslint-enable vue/no-v-text-v-html-on-component -->
<preview :id="'theme-preview-' + style.key" /> <preview :id="'theme-preview-' + style.key" />
<h4 class="theme-name"> <h4 class="theme-name">
@ -136,8 +140,8 @@
</h4> </h4>
<PaletteEditor <PaletteEditor
v-if="expertLevel > 0" v-if="expertLevel > 0"
class="userPalette"
v-model="userPalette" v-model="userPalette"
class="userPalette"
:compact="true" :compact="true"
:apply="true" :apply="true"
@applyPalette="data => setPaletteCustom(data)" @applyPalette="data => setPaletteCustom(data)"
@ -160,7 +164,7 @@
<li> <li>
<UnitSetting <UnitSetting
path="textSize" path="textSize"
step="0.1" :step="0.1"
:units="['px', 'rem']" :units="['px', 'rem']"
:reset-default="{ 'px': 14, 'rem': 1 }" :reset-default="{ 'px': 14, 'rem': 1 }"
timed-apply-mode timed-apply-mode
@ -236,7 +240,7 @@
<li> <li>
<UnitSetting <UnitSetting
path="emojiSize" path="emojiSize"
step="0.1" :step="0.1"
:units="['px', 'rem']" :units="['px', 'rem']"
:reset-default="{ 'px': 32, 'rem': 2.2 }" :reset-default="{ 'px': 32, 'rem': 2.2 }"
> >
@ -259,7 +263,7 @@
<li> <li>
<UnitSetting <UnitSetting
path="navbarSize" path="navbarSize"
step="0.1" :step="0.1"
:units="['px', 'rem']" :units="['px', 'rem']"
:reset-default="{ 'px': 55, 'rem': 3.5 }" :reset-default="{ 'px': 55, 'rem': 3.5 }"
> >
@ -270,7 +274,7 @@
<li> <li>
<UnitSetting <UnitSetting
path="panelHeaderSize" path="panelHeaderSize"
step="0.1" :step="0.1"
:units="['px', 'rem']" :units="['px', 'rem']"
:reset-default="{ 'px': 52, 'rem': 3.2 }" :reset-default="{ 'px': 52, 'rem': 3.2 }"
timed-apply-mode timed-apply-mode

View file

@ -106,7 +106,7 @@
key="hideScrobblesAfter" key="hideScrobblesAfter"
path="hideScrobblesAfter" path="hideScrobblesAfter"
:units="['m', 'h', 'd']" :units="['m', 'h', 'd']"
unitSet="time" unit-set="time"
expert="1" expert="1"
> >
{{ $t('settings.hide_scrobbles_after') }} {{ $t('settings.hide_scrobbles_after') }}

View file

@ -81,6 +81,8 @@ const GeneralTab = {
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val }) this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
} }
}, },
instanceShoutboxPresent () { return this.$store.state.instance.shoutAvailable },
instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel },
...SharedComputedObject() ...SharedComputedObject()
}, },
methods: { methods: {

View file

@ -226,8 +226,8 @@
</BooleanSetting> </BooleanSetting>
</li> </li>
<ul <ul
class="setting-list suboptions"
v-if="mergedConfig.useAbsoluteTimeFormat" v-if="mergedConfig.useAbsoluteTimeFormat"
class="setting-list suboptions"
> >
<li> <li>
<UnitSetting <UnitSetting

View file

@ -149,6 +149,7 @@
</div> </div>
<div> <div>
<i18n-t <i18n-t
scope="global"
keypath="settings.new_alias_target" keypath="settings.new_alias_target"
tag="p" tag="p"
> >
@ -184,6 +185,7 @@
<i18n-t <i18n-t
keypath="settings.move_account_target" keypath="settings.move_account_target"
tag="p" tag="p"
scope="global"
> >
<template #example> <template #example>
<code> <code>

View file

@ -7,10 +7,12 @@
<h2> {{ $t('settings.style.themes3.editor.title') }} </h2> <h2> {{ $t('settings.style.themes3.editor.title') }} </h2>
<div class="meta-preview"> <div class="meta-preview">
<!-- eslint-disable vue/no-v-text-v-html-on-component --> <!-- eslint-disable vue/no-v-text-v-html-on-component -->
<!-- eslint-disable vue/no-v-html -->
<component <component
:is="'style'" :is="'style'"
v-html="overallPreviewCssRules" v-html="overallPreviewCssRules"
/> />
<!-- eslint-enable vue/no-v-html -->
<!-- eslint-enable vue/no-v-text-v-html-on-component --> <!-- eslint-enable vue/no-v-text-v-html-on-component -->
<Preview id="edited-style-preview" /> <Preview id="edited-style-preview" />
<teleport <teleport
@ -52,22 +54,34 @@
</teleport> </teleport>
<ul class="setting-list style-metadata"> <ul class="setting-list style-metadata">
<li> <li>
<StringSetting class="meta-field" v-model="name"> <StringSetting
v-model="name"
class="meta-field"
>
{{ $t('settings.style.themes3.editor.style_name') }} {{ $t('settings.style.themes3.editor.style_name') }}
</StringSetting> </StringSetting>
</li> </li>
<li> <li>
<StringSetting class="meta-field" v-model="author"> <StringSetting
v-model="author"
class="meta-field"
>
{{ $t('settings.style.themes3.editor.style_author') }} {{ $t('settings.style.themes3.editor.style_author') }}
</StringSetting> </StringSetting>
</li> </li>
<li> <li>
<StringSetting class="meta-field" v-model="license"> <StringSetting
v-model="license"
class="meta-field"
>
{{ $t('settings.style.themes3.editor.style_license') }} {{ $t('settings.style.themes3.editor.style_license') }}
</StringSetting> </StringSetting>
</li> </li>
<li> <li>
<StringSetting class="meta-field" v-model="website"> <StringSetting
v-model="website"
class="meta-field"
>
{{ $t('settings.style.themes3.editor.style_website') }} {{ $t('settings.style.themes3.editor.style_website') }}
</StringSetting> </StringSetting>
</li> </li>
@ -172,6 +186,7 @@
> >
<ColorInput <ColorInput
v-model="editedBackgroundColor" v-model="editedBackgroundColor"
name="component-background-color"
:fallback="computeColor(editedBackgroundColor) ?? previewColors.background" :fallback="computeColor(editedBackgroundColor) ?? previewColors.background"
:disabled="!isBackgroundColorPresent" :disabled="!isBackgroundColorPresent"
:label="$t('settings.style.themes3.editor.background')" :label="$t('settings.style.themes3.editor.background')"
@ -183,6 +198,7 @@
<ColorInput <ColorInput
v-if="componentHas('Text')" v-if="componentHas('Text')"
v-model="editedTextColor" v-model="editedTextColor"
name="component-text-color"
:fallback="computeColor(editedTextColor) ?? previewColors.text" :fallback="computeColor(editedTextColor) ?? previewColors.text"
:label="$t('settings.style.themes3.editor.text_color')" :label="$t('settings.style.themes3.editor.text_color')"
:disabled="!isTextColorPresent" :disabled="!isTextColorPresent"
@ -228,8 +244,8 @@
<Checkbox v-model="isTextAutoPresent" /> <Checkbox v-model="isTextAutoPresent" />
</Tooltip> </Tooltip>
<div <div
class="style-control suboption"
v-if="componentHas('Text')" v-if="componentHas('Text')"
class="style-control suboption"
> >
<label class="label"> <label class="label">
{{ $t('settings.style.themes3.editor.contrast') }} {{ $t('settings.style.themes3.editor.contrast') }}
@ -239,11 +255,11 @@
:contrast="contrast" :contrast="contrast"
/> />
</div> </div>
<div v-if="componentHas('Text')"> <div v-if="componentHas('Text')" />
</div>
<ColorInput <ColorInput
v-if="componentHas('Link')" v-if="componentHas('Link')"
v-model="editedLinkColor" v-model="editedLinkColor"
name="component-link-color"
:fallback="computeColor(editedLinkColor) ?? previewColors.link" :fallback="computeColor(editedLinkColor) ?? previewColors.link"
:label="$t('settings.style.themes3.editor.link_color')" :label="$t('settings.style.themes3.editor.link_color')"
:disabled="!isLinkColorPresent" :disabled="!isLinkColorPresent"
@ -258,6 +274,7 @@
<ColorInput <ColorInput
v-if="componentHas('Icon')" v-if="componentHas('Icon')"
v-model="editedIconColor" v-model="editedIconColor"
name="component-icon-color"
:fallback="computeColor(editedIconColor) ?? previewColors.icon" :fallback="computeColor(editedIconColor) ?? previewColors.icon"
:label="$t('settings.style.themes3.editor.icon_color')" :label="$t('settings.style.themes3.editor.icon_color')"
:disabled="!isIconColorPresent" :disabled="!isIconColorPresent"
@ -272,6 +289,7 @@
<ColorInput <ColorInput
v-if="componentHas('Border')" v-if="componentHas('Border')"
v-model="editedBorderColor" v-model="editedBorderColor"
name="component-border-color"
:fallback="computeColor(editedBorderColor) ?? previewColors.border" :fallback="computeColor(editedBorderColor) ?? previewColors.border"
:label="$t('settings.style.themes3.editor.border_color')" :label="$t('settings.style.themes3.editor.border_color')"
:disabled="!isBorderColorPresent" :disabled="!isBorderColorPresent"
@ -285,6 +303,7 @@
</Tooltip> </Tooltip>
<OpacityInput <OpacityInput
v-model="editedOpacity" v-model="editedOpacity"
name="component-opacity"
:disabled="!isOpacityPresent" :disabled="!isOpacityPresent"
:label="$t('settings.style.themes3.editor.opacity')" :label="$t('settings.style.themes3.editor.opacity')"
/> />
@ -293,6 +312,7 @@
</Tooltip> </Tooltip>
<RoundnessInput <RoundnessInput
v-model="editedRoundness" v-model="editedRoundness"
name="component-roundness"
:disabled="!isRoundnessPresent" :disabled="!isRoundnessPresent"
:label="$t('settings.style.themes3.editor.roundness')" :label="$t('settings.style.themes3.editor.roundness')"
/> />
@ -350,22 +370,22 @@
</Select> </Select>
<SelectMotion <SelectMotion
class="list-select-movement" class="list-select-movement"
:modelValue="palettes" :model-value="palettes"
@update:modelValue="onPalettesUpdate"
:selected-id="selectedPaletteId" :selected-id="selectedPaletteId"
:get-add-value="getNewPalette" :get-add-value="getNewPalette"
@update:modelValue="onPalettesUpdate"
@update:selectedId="e => selectedPaletteId = e" @update:selectedId="e => selectedPaletteId = e"
/> />
<div class="list-edit-area"> <div class="list-edit-area">
<StringSetting <StringSetting
class="palette-name-input"
v-model="selectedPalette.name" v-model="selectedPalette.name"
class="palette-name-input"
> >
{{ $t('settings.style.themes3.palette.name_label') }} {{ $t('settings.style.themes3.palette.name_label') }}
</StringSetting> </StringSetting>
<PaletteEditor <PaletteEditor
class="palette-editor-single"
v-model="selectedPalette" v-model="selectedPalette"
class="palette-editor-single"
/> />
</div> </div>
</div> </div>
@ -374,7 +394,6 @@
:label="$t('settings.style.themes3.editor.variables_tab')" :label="$t('settings.style.themes3.editor.variables_tab')"
:model-value="virtualDirectives" :model-value="virtualDirectives"
@update:modelValue="updateVirtualDirectives" @update:modelValue="updateVirtualDirectives"
:normalize-shadows="normalizeShadows"
/> />
</tab-switcher> </tab-switcher>
</div> </div>

View file

@ -26,10 +26,10 @@
<SelectMotion <SelectMotion
class="list-select-movement" class="list-select-movement"
:model-value="modelValue" :model-value="modelValue"
@update:modelValue="e => emit('update:modelValue', e)"
:selected-id="selectedVirtualDirectiveId" :selected-id="selectedVirtualDirectiveId"
@update:selectedId="e => selectedVirtualDirectiveId = e"
:get-add-value="getNewVirtualDirective" :get-add-value="getNewVirtualDirective"
@update:modelValue="e => emit('update:modelValue', e)"
@update:selectedId="e => selectedVirtualDirectiveId = e"
/> />
<div class="list-edit-area"> <div class="list-edit-area">
<div class="variable-selector"> <div class="variable-selector">
@ -41,8 +41,8 @@
{{ ' ' }} {{ ' ' }}
</label> </label>
<input <input
class="input"
v-model="selectedVirtualDirective.name" v-model="selectedVirtualDirective.name"
class="input"
> >
<label <label
class="variable-type-label" class="variable-type-label"
@ -54,13 +54,13 @@
<Select <Select
v-model="selectedVirtualDirectiveValType" v-model="selectedVirtualDirectiveValType"
> >
<option value='shadow'> <option value="shadow">
{{ $t('settings.style.themes3.editor.variables.type_shadow') }} {{ $t('settings.style.themes3.editor.variables.type_shadow') }}
</option> </option>
<option value='color'> <option value="color">
{{ $t('settings.style.themes3.editor.variables.type_color') }} {{ $t('settings.style.themes3.editor.variables.type_color') }}
</option> </option>
<option value='generic'> <option value="generic">
{{ $t('settings.style.themes3.editor.variables.type_generic') }} {{ $t('settings.style.themes3.editor.variables.type_generic') }}
</option> </option>
</Select> </Select>
@ -72,6 +72,7 @@
:compact="true" :compact="true"
/> />
<ColorInput <ColorInput
name="virtual-directive-color"
v-if="selectedVirtualDirectiveValType === 'color'" v-if="selectedVirtualDirectiveValType === 'color'"
v-model="draftVirtualDirective" v-model="draftVirtualDirective"
:fallback="computeColor(draftVirtualDirective)" :fallback="computeColor(draftVirtualDirective)"

View file

@ -133,7 +133,7 @@ export default {
Object Object
.values(themesIndex) .values(themesIndex)
.forEach(themeFunc => { .forEach(themeFunc => {
themeFunc().then(themeData => this.availableStyles.push(themeData)) themeFunc().then(themeData => themeData && this.availableStyles.push(themeData))
}) })
}) })
}, },

View file

@ -72,7 +72,7 @@
text-overflow: ellipsis; text-overflow: ellipsis;
--_still_image-label-scale: 0.25; --_still_image-label-scale: 0.25;
--emoji-size: 14px; --emoji-size: 1em;
} }
.status-favicon { .status-favicon {

View file

@ -386,6 +386,7 @@
class="heading-edited-row" class="heading-edited-row"
> >
<i18n-t <i18n-t
scope="global"
keypath="status.edited_at" keypath="status.edited_at"
tag="span" tag="span"
> >
@ -443,7 +444,10 @@
v-else-if="hasInvisibleQuote" v-else-if="hasInvisibleQuote"
class="quoted-status -unavailable-prompt" class="quoted-status -unavailable-prompt"
> >
<i18n-t keypath="status.invisible_quote"> <i18n-t
scope="global"
keypath="status.invisible_quote"
>
<template #link> <template #link>
<bdi> <bdi>
<a <a

View file

@ -113,7 +113,7 @@
align-items: top; align-items: top;
flex-direction: row; flex-direction: row;
--emoji-size: 16px; --emoji-size: calc(var(--emojiSize, 32px) / 2);
& .body, & .body,
& .attachments { & .attachments {

View file

@ -90,6 +90,9 @@ const StatusContent = {
} }
return true return true
}, },
localCollapseSubjectDefault () {
return this.mergedConfig.collapseMessageWithSubject
},
attachmentSize () { attachmentSize () {
if (this.compact) { if (this.compact) {
return 'small' return 'small'

View file

@ -145,7 +145,12 @@ export default {
if (props.fullHeight) { if (props.fullHeight) {
classes.push('full-height') classes.push('full-height')
} }
const renderSlot = (!this.renderOnlyFocused || active) let delayRender = slot.props['delay-render']
if (delayRender && active) {
slot.props['delay-render'] = false
delayRender = false
}
const renderSlot = (!delayRender && (!this.renderOnlyFocused || active))
? slot ? slot
: '' : ''

View file

@ -1,12 +1,15 @@
<template> <template>
<div :class="['Timeline', classes.root]"> <div :class="['Timeline', classes.root]">
<div :class="classes.header"> <div
v-if="!embedded"
:class="classes.header"
>
<TimelineMenu <TimelineMenu
v-if="!embedded" v-if="!embedded"
:timeline-name="timelineName" :timeline-name="timelineName"
/> />
<div <div
v-if="showScrollTop && !embedded" v-if="showScrollTop"
class="rightside-button" class="rightside-button"
> >
<button <button
@ -24,7 +27,7 @@
</FALayers> </FALayers>
</button> </button>
</div> </div>
<template v-if="mobileLayout && !embedded"> <template v-if="mobileLayout">
<div <div
v-if="showLoadButton" v-if="showLoadButton"
class="rightside-button" class="rightside-button"
@ -44,7 +47,7 @@
</button> </button>
</div> </div>
<div <div
v-else-if="!embedded" v-else
class="loadmore-text faint veryfaint rightside-icon" class="loadmore-text faint veryfaint rightside-icon"
:title="$t('timeline.up_to_date')" :title="$t('timeline.up_to_date')"
:aria-disabled="true" :aria-disabled="true"
@ -65,7 +68,7 @@
{{ loadButtonString }} {{ loadButtonString }}
</button> </button>
<div <div
v-else-if="!embedded" v-else
class="loadmore-text faint" class="loadmore-text faint"
@click.prevent @click.prevent
> >
@ -73,11 +76,9 @@
</div> </div>
</template> </template>
<QuickFilterSettings <QuickFilterSettings
v-if="!embedded"
class="rightside-button" class="rightside-button"
/> />
<QuickViewSettings <QuickViewSettings
v-if="!embedded"
class="rightside-button" class="rightside-button"
/> />
</div> </div>
@ -148,6 +149,8 @@
/> />
</div> </div>
</teleport> </teleport>
<!-- spacer to avoid having empty shrug -->
<span v-if="embedded && footerSlipgate" />
</div> </div>
</div> </div>
</template> </template>

View file

@ -34,6 +34,7 @@
class="extra-info-group" class="extra-info-group"
> >
<i18n-t <i18n-t
scope="global"
keypath="update.update_bugs" keypath="update.update_bugs"
tag="p" tag="p"
> >
@ -45,6 +46,7 @@
</template> </template>
</i18n-t> </i18n-t>
<i18n-t <i18n-t
scope="global"
keypath="update.update_changelog" keypath="update.update_changelog"
tag="p" tag="p"
> >
@ -57,6 +59,7 @@
</i18n-t> </i18n-t>
<p class="art-credit"> <p class="art-credit">
<i18n-t <i18n-t
scope="global"
keypath="update.art_by" keypath="update.art_by"
tag="small" tag="small"
> >

View file

@ -8,7 +8,7 @@
:style="style" :style="style"
class="background-image" class="background-image"
/> />
<div :class="onClose ? '' : panel-heading -flexible-height"> <div :class="onClose ? '' : 'panel-heading -flexible-height'">
<div class="user-info"> <div class="user-info">
<div class="container"> <div class="container">
<a <a

View file

@ -51,7 +51,7 @@
.user-list-popover { .user-list-popover {
padding: 0.5em; padding: 0.5em;
--emoji-size: 16px; --emoji-size: calc(var(--emojiSize, 32px) / 2);
.user-list-row { .user-list-row {
padding: 0.25em; padding: 0.25em;

View file

@ -166,7 +166,7 @@
flex-basis: 500px; flex-basis: 500px;
// No sticky header on user profile // No sticky header on user profile
--currentPanelStack: 1; --currentPanelStack: 0;
.user-birthday { .user-birthday {
margin: 0 0.75em 0.5em; margin: 0 0.75em 0.5em;

View file

@ -1449,6 +1449,9 @@
"error_sending_message": "Something went wrong when sending the message.", "error_sending_message": "Something went wrong when sending the message.",
"empty_chat_list_placeholder": "You don't have any chats yet. Start a new chat!" "empty_chat_list_placeholder": "You don't have any chats yet. Start a new chat!"
}, },
"bookmarks": {
"manage_bookmark_folders": "Manage bookmark folders"
},
"lists": { "lists": {
"lists": "Lists", "lists": "Lists",
"new": "New List", "new": "New List",

View file

@ -307,7 +307,7 @@ const config = {
applyConfig(state) applyConfig(state)
} }
if (name.startsWith('theme3hacks')) { if (name.startsWith('theme3hacks')) {
dispatch('setTheme', { recompile: true }) dispatch('applyTheme', { recompile: true })
} }
switch (name) { switch (name) {
case 'theme': case 'theme':