Merge remote-tracking branch 'origin/develop' into timed-user-mutes

This commit is contained in:
Henry Jameson 2025-07-09 15:57:23 +03:00
commit 385f921c41
72 changed files with 1336 additions and 851 deletions

View file

@ -12,10 +12,10 @@ import { newImporter } from 'src/services/export_import/export_import.js'
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
import { init } from 'src/services/theme_data/theme_data_3.service.js'
import {
getCssRules,
getScopedVersion
getCssRules
} from 'src/services/theme_data/css_utils.js'
import { deserialize } from 'src/services/theme_data/iss_deserializer.js'
import { createStyleSheet, adoptStyleSheets } from 'src/services/style_setter/style_setter.js'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
@ -155,19 +155,23 @@ const AppearanceTab = {
}))
})
this.previewTheme('stock', 'v3')
if (window.IntersectionObserver) {
this.intersectionObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(({ target, isIntersecting }) => {
if (!isIntersecting) return
const theme = this.availableStyles.find(x => x.key === target.dataset.themeKey)
this.$nextTick(() => {
if (theme) theme.ready = true
if (theme) this.previewTheme(theme.key, theme.version, theme.data)
})
observer.unobserve(target)
})
}, {
root: this.$refs.themeList
})
} else {
this.availableStyles.forEach(theme => this.previewTheme(theme.key, theme.version, theme.data))
}
},
updated () {
@ -391,7 +395,6 @@ const AppearanceTab = {
inputRuleset: [...input, paletteRule].filter(x => x),
ultimateBackgroundColor: '#000000',
liteMode: true,
debug: true,
onlyNormalState: true
})
}
@ -400,7 +403,6 @@ const AppearanceTab = {
inputRuleset: [],
ultimateBackgroundColor: '#000000',
liteMode: true,
debug: true,
onlyNormalState: true
})
}
@ -409,10 +411,15 @@ const AppearanceTab = {
this.compilationCache[key] = theme3
}
return getScopedVersion(
getCssRules(theme3.eager),
'#theme-preview-' + key
).join('\n')
const sheet = createStyleSheet('appearance-tab-previews', 90)
sheet.addRule([
'#theme-preview-', key, ' {\n',
getCssRules(theme3.eager).join('\n'),
'\n}'
].join(''))
sheet.ready = true
adoptStyleSheets()
}
}
}

View file

@ -16,14 +16,6 @@
:disabled="switchInProgress"
@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">
{{ $t('settings.style.stock_theme_used') }}
@ -61,16 +53,6 @@
:disabled="switchInProgress"
@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">
{{ style.name }}

View file

@ -8,6 +8,7 @@ import InterfaceLanguageSwitcher from 'src/components/interface_language_switche
import SharedComputedObject from '../helpers/shared_computed_object.js'
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
import { clearCache, cacheKey, emojiCacheKey } from 'src/services/sw/sw.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faGlobe
@ -98,6 +99,21 @@ const GeneralTab = {
methods: {
changeDefaultScope (value) {
this.$store.dispatch('setProfileOption', { name: 'defaultScope', value })
},
clearCache (key) {
clearCache(key)
.then(() => {
this.$store.dispatch('settingsSaved', { success: true })
})
.catch(error => {
this.$store.dispatch('settingsSaved', { error })
})
},
clearAssetCache () {
this.clearCache(cacheKey)
},
clearEmojiCache () {
this.clearCache(emojiCacheKey)
}
}
}

View file

@ -509,6 +509,29 @@
</li>
</ul>
</div>
<div
class="setting-item"
>
<h2>{{ $t('settings.cache') }}</h2>
<ul class="setting-list">
<li>
<button
class="btn button-default"
@click="clearAssetCache"
>
{{ $t('settings.clear_asset_cache') }}
</button>
</li>
<li>
<button
class="btn button-default"
@click="clearEmojiCache"
>
{{ $t('settings.clear_emoji_cache') }}
</button>
</li>
</ul>
</div>
</div>
</template>

View file

@ -41,8 +41,8 @@ const SecurityTab = {
user () {
return this.$store.state.users.currentUser
},
pleromaBackend () {
return this.$store.state.instance.pleromaBackend
pleromaExtensionsAvailable () {
return this.$store.state.instance.pleromaExtensionsAvailable
},
oauthTokens () {
return useOAuthTokensStore().tokens.map(oauthToken => {

View file

@ -1,4 +1,4 @@
import { ref, reactive, computed, watch, watchEffect, provide, getCurrentInstance } from 'vue'
import { ref, reactive, computed, watch, provide, getCurrentInstance } from 'vue'
import { useInterfaceStore } from 'src/stores/interface'
import { get, set, unset, throttle } from 'lodash'
@ -19,11 +19,9 @@ import Preview from '../theme_tab/theme_preview.vue'
import VirtualDirectivesTab from './virtual_directives_tab.vue'
import { createStyleSheet, adoptStyleSheets } from 'src/services/style_setter/style_setter.js'
import { init, findColor } from 'src/services/theme_data/theme_data_3.service.js'
import {
getCssRules,
getScopedVersion
} from 'src/services/theme_data/css_utils.js'
import { getCssRules } from 'src/services/theme_data/css_utils.js'
import { serialize } from 'src/services/theme_data/iss_serializer.js'
import { deserializeShadow, deserialize } from 'src/services/theme_data/iss_deserializer.js'
import {
@ -372,6 +370,9 @@ export default {
const path = getPath(component, directive)
usedRule = get(real, path) // get real
if (usedRule === '') {
return usedRule
}
if (!usedRule) {
usedRule = get(fallback, path)
}
@ -379,7 +380,7 @@ export default {
return postProcess(usedRule)
},
set (value) {
if (value) {
if (value != null) {
set(allEditedRules.value, getPath(component, directive), value)
} else {
unset(allEditedRules.value, getPath(component, directive))
@ -667,7 +668,7 @@ export default {
})
exports.clearStyle = () => {
onImport(interfaceStore().styleDataUsed)
onImport(interfaceStore.styleDataUsed)
}
exports.exportStyle = () => {
@ -685,19 +686,26 @@ export default {
const overallPreviewRules = ref([])
exports.overallPreviewRules = overallPreviewRules
const overallPreviewCssRules = ref([])
watchEffect(throttle(() => {
watch([overallPreviewRules], () => {
let css = null
try {
overallPreviewCssRules.value = getScopedVersion(
getCssRules(overallPreviewRules.value),
'#edited-style-preview'
).join('\n')
css = getCssRules(overallPreviewRules.value).map(r => r.replace('html', '&'))
} catch (e) {
console.error(e)
return
}
}, 500))
exports.overallPreviewCssRules = overallPreviewCssRules
const sheet = createStyleSheet('style-tab-overall-preview', 90)
sheet.clear()
sheet.addRule([
'#edited-style-preview {\n',
css.join('\n'),
'\n}'
].join(''))
sheet.ready = true
adoptStyleSheets()
})
const updateOverallPreview = throttle(() => {
try {
@ -721,12 +729,12 @@ export default {
console.error('Could not compile preview theme', e)
return null
}
}, 5000)
}, 1000)
//
// Apart from "hover" we can't really show how component looks like in
// certain states, so we have to fake them.
const simulatePseudoSelectors = (css, prefix) => css
.replace(prefix, '.component-preview .preview-block')
.replace(prefix, '.preview-block')
.replace(':active', '.preview-active')
.replace(':hover', '.preview-hover')
.replace(':active', '.preview-active')

View file

@ -6,14 +6,6 @@
<div class="setting-item heading">
<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
v-if="isActive"
@ -155,12 +147,6 @@
</ul>
</div>
<div class="preview-container">
<!-- eslint-disable vue/no-v-html vue/no-v-text-v-html-on-component -->
<component
:is="'style'"
v-html="previewCss"
/>
<!-- eslint-enable vue/no-v-html vue/no-v-text-v-html-on-component -->
<ComponentPreview
class="component-preview"
:show-text="componentHas('Text')"

View file

@ -31,6 +31,7 @@ import {
getCssRules,
getScopedVersion
} from 'src/services/theme_data/css_utils.js'
import { createStyleSheet, adoptStyleSheets } from 'src/services/style_setter/style_setter.js'
import ColorInput from 'src/components/color_input/color_input.vue'
import RangeInput from 'src/components/range_input/range_input.vue'
@ -68,7 +69,6 @@ const colorConvert = (color) => {
export default {
data () {
return {
themeV3Preview: [],
themeImporter: newImporter({
validator: this.importValidator,
onImport: this.onImport,
@ -697,10 +697,16 @@ export default {
liteMode: true
})
this.themeV3Preview = getScopedVersion(
const sheet = createStyleSheet('theme-tab-overall-preview', 90)
const rule = getScopedVersion(
getCssRules(theme3.eager),
'#theme-preview'
'&'
).join('\n')
sheet.clear()
sheet.addRule('#theme-preview {\n' + rule + '\n}')
sheet.ready = true
adoptStyleSheets()
}
},
watch: {

View file

@ -123,12 +123,6 @@
</div>
</div>
<!-- eslint-disable vue/no-v-html vue/no-v-text-v-html-on-component -->
<component
:is="'style'"
v-html="themeV3Preview"
/>
<!-- eslint-enable vue/no-v-html vue/no-v-text-v-html-on-component -->
<preview id="theme-preview" />
<div>