Merge branch 'setttingssync' into shigusegubu-themes3

This commit is contained in:
Henry Jameson 2026-04-10 17:04:51 +03:00
commit d55595d7f5
8 changed files with 41 additions and 102 deletions

View file

@ -235,7 +235,7 @@
<li> <li>
<ChoiceSetting <ChoiceSetting
id="underlayOverride" id="underlayOverride"
path="theme3hacks.underlay" path="underlay"
:options="underlayOverrideModes" :options="underlayOverrideModes"
> >
{{ $t('settings.style.themes3.hacks.underlay_overrides') }} {{ $t('settings.style.themes3.hacks.underlay_overrides') }}

View file

@ -23,15 +23,12 @@ const APPEARANCE_SETTINGS_KEYS = [
'forcedRoundness', 'forcedRoundness',
'emojiSize', 'emojiSize',
'emojiReactionsScale', 'emojiReactionsScale',
]
const HACKS_KEYS = new Set([
'fontInterface', 'fontInterface',
'fontPosts', 'fontPosts',
'fontInput', 'fontInput',
'fontMonospace', 'fontMonospace',
'underlay', 'underlay',
]) ]
const MIXED_KEYS = new Set([ const MIXED_KEYS = new Set([
...APPEARANCE_SETTINGS_KEYS, ...APPEARANCE_SETTINGS_KEYS,
@ -45,8 +42,6 @@ export const piniaStylePlugin = ({ store, options }) => {
const { path } = args[0] const { path } = args[0]
if (MIXED_KEYS.has(path)) { if (MIXED_KEYS.has(path)) {
after(() => applyStyleConfig(useMergedConfigStore().mergedConfig)) after(() => applyStyleConfig(useMergedConfigStore().mergedConfig))
}
if (HACKS_KEYS.has(path)) {
after(() => useInterfaceStore().applyTheme({ recompile: true })) after(() => useInterfaceStore().applyTheme({ recompile: true }))
} }
} }

View file

@ -41,7 +41,7 @@ const i18n = createI18n({
messages.setLanguage(i18n.global, currentLocale) messages.setLanguage(i18n.global, currentLocale)
const persistedStateOptions = { const persistedStateOptions = {
paths: ['users.lastLoginName', 'oauth'], paths: ['users.lastLoginName', 'oauth', 'config'],
} }
;(async () => { ;(async () => {

View file

@ -1,45 +0,0 @@
import { useMergedConfigStore } from 'src/stores/merged_config.js'
export const CONFIG_MIGRATION = 1
import { v4 as uuidv4 } from 'uuid'
// for future use
/*
const simpleDeclaration = {
store: 'server-side',
migrationFlag: 'configMigration',
migration(serverside, rootState) {
serverside.setSimplePrefAndSave({ path: field, value: rootState.config[oldField ?? field] })
}
}
*/
export const declarations = [
{
field: 'muteFilters',
store: 'server-side',
migrationFlag: 'configMigration',
migrationNum: 1,
description: 'Mute filters, wordfilter/regexp/etc',
valueType: 'complex',
migration(serverside, rootState) {
useMergedConfigStore().mergedConfig.muteWords.forEach((word, order) => {
const uniqueId = uuidv4()
serverside.setPreference({
path: 'simple.muteFilters.' + uniqueId,
value: {
type: 'word',
value: word,
name: word,
enabled: true,
expires: null,
hide: false,
order,
},
})
})
},
},
]

View file

@ -531,18 +531,17 @@ export const INSTANCE_DEFAULT_CONFIG_DEFINITIONS = {
type: 'string', type: 'string',
required: false, required: false,
}, },
theme3hacks: {
description: 'Theme 3 hacks (need separation)',
type: 'object',
required: false,
default: {},
},
highlights: { highlights: {
description: 'User highlights', description: 'User highlights',
type: 'object', type: 'object',
required: false, required: false,
default: {}, default: {},
}, },
underlay: {
description: 'Underlay override',
required: true,
default: 'none',
},
} }
export const INSTANCE_DEFAULT_CONFIG = convertDefinitions( export const INSTANCE_DEFAULT_CONFIG = convertDefinitions(
INSTANCE_DEFAULT_CONFIG_DEFINITIONS, INSTANCE_DEFAULT_CONFIG_DEFINITIONS,
@ -634,11 +633,6 @@ export const LOCAL_DEFAULT_CONFIG_DEFINITIONS = {
description: 'Streaming API (WebSocket)', description: 'Streaming API (WebSocket)',
default: false, default: false,
}, },
underlay: {
description: 'Underlay override',
required: true,
default: 'none',
},
fontInterface: { fontInterface: {
description: 'Interface font override', description: 'Interface font override',
type: 'object', type: 'object',
@ -766,6 +760,7 @@ export const validateSetting = ({
if (value === undefined) return undefined // only null is allowed as missing value if (value === undefined) return undefined // only null is allowed as missing value
if (definition === undefined) return undefined // invalid definition if (definition === undefined) return undefined // invalid definition
const path = fullPath.replace(/^simple./, '') const path = fullPath.replace(/^simple./, '')
const depth = path.split('.')
if ( if (
validateObjects && validateObjects &&
definition.type === 'object' && definition.type === 'object' &&
@ -777,12 +772,6 @@ export const validateSetting = ({
return undefined return undefined
} }
if (path.includes('muteFilters')) {
console.log('##', path, value, definition)
console.log(value)
console.log(path)
console.log('====')
}
if (get(defaultState, path.split('.')[0]) === undefined) { if (get(defaultState, path.split('.')[0]) === undefined) {
const string = `Unknown option ${fullPath}, value: ${value}` const string = `Unknown option ${fullPath}, value: ${value}`
@ -811,7 +800,7 @@ export const validateSetting = ({
} }
} }
if (value !== null && type != null && typeof value !== type) { if (depth > 2 && value !== null && type != null && typeof value !== type) {
const string = `Invalid type for setting ${path}: expected type ${type}, got ${typeof value}, value ${value}; defaulting` const string = `Invalid type for setting ${path}: expected type ${type}, got ${typeof value}, value ${value}; defaulting`
if (throwError) { if (throwError) {

View file

@ -30,8 +30,6 @@ import { useOAuthStore } from 'src/stores/oauth.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { useUserHighlightStore } from 'src/stores/user_highlight.js' import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import { declarations } from 'src/modules/config_declaration'
// TODO: Unify with mergeOrAdd in statuses.js // TODO: Unify with mergeOrAdd in statuses.js
export const mergeOrAdd = (arr, obj, item) => { export const mergeOrAdd = (arr, obj, item) => {
if (!item) { if (!item) {
@ -742,25 +740,6 @@ const users = {
useSyncConfigStore().setFlag({ flag: 'configMigration', value: 0 }) useSyncConfigStore().setFlag({ flag: 'configMigration', value: 0 })
/**/ /**/
const { configMigration } = useSyncConfigStore().flagStorage
declarations
.filter((x) => {
return (
x.store === 'server-side' &&
x.migrationNum > 0 &&
x.migrationNum > configMigration
)
})
.toSorted((a, b) => a.configMigration - b.configMigration)
.forEach((value) => {
value.migration(useSyncConfigStore(), store.rootState)
useSyncConfigStore().setFlag({
flag: 'configMigration',
value: value.migrationNum,
})
useSyncConfigStore().pushSyncConfig()
})
if (user.token) { if (user.token) {
dispatch('setWsToken', user.token) dispatch('setWsToken', user.token)

View file

@ -14,6 +14,7 @@ import {
uniqWith, uniqWith,
unset, unset,
} from 'lodash' } from 'lodash'
import { v4 as uuidv4 } from 'uuid'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { toRaw } from 'vue' import { toRaw } from 'vue'
@ -676,15 +677,17 @@ export const useSyncConfigStore = defineStore('sync_config', {
// Various migrations // Various migrations
console.debug('Migrating from old config') console.debug('Migrating from old config')
const vuexState = (await storage.getItem('vuex-lz')) ?? {} const vuexState = (await storage.getItem('vuex-lz')) ?? {}
vuexState.config = vuexState.config ?? {} const config = vuexState.config ?? {}
const migratedEntries = new Set(vuexState.config._syncMigration ?? []) const migratedEntries = new Set(config._syncMigration ?? [])
console.debug( console.debug(
`Already migrated Values: ${[...migratedEntries].join() || '[none]'}`, `Already migrated Values: ${[...migratedEntries].join() || '[none]'}`,
) )
const { configMigration } = useSyncConfigStore().flagStorage
Object.entries(oldDefaultConfigSync).forEach(([key, value]) => { Object.entries(oldDefaultConfigSync).forEach(([key, value]) => {
const oldValue = vuexState.config[key] const oldValue = config[key]
const defaultValue = value const defaultValue = value
const present = oldValue !== undefined const present = oldValue !== undefined
@ -710,10 +713,27 @@ export const useSyncConfigStore = defineStore('sync_config', {
path: 'fontMonospace', path: 'fontMonospace',
value: oldValue.fonts.monospace, value: oldValue.fonts.monospace,
}) })
useLocalConfigStore().set({ useSyncConfigStore().setSimplePrefAndSave({
path: 'underlay', path: 'underlay',
value: oldValue.underlay, value: oldValue.underlay,
}) })
} else if (key == 'muteWords') {
oldValue.forEach((word, order) => {
const uniqueId = uuidv4()
useSyncConfigStore().setPreference({
path: 'simple.muteFilters.' + uniqueId,
value: {
type: 'word',
value: word,
name: word,
enabled: true,
expires: null,
hide: false,
order,
},
})
})
} else { } else {
this.setPreference({ path: `simple.${key}`, value: oldValue }) this.setPreference({ path: `simple.${key}`, value: oldValue })
} }
@ -722,7 +742,8 @@ export const useSyncConfigStore = defineStore('sync_config', {
} }
}) })
vuexState.config._syncMigration = [...migratedEntries] config._syncMigration = [...migratedEntries]
vuexState.config = config
storage.setItem('vuex-lz', vuexState) storage.setItem('vuex-lz', vuexState)
if (!needUpload && recent && stale) { if (!needUpload && recent && stale) {
@ -789,7 +810,7 @@ export const useSyncConfigStore = defineStore('sync_config', {
}) })
return finalValue === undefined return finalValue === undefined
? definition.default ? [path, definition.default]
: [path, finalValue] : [path, finalValue]
}) })
newState.prefsStorage.simple = Object.fromEntries( newState.prefsStorage.simple = Object.fromEntries(

View file

@ -278,21 +278,21 @@ export const useUserHighlightStore = defineStore('user_highlight', {
let dirty = false let dirty = false
const vuexState = (await storage.getItem('vuex-lz')) ?? {} const vuexState = (await storage.getItem('vuex-lz')) ?? {}
vuexState.config = vuexState.config ?? {} const config = vuexState.config ?? {}
const highlight = vuexState.config.highlight ?? {} const highlight = config.highlight ?? {}
Object.entries(highlight).forEach(([user, value]) => { Object.entries(highlight).forEach(([user, value]) => {
if ((highlight[user]._migrated || 0) < 1) { if ((highlight[user]._migrated || 0) < 1) {
dirty = true dirty = true
needUpload = true needUpload = true
this.set({ user, value: clone(value) }) this.set({ user, value: clone(value) })
vuexState.config.highlight[user]._migrated = 1 highlight[user]._migrated = 1
console.debug( console.debug(
`[HIGHLIGHT] Migrating user ${user}: ${JSON.stringify(value)}`, `[HIGHLIGHT] Migrating user ${user}: ${JSON.stringify(value)}`,
) )
} }
}) })
storage.setItem('vuex-lz', vuexState) storage.setItem('vuex-lz', { ...vuexState, config: { ...config, highlight } })
if (recent === null) { if (recent === null) {
console.debug( console.debug(