2022-05-22 16:40:59 +00:00
|
|
|
import Cookies from 'js-cookie'
|
2023-03-12 14:32:13 +02:00
|
|
|
import { set } from 'lodash'
|
2026-01-08 17:26:52 +02:00
|
|
|
|
2026-01-06 16:23:17 +02:00
|
|
|
import messages from '../i18n/messages'
|
|
|
|
|
import localeService from '../services/locale/locale.service.js'
|
2026-02-13 14:10:05 +02:00
|
|
|
import { applyStyleConfig } from '../services/style_setter/style_setter.js'
|
2026-01-06 16:23:17 +02:00
|
|
|
import { defaultState, instanceDefaultConfig } from './default_config_state.js'
|
2025-01-30 21:56:07 +02:00
|
|
|
|
2026-01-29 20:40:00 +02:00
|
|
|
import { useEmojiStore } from 'src/stores/emoji.js'
|
|
|
|
|
import { useI18nStore } from 'src/stores/i18n.js'
|
|
|
|
|
import { useInstanceStore } from 'src/stores/instance.js'
|
|
|
|
|
import { useInterfaceStore } from 'src/stores/interface.js'
|
|
|
|
|
|
2022-05-22 16:40:59 +00:00
|
|
|
const BACKEND_LANGUAGE_COOKIE_NAME = 'userLanguage'
|
2024-07-10 22:49:56 +03:00
|
|
|
const APPEARANCE_SETTINGS_KEYS = new Set([
|
|
|
|
|
'sidebarColumnWidth',
|
|
|
|
|
'contentColumnWidth',
|
|
|
|
|
'notifsColumnWidth',
|
2025-03-10 23:36:04 -04:00
|
|
|
'themeEditorMinWidth',
|
2024-07-10 22:49:56 +03:00
|
|
|
'textSize',
|
|
|
|
|
'navbarSize',
|
|
|
|
|
'panelHeaderSize',
|
|
|
|
|
'forcedRoundness',
|
|
|
|
|
'emojiSize',
|
2026-01-06 16:22:52 +02:00
|
|
|
'emojiReactionsScale',
|
2024-07-10 22:49:56 +03:00
|
|
|
])
|
2017-02-14 22:21:23 +01:00
|
|
|
|
2020-05-26 22:50:37 +03:00
|
|
|
/* TODO this is a bit messy.
|
|
|
|
|
* We need to declare settings with their types and also deal with
|
|
|
|
|
* instance-default settings in some way, hopefully try to avoid copy-pasta
|
|
|
|
|
* in general.
|
|
|
|
|
*/
|
|
|
|
|
export const multiChoiceProperties = [
|
|
|
|
|
'postContentType',
|
2022-01-10 01:16:33 -05:00
|
|
|
'subjectLineBehavior',
|
2021-08-06 20:18:27 -04:00
|
|
|
'conversationDisplay', // tree | linear
|
2021-09-05 16:35:47 -04:00
|
|
|
'conversationOtherRepliesButton', // below | inside
|
2022-08-09 10:44:20 +03:00
|
|
|
'mentionLinkDisplay', // short | full_for_remote | full
|
2023-04-06 14:15:57 -04:00
|
|
|
'userPopoverAvatarAction', // close | zoom | open
|
2026-01-06 16:22:52 +02:00
|
|
|
'unsavedPostAction', // save | discard | confirm
|
2020-05-26 22:50:37 +03:00
|
|
|
]
|
|
|
|
|
|
2019-09-29 22:33:15 +03:00
|
|
|
// caching the instance default properties
|
2025-10-14 18:15:46 -04:00
|
|
|
export const instanceDefaultProperties = Object.keys(instanceDefaultConfig)
|
2019-09-29 22:33:15 +03:00
|
|
|
|
2017-02-14 22:21:23 +01:00
|
|
|
const config = {
|
2020-10-01 01:43:07 +03:00
|
|
|
state: { ...defaultState },
|
2019-09-29 22:33:15 +03:00
|
|
|
getters: {
|
2026-01-29 01:45:31 +02:00
|
|
|
defaultConfig() {
|
2020-10-01 01:43:07 +03:00
|
|
|
return {
|
|
|
|
|
...defaultState,
|
|
|
|
|
...Object.fromEntries(
|
2026-01-29 13:44:33 +02:00
|
|
|
instanceDefaultProperties.map((key) => [
|
|
|
|
|
key,
|
2026-01-29 15:07:00 +02:00
|
|
|
useInstanceStore().prefsStorage[key],
|
2026-01-29 13:44:33 +02:00
|
|
|
]),
|
2026-01-06 16:22:52 +02:00
|
|
|
),
|
2020-10-01 01:43:07 +03:00
|
|
|
}
|
|
|
|
|
},
|
2026-01-29 01:45:31 +02:00
|
|
|
mergedConfig(state) {
|
|
|
|
|
const instancePrefs = useInstanceStore().prefsStorage
|
|
|
|
|
const result = Object.fromEntries(
|
2026-01-29 15:07:00 +02:00
|
|
|
Object.keys(defaultState).map((key) => [
|
|
|
|
|
key,
|
|
|
|
|
state[key] ?? instancePrefs[key],
|
2026-01-29 01:45:31 +02:00
|
|
|
]),
|
|
|
|
|
)
|
|
|
|
|
return result
|
2026-01-06 16:22:52 +02:00
|
|
|
},
|
2019-09-29 22:33:15 +03:00
|
|
|
},
|
2017-02-14 22:21:23 +01:00
|
|
|
mutations: {
|
2026-01-06 16:22:52 +02:00
|
|
|
setOptionTemporarily(state, { name, value }) {
|
2024-05-22 19:54:19 +03:00
|
|
|
set(state, name, value)
|
2026-02-13 14:10:05 +02:00
|
|
|
applyStyleConfig(state)
|
2024-05-22 19:54:19 +03:00
|
|
|
},
|
2026-01-06 16:22:52 +02:00
|
|
|
setOption(state, { name, value }) {
|
2023-03-12 14:32:13 +02:00
|
|
|
set(state, name, value)
|
2018-06-19 16:17:50 +03:00
|
|
|
},
|
2026-01-06 16:22:52 +02:00
|
|
|
setHighlight(state, { user, color, type }) {
|
2018-08-05 05:18:04 +03:00
|
|
|
const data = this.state.config.highlight[user]
|
|
|
|
|
if (color || type) {
|
2026-01-06 16:22:52 +02:00
|
|
|
state.highlight[user] = {
|
|
|
|
|
color: color || data.color,
|
|
|
|
|
type: type || data.type,
|
|
|
|
|
}
|
2018-06-19 16:17:50 +03:00
|
|
|
} else {
|
2021-04-25 13:24:08 +03:00
|
|
|
delete state.highlight[user]
|
2018-06-19 16:17:50 +03:00
|
|
|
}
|
2026-01-06 16:22:52 +02:00
|
|
|
},
|
2017-02-14 22:21:23 +01:00
|
|
|
},
|
|
|
|
|
actions: {
|
2026-01-06 16:22:52 +02:00
|
|
|
loadSettings({ dispatch }, data) {
|
2021-03-08 21:56:20 +02:00
|
|
|
const knownKeys = new Set(Object.keys(defaultState))
|
2021-03-08 21:14:03 +02:00
|
|
|
const presentKeys = new Set(Object.keys(data))
|
|
|
|
|
const intersection = new Set()
|
2022-07-31 12:35:48 +03:00
|
|
|
for (const elem of presentKeys) {
|
2021-03-08 21:14:03 +02:00
|
|
|
if (knownKeys.has(elem)) {
|
|
|
|
|
intersection.add(elem)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-06 16:22:52 +02:00
|
|
|
intersection.forEach((name) =>
|
|
|
|
|
dispatch('setOption', { name, value: data[name] }),
|
2021-03-08 19:53:30 +02:00
|
|
|
)
|
|
|
|
|
},
|
2026-01-06 16:22:52 +02:00
|
|
|
setHighlight({ commit }, { user, color, type }) {
|
2019-07-05 10:02:14 +03:00
|
|
|
commit('setHighlight', { user, color, type })
|
2018-06-19 16:17:50 +03:00
|
|
|
},
|
2026-01-06 16:22:52 +02:00
|
|
|
setOptionTemporarily({ commit, dispatch, state }, { name, value }) {
|
2025-01-30 21:56:07 +02:00
|
|
|
if (useInterfaceStore().temporaryChangesTimeoutId !== null) {
|
2026-01-06 16:22:52 +02:00
|
|
|
console.warn("Can't track more than one temporary change")
|
2024-05-22 19:54:19 +03:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const oldValue = state[name]
|
|
|
|
|
|
|
|
|
|
commit('setOptionTemporarily', { name, value })
|
|
|
|
|
|
|
|
|
|
const confirm = () => {
|
|
|
|
|
dispatch('setOption', { name, value })
|
2025-03-19 03:33:05 +02:00
|
|
|
useInterfaceStore().clearTemporaryChanges()
|
2024-05-22 19:54:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const revert = () => {
|
|
|
|
|
commit('setOptionTemporarily', { name, value: oldValue })
|
2025-03-19 03:33:05 +02:00
|
|
|
useInterfaceStore().clearTemporaryChanges()
|
2024-05-22 19:54:19 +03:00
|
|
|
}
|
|
|
|
|
|
2025-03-19 03:33:05 +02:00
|
|
|
useInterfaceStore().setTemporaryChanges({
|
2024-05-22 19:54:19 +03:00
|
|
|
confirm,
|
2026-01-06 16:22:52 +02:00
|
|
|
revert,
|
2024-05-22 19:54:19 +03:00
|
|
|
})
|
|
|
|
|
},
|
2026-01-06 16:22:52 +02:00
|
|
|
setThemeV2({ commit, dispatch }, { customTheme, customThemeSource }) {
|
2024-07-17 22:10:11 +03:00
|
|
|
commit('setOption', { name: 'theme', value: 'custom' })
|
2024-07-12 02:40:57 +03:00
|
|
|
commit('setOption', { name: 'customTheme', value: customTheme })
|
2026-01-06 16:22:52 +02:00
|
|
|
commit('setOption', {
|
|
|
|
|
name: 'customThemeSource',
|
|
|
|
|
value: customThemeSource,
|
|
|
|
|
})
|
2024-07-12 02:40:57 +03:00
|
|
|
dispatch('setTheme', { themeData: customThemeSource, recompile: true })
|
|
|
|
|
},
|
2026-01-06 16:22:52 +02:00
|
|
|
setOption({ commit, dispatch, state }, { name, value }) {
|
|
|
|
|
const exceptions = new Set(['useStreamingApi'])
|
2023-03-12 16:51:50 +02:00
|
|
|
|
|
|
|
|
if (exceptions.has(name)) {
|
|
|
|
|
switch (name) {
|
|
|
|
|
case 'useStreamingApi': {
|
|
|
|
|
const action = value ? 'enableMastoSockets' : 'disableMastoSockets'
|
|
|
|
|
|
2026-01-06 16:22:52 +02:00
|
|
|
dispatch(action)
|
|
|
|
|
.then(() => {
|
|
|
|
|
commit('setOption', { name: 'useStreamingApi', value })
|
|
|
|
|
})
|
|
|
|
|
.catch((e) => {
|
|
|
|
|
console.error('Failed starting MastoAPI Streaming socket', e)
|
|
|
|
|
dispatch('disableMastoSockets')
|
|
|
|
|
dispatch('setOption', { name: 'useStreamingApi', value: false })
|
|
|
|
|
})
|
2024-07-12 02:40:57 +03:00
|
|
|
break
|
2023-03-12 16:51:50 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
commit('setOption', { name, value })
|
2024-07-16 21:01:20 +03:00
|
|
|
if (APPEARANCE_SETTINGS_KEYS.has(name)) {
|
2026-02-13 14:10:05 +02:00
|
|
|
applyStyleConfig(state)
|
2024-07-10 22:49:56 +03:00
|
|
|
}
|
2024-07-16 21:01:20 +03:00
|
|
|
if (name.startsWith('theme3hacks')) {
|
2024-12-22 16:49:42 +02:00
|
|
|
dispatch('applyTheme', { recompile: true })
|
2024-07-16 21:01:20 +03:00
|
|
|
}
|
2023-03-12 16:51:50 +02:00
|
|
|
switch (name) {
|
|
|
|
|
case 'theme':
|
2024-07-17 22:10:11 +03:00
|
|
|
if (value === 'custom') break
|
2026-01-06 16:22:52 +02:00
|
|
|
dispatch('setTheme', {
|
|
|
|
|
themeName: value,
|
|
|
|
|
recompile: true,
|
|
|
|
|
saveData: true,
|
|
|
|
|
})
|
2023-03-12 16:51:50 +02:00
|
|
|
break
|
2024-06-21 23:28:24 +03:00
|
|
|
case 'themeDebug': {
|
2024-07-10 22:49:56 +03:00
|
|
|
dispatch('setTheme', { recompile: true })
|
2023-03-12 16:51:50 +02:00
|
|
|
break
|
2024-06-21 23:28:24 +03:00
|
|
|
}
|
2023-03-12 16:51:50 +02:00
|
|
|
case 'interfaceLanguage':
|
2025-01-30 18:08:05 +02:00
|
|
|
messages.setLanguage(useI18nStore().i18n, value)
|
2026-01-29 01:45:31 +02:00
|
|
|
useEmojiStore().loadUnicodeEmojiData(value)
|
2023-03-12 16:51:50 +02:00
|
|
|
Cookies.set(
|
|
|
|
|
BACKEND_LANGUAGE_COOKIE_NAME,
|
2026-01-06 16:22:52 +02:00
|
|
|
localeService.internalToBackendLocaleMulti(value),
|
2023-03-12 16:51:50 +02:00
|
|
|
)
|
|
|
|
|
break
|
|
|
|
|
case 'thirdColumnMode':
|
2025-01-30 18:08:05 +02:00
|
|
|
useInterfaceStore().setLayoutWidth(undefined)
|
2023-03-12 16:51:50 +02:00
|
|
|
break
|
|
|
|
|
}
|
2017-02-14 22:21:23 +01:00
|
|
|
}
|
2026-01-06 16:22:52 +02:00
|
|
|
},
|
|
|
|
|
},
|
2017-02-14 22:21:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default config
|