Merge branch 'setttingssync' into shigusegubu-themes3

This commit is contained in:
Henry Jameson 2026-03-18 16:52:37 +02:00
commit 6592955a28
12 changed files with 113 additions and 126 deletions

View file

@ -2,6 +2,8 @@ import StillImage from 'src/components/still-image/still-image.vue'
import UserAvatar from '../user_avatar/user_avatar.vue' import UserAvatar from '../user_avatar/user_avatar.vue'
import UserListPopover from '../user_list_popover/user_list_popover.vue' import UserListPopover from '../user_list_popover/user_list_popover.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faCheck, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons' import { faCheck, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons'
@ -42,7 +44,7 @@ const EmojiReactions = {
return !!this.$store.state.users.currentUser return !!this.$store.state.users.currentUser
}, },
remoteInteractionLink() { remoteInteractionLink() {
return this.$store.getters.remoteInteractionLink({ return useInstanceStore().getRemoteInteractionLink({
statusId: this.status.id, statusId: this.status.id,
}) })
}, },

View file

@ -48,9 +48,6 @@ const GeneralTab = {
}, },
...SharedComputedObject(), ...SharedComputedObject(),
...mapState(useInstanceCapabilitiesStore, ['blockExpiration']), ...mapState(useInstanceCapabilitiesStore, ['blockExpiration']),
...mapState(useSyncConfigStore, {
theme3hacks: (store) => store.mergedConfig.theme3hacks,
}),
}, },
methods: { methods: {
updateProfile() { updateProfile() {
@ -67,17 +64,8 @@ const GeneralTab = {
this.$store.commit('setCurrentUser', user) this.$store.commit('setCurrentUser', user)
}) })
}, },
updateFont(key, value) { updateFont(path, value) {
useLocalConfigStore().set({ useLocalConfigStore().set({ path, value })
path: 'theme3hacks',
value: {
...this.mergedConfig.theme3hacks,
fonts: {
...this.mergedConfig.theme3hacks.fonts,
[key]: value,
},
},
})
}, },
}, },
} }

View file

@ -64,21 +64,21 @@
</li> </li>
<li> <li>
<FontControl <FontControl
:model-value="theme3hacks.fonts.interface" :model-value="mergedConfig.fontInterface"
name="ui" name="ui"
:label="$t('settings.style.fonts.components_inline.interface')" :label="$t('settings.style.fonts.components_inline.interface')"
:fallback="{ family: 'sans-serif' }" :fallback="{ family: 'sans-serif' }"
no-inherit="1" no-inherit="1"
@update:model-value="v => updateFont('interface', v)" @update:model-value="v => updateFont('fontInterface', v)"
/> />
</li> </li>
<li> <li>
<FontControl <FontControl
:model-value="theme3hacks.fonts.input" :model-value="mergedConfig.fontInput"
name="input" name="input"
:fallback="{ family: 'inherit' }" :fallback="{ family: 'inherit' }"
:label="$t('settings.style.fonts.components_inline.input')" :label="$t('settings.style.fonts.components_inline.input')"
@update:model-value="v => updateFont('input', v)" @update:model-value="v => updateFont('fontInput', v)"
/> />
</li> </li>
<li> <li>

View file

@ -4,9 +4,10 @@ import ChoiceSetting from '../helpers/choice_setting.vue'
import IntegerSetting from '../helpers/integer_setting.vue' import IntegerSetting from '../helpers/integer_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js' import SharedComputedObject from '../helpers/shared_computed_object.js'
import { useLocalConfigStore } from 'src/stores/local_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
const GeneralTab = { const PostsTab = {
data() { data() {
return { return {
conversationDisplayOptions: ['tree', 'linear'].map((mode) => ({ conversationDisplayOptions: ['tree', 'linear'].map((mode) => ({
@ -66,19 +67,10 @@ const GeneralTab = {
...SharedComputedObject(), ...SharedComputedObject(),
}, },
methods: { methods: {
updateFont(key, value) { updateFont(path, value) {
useSyncConfigStore().setSimplePrefAndSave({ useLocalConfigStore().set({ path, value })
path: 'theme3hacks',
value: {
...this.mergedConfig.theme3hacks,
fonts: {
...this.mergedConfig.theme3hacks.fonts,
[key]: value,
},
},
})
}, },
}, },
} }
export default GeneralTab export default PostsTab

View file

@ -56,22 +56,20 @@
</li> </li>
<li> <li>
<FontControl <FontControl
:model-value="mergedConfig.theme3hacks.fonts.post" :model-value="mergedConfig.fontPosts"
name="post" name="post"
:is-local="true"
:fallback="{ family: 'inherit' }" :fallback="{ family: 'inherit' }"
:label="$t('settings.style.fonts.components.post')" :label="$t('settings.style.fonts.components.post')"
@update:model-value="v => updateFont('post', v)" @update:model-value="v => updateFont('fontPosts', v)"
/> />
</li> </li>
<li> <li>
<FontControl <FontControl
:model-value="mergedConfig.theme3hacks.fonts.monospace" :model-value="mergedConfig.fontMonospace"
:is-local="true"
name="postCode" name="postCode"
:fallback="{ family: 'monospace' }" :fallback="{ family: 'monospace' }"
:label="$t('settings.style.fonts.components.monospace')" :label="$t('settings.style.fonts.components.monospace')"
@update:model-value="v => updateFont('monospace', v)" @update:model-value="v => updateFont('fontMonospace', v)"
/> />
</li> </li>
<li> <li>

View file

@ -1,3 +1,4 @@
import { useInterfaceStore } from 'src/stores/interface.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { applyStyleConfig } from 'src/services/style_setter/style_setter.js' import { applyStyleConfig } from 'src/services/style_setter/style_setter.js'
@ -23,6 +24,15 @@ const APPEARANCE_SETTINGS_KEYS = [
'emojiSize', 'emojiSize',
'emojiReactionsScale', 'emojiReactionsScale',
] ]
const HACKS_KEYS = new Set([
'fontInterface',
'fontPosts',
'fontInput',
'fontMonospace',
'underlay',
])
const MIXED_KEYS = new Set([ const MIXED_KEYS = new Set([
...APPEARANCE_SETTINGS_KEYS, ...APPEARANCE_SETTINGS_KEYS,
...APPEARANCE_SETTINGS_KEYS.map((x) => 'simple.' + x), ...APPEARANCE_SETTINGS_KEYS.map((x) => 'simple.' + x),
@ -36,6 +46,9 @@ export const piniaStylePlugin = ({ store, options }) => {
if (MIXED_KEYS.has(path)) { if (MIXED_KEYS.has(path)) {
after(() => applyStyleConfig(useSyncConfigStore().mergedConfig)) after(() => applyStyleConfig(useSyncConfigStore().mergedConfig))
} }
if (HACKS_KEYS.has(path)) {
after(() => useInterfaceStore().applyTheme({ recompile: true }))
}
} }
}) })
} }

View file

@ -181,6 +181,13 @@ export const defaultConfigLocal = {
alwaysUseJpeg: false, alwaysUseJpeg: false,
imageCompression: true, imageCompression: true,
useStreamingApi: false, useStreamingApi: false,
underlay: 'none',
fontInterface: undefined,
fontInput: undefined,
fontPosts: undefined,
fontMonospace: undefined,
themeDebug: false, // debug mode that uses computed backgrounds instead of real ones to debug contrast functions
forceThemeRecompilation: false, // flag that forces recompilation on boot even if cache exists
} }
export const LOCAL_ONLY_KEYS = new Set(Object.keys(defaultConfigLocal)) export const LOCAL_ONLY_KEYS = new Set(Object.keys(defaultConfigLocal))
@ -212,16 +219,4 @@ export const defaultState = {
styleCustomData: null, styleCustomData: null,
palette: null, palette: null,
paletteCustomData: null, paletteCustomData: null,
themeDebug: false, // debug mode that uses computed backgrounds instead of real ones to debug contrast functions
forceThemeRecompilation: false, // flag that forces recompilation on boot even if cache exists
theme3hacks: {
// Hacks, user overrides that are independent of theme used
underlay: 'none',
fonts: {
interface: undefined,
input: undefined,
post: undefined,
monospace: undefined,
},
},
} }

View file

@ -2,7 +2,7 @@
// used to migrate from old config. // used to migrate from old config.
// commented entries are unsynced stuff // commented entries are unsynced stuff
export const defaultConfigSync = { export const oldDefaultConfigSync = {
expertLevel: 0, // used to track which settings to show and hide expertLevel: 0, // used to track which settings to show and hide
hideISP: false, hideISP: false,
hideInstanceWallpaper: false, hideInstanceWallpaper: false,

View file

@ -702,13 +702,15 @@ const users = {
user.domainMutes = [] user.domainMutes = []
commit('setCurrentUser', user) commit('setCurrentUser', user)
useSyncConfigStore().initSyncConfig(user).then(() => { useSyncConfigStore()
useInterfaceStore() .initSyncConfig(user)
.applyTheme() .then(() => {
.catch((e) => { useInterfaceStore()
console.error('Error setting theme', e) .applyTheme()
}) .catch((e) => {
}) console.error('Error setting theme', e)
})
})
useUserHighlightStore().initUserHighlight(user) useUserHighlightStore().initUserHighlight(user)
commit('addNewUsers', [user]) commit('addNewUsers', [user])

View file

@ -598,8 +598,9 @@ export const useInterfaceStore = defineStore('interface', {
this.themeApplied = true this.themeApplied = true
}, },
async applyTheme({ recompile = false } = {}) { async applyTheme({ recompile = false } = {}) {
const { forceThemeRecompilation, themeDebug, theme3hacks } = const { mergedConfig } = useSyncConfigStore()
useSyncConfigStore().mergedConfig const { forceThemeRecompilation, themeDebug } = mergedConfig
this.themeChangeInProgress = true this.themeChangeInProgress = true
// If we're not forced to recompile try using // If we're not forced to recompile try using
// cache (tryLoadCache return true if load successful) // cache (tryLoadCache return true if load successful)
@ -646,68 +647,41 @@ export const useInterfaceStore = defineStore('interface', {
convertTheme2To3(normalizeThemeData(this.themeDataUsed)) convertTheme2To3(normalizeThemeData(this.themeDataUsed))
const hacks = [] const hacks = []
Object.entries(theme3hacks).forEach(([key, value]) => { const fontMap = {
switch (key) { Interface: 'Root',
case 'fonts': { Input: 'Input',
Object.entries(theme3hacks.fonts).forEach(([fontKey, font]) => { Posts: 'Post',
if (!font?.family) return Monospace: 'Root',
switch (fontKey) { }
case 'interface':
hacks.push({ Object.entries(fontMap).forEach(([font, component]) => {
component: 'Root', const family = mergedConfig[`font${font}`]?.family
directives: { const variable = font === 'Monospace' ? '--monoFont' : '--font'
'--font': 'generic | ' + font.family, if (family) {
}, hacks.push({
}) component,
break directives: {
case 'input': [variable]: `generic | "${family}"`,
hacks.push({ },
component: 'Input', })
directives: {
'--font': 'generic | ' + font.family,
},
})
break
case 'post':
hacks.push({
component: 'RichContent',
directives: {
'--font': 'generic | ' + font.family,
},
})
break
case 'monospace':
hacks.push({
component: 'Root',
directives: {
'--monoFont': 'generic | ' + font.family,
},
})
break
}
})
break
}
case 'underlay': {
if (value !== 'none') {
const newRule = {
component: 'Underlay',
directives: {},
}
if (value === 'opaque') {
newRule.directives.opacity = 1
newRule.directives.background = '--wallpaper'
}
if (value === 'transparent') {
newRule.directives.opacity = 0
}
hacks.push(newRule)
}
break
}
} }
}) })
if (mergedConfig.underlay !== 'none') {
const newRule = {
component: 'Underlay',
directives: {},
}
if (mergedConfig.underlay === 'opaque') {
newRule.directives.opacity = 1
newRule.directives.background = '--wallpaper'
}
if (mergedConfig.underlay === 'transparent') {
newRule.directives.opacity = 0
}
hacks.push(newRule)
}
const rulesetArray = [ const rulesetArray = [
theme2ruleset, theme2ruleset,
this.styleDataUsed, this.styleDataUsed,
@ -724,6 +698,7 @@ export const useInterfaceStore = defineStore('interface', {
themeDebug, themeDebug,
) )
} catch (e) { } catch (e) {
console.error(e)
window.splashError(e) window.splashError(e)
} }
}, },

View file

@ -33,9 +33,9 @@ export const useLocalConfigStore = defineStore('local_config', {
set(this.prefsStorage, path, undefined) set(this.prefsStorage, path, undefined)
}, },
clearLocalConfig() { clearLocalConfig() {
const blankState = { ...cloneDeep(defaultState) }
Object.keys(this).forEach((k) => { Object.keys(this).forEach((k) => {
this.prefsStorage[k] = blankState[k] this.prefsStorage[k] = undefined
this.tempStorage[k] = undefined
}) })
}, },
}, },

View file

@ -28,7 +28,7 @@ import {
instanceDefaultConfig, instanceDefaultConfig,
LOCAL_ONLY_KEYS, LOCAL_ONLY_KEYS,
} from 'src/modules/default_config_state.js' } from 'src/modules/default_config_state.js'
import { defaultConfigSync } from 'src/modules/old_default_config_state.js' import { oldDefaultConfigSync } from 'src/modules/old_default_config_state.js'
export const VERSION = 2 export const VERSION = 2
export const NEW_USER_DATE = new Date('2026-03-16') // date of writing this, basically export const NEW_USER_DATE = new Date('2026-03-16') // date of writing this, basically
@ -628,7 +628,7 @@ export const useSyncConfigStore = defineStore('sync_config', {
const migratedEntries = new Set(vuexState.config._syncMigration ?? []) const migratedEntries = new Set(vuexState.config._syncMigration ?? [])
console.debug(`Already migrated Values: ${[...migratedEntries].join()}`) console.debug(`Already migrated Values: ${[...migratedEntries].join()}`)
Object.entries(defaultConfigSync).forEach(([key, value]) => { Object.entries(oldDefaultConfigSync).forEach(([key, value]) => {
const oldValue = vuexState.config[key] const oldValue = vuexState.config[key]
const defaultValue = value const defaultValue = value
@ -638,7 +638,30 @@ export const useSyncConfigStore = defineStore('sync_config', {
if (present && !migrated && different) { if (present && !migrated && different) {
console.debug(`Migrating config ${key}: ${oldValue}`) console.debug(`Migrating config ${key}: ${oldValue}`)
this.setPreference({ path: `simple.${key}`, oldValue }) if (key === 'theme3hacks') {
useLocalConfigStore().set({
path: 'fontInterface',
value: oldValue.fonts.interface,
})
useLocalConfigStore().set({
path: 'fontInput',
value: oldValue.fonts.input,
})
useLocalConfigStore().set({
path: 'fontPost',
value: oldValue.fonts.post,
})
useLocalConfigStore().set({
path: 'fontMonospace',
value: oldValue.fonts.monospace,
})
useLocalConfigStore().set({
path: 'underlay',
value: oldValue.underlay,
})
} else {
this.setPreference({ path: `simple.${key}`, value: oldValue })
}
migratedEntries.add(key) migratedEntries.add(key)
needUpload = true needUpload = true
} }
@ -705,8 +728,7 @@ export const useSyncConfigStore = defineStore('sync_config', {
if (!needPush) return if (!needPush) return
this.updateCache({ username: window.vuex.state.users.currentUser.fqn }) this.updateCache({ username: window.vuex.state.users.currentUser.fqn })
const params = { pleroma_settings_store: { 'pleroma-fe': this.cache } } const params = { pleroma_settings_store: { 'pleroma-fe': this.cache } }
window.vuex.state.api.backendInteractor window.vuex.state.api.backendInteractor.updateProfileJSON({ params })
.updateProfileJSON({ params })
}, },
}, },
getters: { getters: {