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>
<meta charset="utf-8">
<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 -->
<style id="splashscreen">
#splash {

View file

@ -70,7 +70,7 @@
<PostStatusModal />
<EditStatusModal v-if="editingAvailable" />
<StatusHistoryModal v-if="editingAvailable" />
<SettingsModal :class="layoutModalClass"/>
<SettingsModal :class="layoutModalClass" />
<UpdateNotification />
<GlobalNoticeList />
</div>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -125,7 +125,7 @@
<NavigationEntry
v-if="!forceEditMode && currentUser"
: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"
/>
</ul>

View file

@ -1,11 +1,16 @@
// routes that take :username property
export const USERNAME_ROUTES = new Set([
'bookmarks',
'dms',
'interactions',
'notifications',
'chat',
'chats',
'user-profile'
'chats'
])
// routes that take :name property
export const NAME_ROUTES = new Set([
'user-profile',
'legacy-user-profile'
])
export const TIMELINES = {
@ -94,7 +99,9 @@ export function routeTo (item, currentUser) {
}
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

View file

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

View file

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

View file

@ -8,7 +8,7 @@
class="label"
:class="{ faint: !present || disabled }"
>
{{ label }}
{{ label }}
</label>
<Checkbox
v-if="typeof fallback !== 'undefined'"

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -4,6 +4,21 @@ export default {
...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: {
type: Number,
required: false,

View file

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

View file

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

View file

@ -17,7 +17,10 @@
<div :label="$t('admin_dash.tabs.nodb')">
<div class="setting-item">
<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>
<a
href="https://docs-develop.pleroma.social/backend/configuration/howto_database_config/"

View file

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

View file

@ -119,7 +119,15 @@ const AppearanceTab = {
updateIndex('theme').then(themes => {
themes.forEach(([key, themePromise]) => themePromise.then(data => {
this.availableThemesV2.push({ key, data, name: data.name, version: 'v2' })
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' })
}
}))
})
@ -251,12 +259,10 @@ const AppearanceTab = {
return ['sidebar', 'content', ...notif]
}
},
instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel },
instanceWallpaperUsed () {
return this.$store.state.instance.background &&
!this.$store.state.users.currentUser.background_image
},
instanceShoutboxPresent () { return this.$store.state.instance.shoutAvailable },
language: {
get: function () { return this.$store.getters.mergedConfig.interfaceLanguage },
set: function (val) {

View file

@ -16,10 +16,12 @@
@click="resetTheming"
>
<!-- eslint-disable vue/no-v-text-v-html-on-component -->
<!-- eslint-disable vue/no-v-html -->
<component
:is="'style'"
v-html="previewTheme('stock', 'v3')"
/>
<!-- eslint-enable vue/no-v-html -->
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
<preview id="theme-preview-stock" />
<h4 class="theme-name">
@ -58,12 +60,14 @@
@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-html -->
<div v-if="style.ready || noIntersectionObserver">
<component
:is="'style'"
v-html="previewTheme(style.key, style.version, style.data)"
/>
</div>
<!-- eslint-enable vue/no-v-html -->
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
<preview :id="'theme-preview-' + style.key" />
<h4 class="theme-name">
@ -73,13 +77,13 @@
</button>
</ul>
<div class="import-file-container">
<button
class="btn button-default"
@click="importFile"
>
<FAIcon icon="folder-open" />
{{ $t('settings.style.themes3.editor.load_style') }}
</button>
<button
class="btn button-default"
@click="importFile"
>
<FAIcon icon="folder-open" />
{{ $t('settings.style.themes3.editor.load_style') }}
</button>
</div>
<div class="setting-item">
<h2>{{ $t('settings.style.themes3.palette.label') }}</h2>
@ -136,8 +140,8 @@
</h4>
<PaletteEditor
v-if="expertLevel > 0"
class="userPalette"
v-model="userPalette"
class="userPalette"
:compact="true"
:apply="true"
@applyPalette="data => setPaletteCustom(data)"
@ -160,7 +164,7 @@
<li>
<UnitSetting
path="textSize"
step="0.1"
:step="0.1"
:units="['px', 'rem']"
:reset-default="{ 'px': 14, 'rem': 1 }"
timed-apply-mode
@ -236,7 +240,7 @@
<li>
<UnitSetting
path="emojiSize"
step="0.1"
:step="0.1"
:units="['px', 'rem']"
:reset-default="{ 'px': 32, 'rem': 2.2 }"
>
@ -259,7 +263,7 @@
<li>
<UnitSetting
path="navbarSize"
step="0.1"
:step="0.1"
:units="['px', 'rem']"
:reset-default="{ 'px': 55, 'rem': 3.5 }"
>
@ -270,7 +274,7 @@
<li>
<UnitSetting
path="panelHeaderSize"
step="0.1"
:step="0.1"
:units="['px', 'rem']"
:reset-default="{ 'px': 52, 'rem': 3.2 }"
timed-apply-mode

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -133,7 +133,7 @@ export default {
Object
.values(themesIndex)
.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;
--_still_image-label-scale: 0.25;
--emoji-size: 14px;
--emoji-size: 1em;
}
.status-favicon {

View file

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

View file

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

View file

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

View file

@ -145,7 +145,12 @@ export default {
if (props.fullHeight) {
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
: ''

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1449,6 +1449,9 @@
"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!"
},
"bookmarks": {
"manage_bookmark_folders": "Manage bookmark folders"
},
"lists": {
"lists": "Lists",
"new": "New List",

View file

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