pleroma-fe boots once again
This commit is contained in:
parent
58e18d48df
commit
c926ed7ac1
26 changed files with 1763 additions and 2245 deletions
|
@ -38,6 +38,7 @@
|
||||||
"pako": "^2.1.0",
|
"pako": "^2.1.0",
|
||||||
"parse-link-header": "2.0.0",
|
"parse-link-header": "2.0.0",
|
||||||
"phoenix": "1.7.18",
|
"phoenix": "1.7.18",
|
||||||
|
"pinia": "^2.0.33",
|
||||||
"punycode.js": "2.3.1",
|
"punycode.js": "2.3.1",
|
||||||
"qrcode": "1.5.4",
|
"qrcode": "1.5.4",
|
||||||
"querystring-es3": "0.2.1",
|
"querystring-es3": "0.2.1",
|
||||||
|
|
|
@ -62,7 +62,7 @@ export default {
|
||||||
document.getElementById('modal').classList = ['-' + this.layoutType]
|
document.getElementById('modal').classList = ['-' + this.layoutType]
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
if (this.$store.state.interface.themeApplied) {
|
if (useInterfaceStore().themeApplied) {
|
||||||
this.removeSplash()
|
this.removeSplash()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -71,7 +71,7 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
themeApplied () {
|
themeApplied () {
|
||||||
return this.$store.state.interface.themeApplied
|
return useInterfaceStore().themeApplied
|
||||||
},
|
},
|
||||||
layoutModalClass () {
|
layoutModalClass () {
|
||||||
return '-' + this.layoutType
|
return '-' + this.layoutType
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-show="$store.state.interface.themeApplied"
|
v-show="themeApplied"
|
||||||
id="app-loaded"
|
id="app-loaded"
|
||||||
:style="bgStyle"
|
:style="bgStyle"
|
||||||
>
|
>
|
||||||
|
|
|
@ -359,7 +359,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
||||||
|
|
||||||
await setConfig({ store })
|
await setConfig({ store })
|
||||||
try {
|
try {
|
||||||
await store.dispatch('applyTheme').catch((e) => { console.error('Error setting theme', e) })
|
await useInterfaceStore().applyTheme().catch((e) => { console.error('Error setting theme', e) })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.splashError(e)
|
window.splashError(e)
|
||||||
return Promise.reject(e)
|
return Promise.reject(e)
|
||||||
|
|
|
@ -3,8 +3,10 @@ import Status from '../status/status.vue'
|
||||||
import ThreadTree from '../thread_tree/thread_tree.vue'
|
import ThreadTree from '../thread_tree/thread_tree.vue'
|
||||||
import { WSConnectionStatus } from '../../services/api/api.service.js'
|
import { WSConnectionStatus } from '../../services/api/api.service.js'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { mapGetters, mapState } from 'vuex'
|
||||||
|
import { mapState as mapPiniaState } from 'pinia'
|
||||||
import QuickFilterSettings from '../quick_filter_settings/quick_filter_settings.vue'
|
import QuickFilterSettings from '../quick_filter_settings/quick_filter_settings.vue'
|
||||||
import QuickViewSettings from '../quick_view_settings/quick_view_settings.vue'
|
import QuickViewSettings from '../quick_view_settings/quick_view_settings.vue'
|
||||||
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
@ -350,8 +352,10 @@ const conversation = {
|
||||||
},
|
},
|
||||||
...mapGetters(['mergedConfig']),
|
...mapGetters(['mergedConfig']),
|
||||||
...mapState({
|
...mapState({
|
||||||
mobileLayout: state => state.interface.layoutType === 'mobile',
|
|
||||||
mastoUserSocketStatus: state => state.api.mastoUserSocketStatus
|
mastoUserSocketStatus: state => state.api.mastoUserSocketStatus
|
||||||
|
}),
|
||||||
|
...mapPiniaState(useInterfaceStore, {
|
||||||
|
mobileLayout: store => store.layoutType === 'mobile'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
import { mapState as mapPiniaState } from 'pinia'
|
||||||
|
import { useAnnouncementsStore } from '../../stores/announcements'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
@ -33,7 +35,10 @@ const ExtraNotifications = {
|
||||||
currentUser () {
|
currentUser () {
|
||||||
return this.$store.state.users.currentUser
|
return this.$store.state.users.currentUser
|
||||||
},
|
},
|
||||||
...mapGetters(['unreadChatCount', 'unreadAnnouncementCount', 'followRequestCount', 'mergedConfig'])
|
...mapGetters(['unreadChatCount', 'followRequestCount', 'mergedConfig']),
|
||||||
|
...mapPiniaState(useAnnouncementsStore, {
|
||||||
|
unreadAnnouncementCount: 'unreadAnnouncementCount'
|
||||||
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openNotificationSettings () {
|
openNotificationSettings () {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import Select from '../select/select.vue'
|
import Select from '../select/select.vue'
|
||||||
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||||
import Popover from 'src/components/popover/popover.vue'
|
import Popover from 'src/components/popover/popover.vue'
|
||||||
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
@ -50,10 +51,10 @@ export default {
|
||||||
return typeof this.modelValue !== 'undefined'
|
return typeof this.modelValue !== 'undefined'
|
||||||
},
|
},
|
||||||
localFontsList () {
|
localFontsList () {
|
||||||
return this.$store.state.interface.localFonts
|
return useInterfaceStore().localFonts
|
||||||
},
|
},
|
||||||
localFontsSize () {
|
localFontsSize () {
|
||||||
return this.$store.state.interface.localFonts?.length
|
return useInterfaceStore().localFonts?.length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { filterNavigation } from 'src/components/navigation/filter.js'
|
||||||
import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
|
import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
|
||||||
import NavigationPins from 'src/components/navigation/navigation_pins.vue'
|
import NavigationPins from 'src/components/navigation/navigation_pins.vue'
|
||||||
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||||
|
import { useAnnouncementsStore } from 'src/stores/announcements'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
@ -24,7 +25,6 @@ import {
|
||||||
faBullhorn,
|
faBullhorn,
|
||||||
faFilePen
|
faFilePen
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { useAnnouncementsStore } from '../../stores/announcements'
|
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
faUsers,
|
faUsers,
|
||||||
|
|
|
@ -17,7 +17,8 @@ import {
|
||||||
faStream,
|
faStream,
|
||||||
faList
|
faList
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { useListsStore } from '../../stores/lists'
|
import { useListsStore } from 'src/stores/lists'
|
||||||
|
import { useAnnouncementsStore } from 'src/stores/announcements'
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
faUsers,
|
faUsers,
|
||||||
|
@ -48,6 +49,9 @@ const NavPanel = {
|
||||||
...mapPiniaState(useListsStore, {
|
...mapPiniaState(useListsStore, {
|
||||||
lists: getListEntries
|
lists: getListEntries
|
||||||
}),
|
}),
|
||||||
|
...mapPiniaState(useAnnouncementsStore, {
|
||||||
|
supportsAnnouncements: store => store.supportsAnnouncements
|
||||||
|
}),
|
||||||
...mapState({
|
...mapState({
|
||||||
bookmarks: getBookmarkFolderEntries,
|
bookmarks: getBookmarkFolderEntries,
|
||||||
currentUser: state => state.users.currentUser,
|
currentUser: state => state.users.currentUser,
|
||||||
|
@ -55,7 +59,6 @@ const NavPanel = {
|
||||||
privateMode: state => state.instance.private,
|
privateMode: state => state.instance.private,
|
||||||
federating: state => state.instance.federating,
|
federating: state => state.instance.federating,
|
||||||
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable,
|
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable,
|
||||||
supportsAnnouncements: state => state.announcements.supportsAnnouncements,
|
|
||||||
pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems)
|
pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems)
|
||||||
}),
|
}),
|
||||||
pinnedList () {
|
pinnedList () {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||||
import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
|
import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { cloneDeep, isEqual } from 'lodash'
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
|
import { mapState as mapPiniaState } from 'pinia'
|
||||||
import {
|
import {
|
||||||
newImporter,
|
newImporter,
|
||||||
newExporter
|
newExporter
|
||||||
|
@ -167,24 +168,15 @@ const SettingsModal = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
currentSaveStateNotice () {
|
...mapPiniaState(useInterfaceStore, {
|
||||||
return useInterfaceStore().settings.currentSaveStateNotice
|
temporaryChangesTimeoutId: store => store.layoutType === 'mobile',
|
||||||
},
|
currentSaveStateNotice: store => store.settings.currentSaveStateNotice,
|
||||||
modalActivated () {
|
modalActivated: store => store.settingsModalState !== 'hidden',
|
||||||
return useInterfaceStore().settingsModalState !== 'hidden'
|
modalMode: store => store.settingsModalMode,
|
||||||
},
|
modalOpenedOnceUser: store => store.settingsModalLoadedUser,
|
||||||
modalMode () {
|
modalOpenedOnceAdmin: store => store.settingsModalLoadedAdmin,
|
||||||
return useInterfaceStore().settingsModalMode
|
modalPeeked: store => store.settingsModalState === 'minimized'
|
||||||
},
|
}),
|
||||||
modalOpenedOnceUser () {
|
|
||||||
return useInterfaceStore().settingsModalLoadedUser
|
|
||||||
},
|
|
||||||
modalOpenedOnceAdmin () {
|
|
||||||
return useInterfaceStore().settingsModalLoadedAdmin
|
|
||||||
},
|
|
||||||
modalPeeked () {
|
|
||||||
return useInterfaceStore().settingsModalState === 'minimized'
|
|
||||||
},
|
|
||||||
expertLevel: {
|
expertLevel: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state.config.expertLevel > 0
|
return this.$store.state.config.expertLevel > 0
|
||||||
|
|
|
@ -158,7 +158,7 @@
|
||||||
</div>
|
</div>
|
||||||
<teleport to="#modal">
|
<teleport to="#modal">
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
v-if="$store.state.interface.temporaryChangesTimeoutId"
|
v-if="temporaryChangesTimeoutId"
|
||||||
:title="$t('settings.confirm_new_setting')"
|
:title="$t('settings.confirm_new_setting')"
|
||||||
:cancel-text="$t('settings.revert')"
|
:cancel-text="$t('settings.revert')"
|
||||||
:confirm-text="$t('settings.confirm')"
|
:confirm-text="$t('settings.confirm')"
|
||||||
|
|
|
@ -4,6 +4,7 @@ import InstanceTab from './admin_tabs/instance_tab.vue'
|
||||||
import LimitsTab from './admin_tabs/limits_tab.vue'
|
import LimitsTab from './admin_tabs/limits_tab.vue'
|
||||||
import FrontendsTab from './admin_tabs/frontends_tab.vue'
|
import FrontendsTab from './admin_tabs/frontends_tab.vue'
|
||||||
import EmojiTab from './admin_tabs/emoji_tab.vue'
|
import EmojiTab from './admin_tabs/emoji_tab.vue'
|
||||||
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
|
@ -45,10 +46,10 @@ const SettingsModalAdminContent = {
|
||||||
return !!this.$store.state.users.currentUser
|
return !!this.$store.state.users.currentUser
|
||||||
},
|
},
|
||||||
open () {
|
open () {
|
||||||
return this.$store.state.interface.settingsModalState !== 'hidden'
|
return useInterfaceStore().settingsModalState !== 'hidden'
|
||||||
},
|
},
|
||||||
bodyLock () {
|
bodyLock () {
|
||||||
return this.$store.state.interface.settingsModalState === 'visible'
|
return useInterfaceStore().settingsModalState === 'visible'
|
||||||
},
|
},
|
||||||
adminDbLoaded () {
|
adminDbLoaded () {
|
||||||
return this.$store.state.adminSettings.loaded
|
return this.$store.state.adminSettings.loaded
|
||||||
|
@ -67,7 +68,7 @@ const SettingsModalAdminContent = {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onOpen () {
|
onOpen () {
|
||||||
const targetTab = this.$store.state.interface.settingsModalTargetTab
|
const targetTab = useInterfaceStore().settingsModalTargetTab
|
||||||
// We're being told to open in specific tab
|
// We're being told to open in specific tab
|
||||||
if (targetTab) {
|
if (targetTab) {
|
||||||
const tabIndex = this.$refs.tabSwitcher.$slots.default().findIndex(elm => {
|
const tabIndex = this.$refs.tabSwitcher.$slots.default().findIndex(elm => {
|
||||||
|
|
|
@ -25,7 +25,7 @@ import {
|
||||||
faInfo,
|
faInfo,
|
||||||
faWindowRestore
|
faWindowRestore
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { useInterfaceStore } from '../../stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
faWrench,
|
faWrench,
|
||||||
|
@ -70,7 +70,7 @@ const SettingsModalContent = {
|
||||||
return this.$store.state.config.expertLevel
|
return this.$store.state.config.expertLevel
|
||||||
},
|
},
|
||||||
isMobileLayout () {
|
isMobileLayout () {
|
||||||
return this.$store.state.interface.layoutType === 'mobile'
|
return useInterfaceStore().layoutType === 'mobile'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import PaletteEditor from 'src/components/palette_editor/palette_editor.vue'
|
||||||
|
|
||||||
import FontControl from 'src/components/font_control/font_control.vue'
|
import FontControl from 'src/components/font_control/font_control.vue'
|
||||||
|
|
||||||
import { normalizeThemeData } from 'src/modules/interface'
|
import { useInterfaceStore, normalizeThemeData } from 'src/stores/interface'
|
||||||
|
|
||||||
import { newImporter } from 'src/services/export_import/export_import.js'
|
import { newImporter } from 'src/services/export_import/export_import.js'
|
||||||
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
|
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
|
||||||
|
@ -131,7 +131,7 @@ const AppearanceTab = {
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
this.userPalette = this.$store.state.interface.paletteDataUsed || {}
|
this.userPalette = useInterfaceStore().paletteDataUsed || {}
|
||||||
|
|
||||||
updateIndex('palette').then(bundledPalettes => {
|
updateIndex('palette').then(bundledPalettes => {
|
||||||
bundledPalettes.forEach(([key, palettePromise]) => palettePromise.then(v => {
|
bundledPalettes.forEach(([key, palettePromise]) => palettePromise.then(v => {
|
||||||
|
@ -187,10 +187,10 @@ const AppearanceTab = {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
switchInProgress () {
|
switchInProgress () {
|
||||||
return this.$store.state.interface.themeChangeInProgress
|
return useInterfaceStore().themeChangeInProgress
|
||||||
},
|
},
|
||||||
paletteDataUsed () {
|
paletteDataUsed () {
|
||||||
return this.$store.state.interface.paletteDataUsed
|
return useInterfaceStore().paletteDataUsed
|
||||||
},
|
},
|
||||||
availableStyles () {
|
availableStyles () {
|
||||||
return [
|
return [
|
||||||
|
@ -205,7 +205,7 @@ const AppearanceTab = {
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
stylePalettes () {
|
stylePalettes () {
|
||||||
const ruleset = this.$store.state.interface.styleDataUsed || []
|
const ruleset = useInterfaceStore().styleDataUsed || []
|
||||||
if (!ruleset && ruleset.length === 0) return
|
if (!ruleset && ruleset.length === 0) return
|
||||||
const meta = ruleset.find(x => x.component === '@meta')
|
const meta = ruleset.find(x => x.component === '@meta')
|
||||||
const result = ruleset.filter(x => x.component.startsWith('@palette'))
|
const result = ruleset.filter(x => x.component.startsWith('@palette'))
|
||||||
|
@ -273,7 +273,7 @@ const AppearanceTab = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
customThemeVersion () {
|
customThemeVersion () {
|
||||||
const { themeVersion } = this.$store.state.interface
|
const { themeVersion } = useInterfaceStore()
|
||||||
return themeVersion
|
return themeVersion
|
||||||
},
|
},
|
||||||
isCustomThemeUsed () {
|
isCustomThemeUsed () {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { ref, reactive, computed, watch, watchEffect, provide, getCurrentInstance } from 'vue'
|
import { ref, reactive, computed, watch, watchEffect, provide, getCurrentInstance } from 'vue'
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
import { get, set, unset, throttle } from 'lodash'
|
import { get, set, unset, throttle } from 'lodash'
|
||||||
|
|
||||||
import Select from 'src/components/select/select.vue'
|
import Select from 'src/components/select/select.vue'
|
||||||
|
@ -81,9 +82,10 @@ export default {
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const exports = {}
|
const exports = {}
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
const interfaceStore = useInterfaceStore()
|
||||||
// All rules that are made by editor
|
// All rules that are made by editor
|
||||||
const allEditedRules = ref(store.state.interface.styleDataUsed || {})
|
const allEditedRules = ref(interfaceStore.styleDataUsed || {})
|
||||||
const styleDataUsed = computed(() => store.state.interface.styleDataUsed)
|
const styleDataUsed = computed(() => interfaceStore.styleDataUsed)
|
||||||
|
|
||||||
watch([styleDataUsed], (value) => {
|
watch([styleDataUsed], (value) => {
|
||||||
onImport(store.state.interface.styleDataUsed)
|
onImport(store.state.interface.styleDataUsed)
|
||||||
|
|
|
@ -297,7 +297,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
themeDataUsed () {
|
themeDataUsed () {
|
||||||
return this.$store.state.interface.themeDataUsed
|
return useInterfaceStore().themeDataUsed
|
||||||
},
|
},
|
||||||
shadowsAvailable () {
|
shadowsAvailable () {
|
||||||
return Object.keys(DEFAULT_SHADOWS).sort()
|
return Object.keys(DEFAULT_SHADOWS).sort()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import StillImage from '../still-image/still-image.vue'
|
import StillImage from '../still-image/still-image.vue'
|
||||||
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ const UserAvatar = {
|
||||||
return {
|
return {
|
||||||
showPlaceholder: false,
|
showPlaceholder: false,
|
||||||
defaultAvatar: `${this.$store.state.instance.server + this.$store.state.instance.defaultAvatar}`,
|
defaultAvatar: `${this.$store.state.instance.server + this.$store.state.instance.defaultAvatar}`,
|
||||||
betterShadow: this.$store.state.interface.browserSupport.cssFilter
|
betterShadow: useInterfaceStore().browserSupport.cssFilter
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
11
src/main.js
11
src/main.js
|
@ -14,18 +14,11 @@ import configModule from './modules/config.js'
|
||||||
import profileConfigModule from './modules/profileConfig.js'
|
import profileConfigModule from './modules/profileConfig.js'
|
||||||
import serverSideStorageModule from './modules/serverSideStorage.js'
|
import serverSideStorageModule from './modules/serverSideStorage.js'
|
||||||
import adminSettingsModule from './modules/adminSettings.js'
|
import adminSettingsModule from './modules/adminSettings.js'
|
||||||
import shoutModule from './modules/shout.js'
|
|
||||||
import oauthModule from './modules/oauth.js'
|
import oauthModule from './modules/oauth.js'
|
||||||
import authFlowModule from './modules/auth_flow.js'
|
import authFlowModule from './modules/auth_flow.js'
|
||||||
import oauthTokensModule from './modules/oauth_tokens.js'
|
import oauthTokensModule from './modules/oauth_tokens.js'
|
||||||
import reportsModule from './modules/reports.js'
|
|
||||||
import pollsModule from './modules/polls.js'
|
|
||||||
import postStatusModule from './modules/postStatus.js'
|
|
||||||
import editStatusModule from './modules/editStatus.js'
|
|
||||||
import statusHistoryModule from './modules/statusHistory.js'
|
|
||||||
import draftsModule from './modules/drafts.js'
|
import draftsModule from './modules/drafts.js'
|
||||||
import chatsModule from './modules/chats.js'
|
import chatsModule from './modules/chats.js'
|
||||||
import announcementsModule from './modules/announcements.js'
|
|
||||||
import bookmarkFoldersModule from './modules/bookmark_folders.js'
|
import bookmarkFoldersModule from './modules/bookmark_folders.js'
|
||||||
|
|
||||||
import { createI18n } from 'vue-i18n'
|
import { createI18n } from 'vue-i18n'
|
||||||
|
@ -101,6 +94,7 @@ const persistedStateOptions = {
|
||||||
instance: instanceModule,
|
instance: instanceModule,
|
||||||
// TODO refactor users/statuses modules, they depend on each other
|
// TODO refactor users/statuses modules, they depend on each other
|
||||||
users: usersModule,
|
users: usersModule,
|
||||||
|
lists: listsModule,
|
||||||
statuses: statusesModule,
|
statuses: statusesModule,
|
||||||
notifications: notificationsModule,
|
notifications: notificationsModule,
|
||||||
api: apiModule,
|
api: apiModule,
|
||||||
|
@ -122,10 +116,11 @@ const persistedStateOptions = {
|
||||||
strict: false // Socket modifies itself, let's ignore this for now.
|
strict: false // Socket modifies itself, let's ignore this for now.
|
||||||
// strict: process.env.NODE_ENV !== 'production'
|
// strict: process.env.NODE_ENV !== 'production'
|
||||||
})
|
})
|
||||||
|
window.vuex = store
|
||||||
if (storageError) {
|
if (storageError) {
|
||||||
// Temporarily passing pinia and vuex stores along with storageError result until migration is fully complete.
|
|
||||||
store.dispatch('pushGlobalNotice', { messageKey: 'errors.storage_unavailable', level: 'error' })
|
store.dispatch('pushGlobalNotice', { messageKey: 'errors.storage_unavailable', level: 'error' })
|
||||||
}
|
}
|
||||||
|
// Temporarily passing pinia and vuex stores along with storageError result until migration is fully complete.
|
||||||
return await afterStoreSetup({ pinia, store, storageError, i18n })
|
return await afterStoreSetup({ pinia, store, storageError, i18n })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
splashError(i18n, e)
|
splashError(i18n, e)
|
||||||
|
|
|
@ -6,6 +6,8 @@ import localeService from '../services/locale/locale.service.js'
|
||||||
import { useI18nStore } from '../stores/i18n.js'
|
import { useI18nStore } from '../stores/i18n.js'
|
||||||
import { useInterfaceStore } from '../stores/interface.js'
|
import { useInterfaceStore } from '../stores/interface.js'
|
||||||
|
|
||||||
|
import { defaultState } from './default_config_state.js'
|
||||||
|
|
||||||
const BACKEND_LANGUAGE_COOKIE_NAME = 'userLanguage'
|
const BACKEND_LANGUAGE_COOKIE_NAME = 'userLanguage'
|
||||||
const APPEARANCE_SETTINGS_KEYS = new Set([
|
const APPEARANCE_SETTINGS_KEYS = new Set([
|
||||||
'sidebarColumnWidth',
|
'sidebarColumnWidth',
|
||||||
|
@ -19,8 +21,6 @@ const APPEARANCE_SETTINGS_KEYS = new Set([
|
||||||
'emojiReactionsScale'
|
'emojiReactionsScale'
|
||||||
])
|
])
|
||||||
|
|
||||||
const browserLocale = (window.navigator.language || 'en').split('-')[0]
|
|
||||||
|
|
||||||
/* TODO this is a bit messy.
|
/* TODO this is a bit messy.
|
||||||
* We need to declare settings with their types and also deal with
|
* We need to declare settings with their types and also deal with
|
||||||
* instance-default settings in some way, hopefully try to avoid copy-pasta
|
* instance-default settings in some way, hopefully try to avoid copy-pasta
|
||||||
|
@ -36,168 +36,7 @@ export const multiChoiceProperties = [
|
||||||
'unsavedPostAction' // save | discard | confirm
|
'unsavedPostAction' // save | discard | confirm
|
||||||
]
|
]
|
||||||
|
|
||||||
export const defaultState = {
|
console.log('TEST', defaultState)
|
||||||
expertLevel: 0, // used to track which settings to show and hide
|
|
||||||
|
|
||||||
// Theme stuff
|
|
||||||
theme: undefined, // Very old theme store, stores preset name, still in use
|
|
||||||
|
|
||||||
// V1
|
|
||||||
colors: {}, // VERY old theme store, just colors of V1, probably not even used anymore
|
|
||||||
|
|
||||||
// V2
|
|
||||||
customTheme: undefined, // "snapshot", previously was used as actual theme store for V2 so it's still used in case of PleromaFE downgrade event.
|
|
||||||
customThemeSource: undefined, // "source", stores original theme data
|
|
||||||
|
|
||||||
// V3
|
|
||||||
style: null,
|
|
||||||
styleCustomData: null,
|
|
||||||
palette: 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
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
hideISP: false,
|
|
||||||
hideInstanceWallpaper: false,
|
|
||||||
hideShoutbox: false,
|
|
||||||
// bad name: actually hides posts of muted USERS
|
|
||||||
hideMutedPosts: undefined, // instance default
|
|
||||||
hideMutedThreads: undefined, // instance default
|
|
||||||
hideWordFilteredPosts: undefined, // instance default
|
|
||||||
muteBotStatuses: undefined, // instance default
|
|
||||||
muteSensitiveStatuses: undefined, // instance default
|
|
||||||
collapseMessageWithSubject: undefined, // instance default
|
|
||||||
padEmoji: true,
|
|
||||||
hideAttachments: false,
|
|
||||||
hideAttachmentsInConv: false,
|
|
||||||
hideScrobbles: false,
|
|
||||||
hideScrobblesAfter: '2d',
|
|
||||||
maxThumbnails: 16,
|
|
||||||
hideNsfw: true,
|
|
||||||
preloadImage: true,
|
|
||||||
loopVideo: true,
|
|
||||||
loopVideoSilentOnly: true,
|
|
||||||
streaming: false,
|
|
||||||
emojiReactionsOnTimeline: true,
|
|
||||||
alwaysShowNewPostButton: false,
|
|
||||||
autohideFloatingPostButton: false,
|
|
||||||
pauseOnUnfocused: true,
|
|
||||||
stopGifs: true,
|
|
||||||
replyVisibility: 'all',
|
|
||||||
thirdColumnMode: 'notifications',
|
|
||||||
notificationVisibility: {
|
|
||||||
follows: true,
|
|
||||||
mentions: true,
|
|
||||||
statuses: true,
|
|
||||||
likes: true,
|
|
||||||
repeats: true,
|
|
||||||
moves: true,
|
|
||||||
emojiReactions: true,
|
|
||||||
followRequest: true,
|
|
||||||
reports: true,
|
|
||||||
chatMention: true,
|
|
||||||
polls: true
|
|
||||||
},
|
|
||||||
notificationNative: {
|
|
||||||
follows: true,
|
|
||||||
mentions: true,
|
|
||||||
statuses: true,
|
|
||||||
likes: false,
|
|
||||||
repeats: false,
|
|
||||||
moves: false,
|
|
||||||
emojiReactions: false,
|
|
||||||
followRequest: true,
|
|
||||||
reports: true,
|
|
||||||
chatMention: true,
|
|
||||||
polls: true
|
|
||||||
},
|
|
||||||
webPushNotifications: false,
|
|
||||||
webPushAlwaysShowNotifications: false,
|
|
||||||
muteWords: [],
|
|
||||||
highlight: {},
|
|
||||||
interfaceLanguage: browserLocale,
|
|
||||||
hideScopeNotice: false,
|
|
||||||
useStreamingApi: false,
|
|
||||||
sidebarRight: undefined, // instance default
|
|
||||||
scopeCopy: undefined, // instance default
|
|
||||||
subjectLineBehavior: undefined, // instance default
|
|
||||||
alwaysShowSubjectInput: undefined, // instance default
|
|
||||||
postContentType: undefined, // instance default
|
|
||||||
minimalScopesMode: undefined, // instance default
|
|
||||||
// This hides statuses filtered via a word filter
|
|
||||||
hideFilteredStatuses: undefined, // instance default
|
|
||||||
modalOnRepeat: undefined, // instance default
|
|
||||||
modalOnUnfollow: undefined, // instance default
|
|
||||||
modalOnBlock: undefined, // instance default
|
|
||||||
modalOnMute: undefined, // instance default
|
|
||||||
modalOnMuteConversation: undefined, // instance default
|
|
||||||
modalOnMuteDomain: undefined, // instance default
|
|
||||||
modalOnDelete: undefined, // instance default
|
|
||||||
modalOnLogout: undefined, // instance default
|
|
||||||
modalOnApproveFollow: undefined, // instance default
|
|
||||||
modalOnDenyFollow: undefined, // instance default
|
|
||||||
modalOnRemoveUserFromFollowers: undefined, // instance default
|
|
||||||
modalMobileCenter: undefined,
|
|
||||||
playVideosInModal: false,
|
|
||||||
useOneClickNsfw: false,
|
|
||||||
useContainFit: true,
|
|
||||||
disableStickyHeaders: false,
|
|
||||||
showScrollbars: false,
|
|
||||||
userPopoverAvatarAction: 'open',
|
|
||||||
userPopoverOverlay: false,
|
|
||||||
sidebarColumnWidth: '25rem',
|
|
||||||
contentColumnWidth: '45rem',
|
|
||||||
notifsColumnWidth: '25rem',
|
|
||||||
emojiReactionsScale: undefined,
|
|
||||||
textSize: undefined, // instance default
|
|
||||||
emojiSize: undefined, // instance default
|
|
||||||
navbarSize: undefined, // instance default
|
|
||||||
panelHeaderSize: undefined, // instance default
|
|
||||||
forcedRoundness: undefined, // instance default
|
|
||||||
navbarColumnStretch: false,
|
|
||||||
greentext: undefined, // instance default
|
|
||||||
useAtIcon: undefined, // instance default
|
|
||||||
mentionLinkDisplay: undefined, // instance default
|
|
||||||
mentionLinkShowTooltip: undefined, // instance default
|
|
||||||
mentionLinkShowAvatar: undefined, // instance default
|
|
||||||
mentionLinkFadeDomain: undefined, // instance default
|
|
||||||
mentionLinkShowYous: undefined, // instance default
|
|
||||||
mentionLinkBoldenYou: undefined, // instance default
|
|
||||||
hidePostStats: undefined, // instance default
|
|
||||||
hideBotIndication: undefined, // instance default
|
|
||||||
hideUserStats: undefined, // instance default
|
|
||||||
virtualScrolling: undefined, // instance default
|
|
||||||
sensitiveByDefault: undefined, // instance default
|
|
||||||
conversationDisplay: undefined, // instance default
|
|
||||||
conversationTreeAdvanced: undefined, // instance default
|
|
||||||
conversationOtherRepliesButton: undefined, // instance default
|
|
||||||
conversationTreeFadeAncestors: undefined, // instance default
|
|
||||||
showExtraNotifications: undefined, // instance default
|
|
||||||
showExtraNotificationsTip: undefined, // instance default
|
|
||||||
showChatsInExtraNotifications: undefined, // instance default
|
|
||||||
showAnnouncementsInExtraNotifications: undefined, // instance default
|
|
||||||
showFollowRequestsInExtraNotifications: undefined, // instance default
|
|
||||||
maxDepthInThread: undefined, // instance default
|
|
||||||
autocompleteSelect: undefined, // instance default
|
|
||||||
closingDrawerMarksAsSeen: undefined, // instance default
|
|
||||||
unseenAtTop: undefined, // instance default
|
|
||||||
ignoreInactionableSeen: undefined, // instance default
|
|
||||||
unsavedPostAction: undefined, // instance default
|
|
||||||
autoSaveDraft: undefined, // instance default
|
|
||||||
useAbsoluteTimeFormat: undefined, // instance default
|
|
||||||
absoluteTimeFormatMinAge: undefined, // instance default
|
|
||||||
absoluteTime12h: undefined, // instance default
|
|
||||||
imageCompression: true
|
|
||||||
}
|
|
||||||
|
|
||||||
// caching the instance default properties
|
// caching the instance default properties
|
||||||
export const instanceDefaultProperties = Object.entries(defaultState)
|
export const instanceDefaultProperties = Object.entries(defaultState)
|
||||||
|
@ -261,7 +100,7 @@ const config = {
|
||||||
commit('setHighlight', { user, color, type })
|
commit('setHighlight', { user, color, type })
|
||||||
},
|
},
|
||||||
setOptionTemporarily ({ commit, dispatch, state, rootState }, { name, value }) {
|
setOptionTemporarily ({ commit, dispatch, state, rootState }, { name, value }) {
|
||||||
if (rootState.interface.temporaryChangesTimeoutId !== null) {
|
if (useInterfaceStore().temporaryChangesTimeoutId !== null) {
|
||||||
console.warn('Can\'t track more than one temporary change')
|
console.warn('Can\'t track more than one temporary change')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
164
src/modules/default_config_state.js
Normal file
164
src/modules/default_config_state.js
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
const browserLocale = (window.navigator.language || 'en').split('-')[0]
|
||||||
|
|
||||||
|
export const defaultState = {
|
||||||
|
expertLevel: 0, // used to track which settings to show and hide
|
||||||
|
|
||||||
|
// Theme stuff
|
||||||
|
theme: undefined, // Very old theme store, stores preset name, still in use
|
||||||
|
|
||||||
|
// V1
|
||||||
|
colors: {}, // VERY old theme store, just colors of V1, probably not even used anymore
|
||||||
|
|
||||||
|
// V2
|
||||||
|
customTheme: undefined, // "snapshot", previously was used as actual theme store for V2 so it's still used in case of PleromaFE downgrade event.
|
||||||
|
customThemeSource: undefined, // "source", stores original theme data
|
||||||
|
|
||||||
|
// V3
|
||||||
|
style: null,
|
||||||
|
styleCustomData: null,
|
||||||
|
palette: 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
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
hideISP: false,
|
||||||
|
hideInstanceWallpaper: false,
|
||||||
|
hideShoutbox: false,
|
||||||
|
// bad name: actually hides posts of muted USERS
|
||||||
|
hideMutedPosts: undefined, // instance default
|
||||||
|
hideMutedThreads: undefined, // instance default
|
||||||
|
hideWordFilteredPosts: undefined, // instance default
|
||||||
|
muteBotStatuses: undefined, // instance default
|
||||||
|
muteSensitiveStatuses: undefined, // instance default
|
||||||
|
collapseMessageWithSubject: undefined, // instance default
|
||||||
|
padEmoji: true,
|
||||||
|
hideAttachments: false,
|
||||||
|
hideAttachmentsInConv: false,
|
||||||
|
hideScrobbles: false,
|
||||||
|
hideScrobblesAfter: '2d',
|
||||||
|
maxThumbnails: 16,
|
||||||
|
hideNsfw: true,
|
||||||
|
preloadImage: true,
|
||||||
|
loopVideo: true,
|
||||||
|
loopVideoSilentOnly: true,
|
||||||
|
streaming: false,
|
||||||
|
emojiReactionsOnTimeline: true,
|
||||||
|
alwaysShowNewPostButton: false,
|
||||||
|
autohideFloatingPostButton: false,
|
||||||
|
pauseOnUnfocused: true,
|
||||||
|
stopGifs: true,
|
||||||
|
replyVisibility: 'all',
|
||||||
|
thirdColumnMode: 'notifications',
|
||||||
|
notificationVisibility: {
|
||||||
|
follows: true,
|
||||||
|
mentions: true,
|
||||||
|
statuses: true,
|
||||||
|
likes: true,
|
||||||
|
repeats: true,
|
||||||
|
moves: true,
|
||||||
|
emojiReactions: true,
|
||||||
|
followRequest: true,
|
||||||
|
reports: true,
|
||||||
|
chatMention: true,
|
||||||
|
polls: true
|
||||||
|
},
|
||||||
|
notificationNative: {
|
||||||
|
follows: true,
|
||||||
|
mentions: true,
|
||||||
|
statuses: true,
|
||||||
|
likes: false,
|
||||||
|
repeats: false,
|
||||||
|
moves: false,
|
||||||
|
emojiReactions: false,
|
||||||
|
followRequest: true,
|
||||||
|
reports: true,
|
||||||
|
chatMention: true,
|
||||||
|
polls: true
|
||||||
|
},
|
||||||
|
webPushNotifications: false,
|
||||||
|
webPushAlwaysShowNotifications: false,
|
||||||
|
muteWords: [],
|
||||||
|
highlight: {},
|
||||||
|
interfaceLanguage: browserLocale,
|
||||||
|
hideScopeNotice: false,
|
||||||
|
useStreamingApi: false,
|
||||||
|
sidebarRight: undefined, // instance default
|
||||||
|
scopeCopy: undefined, // instance default
|
||||||
|
subjectLineBehavior: undefined, // instance default
|
||||||
|
alwaysShowSubjectInput: undefined, // instance default
|
||||||
|
postContentType: undefined, // instance default
|
||||||
|
minimalScopesMode: undefined, // instance default
|
||||||
|
// This hides statuses filtered via a word filter
|
||||||
|
hideFilteredStatuses: undefined, // instance default
|
||||||
|
modalOnRepeat: undefined, // instance default
|
||||||
|
modalOnUnfollow: undefined, // instance default
|
||||||
|
modalOnBlock: undefined, // instance default
|
||||||
|
modalOnMute: undefined, // instance default
|
||||||
|
modalOnMuteConversation: undefined, // instance default
|
||||||
|
modalOnMuteDomain: undefined, // instance default
|
||||||
|
modalOnDelete: undefined, // instance default
|
||||||
|
modalOnLogout: undefined, // instance default
|
||||||
|
modalOnApproveFollow: undefined, // instance default
|
||||||
|
modalOnDenyFollow: undefined, // instance default
|
||||||
|
modalOnRemoveUserFromFollowers: undefined, // instance default
|
||||||
|
modalMobileCenter: undefined,
|
||||||
|
playVideosInModal: false,
|
||||||
|
useOneClickNsfw: false,
|
||||||
|
useContainFit: true,
|
||||||
|
disableStickyHeaders: false,
|
||||||
|
showScrollbars: false,
|
||||||
|
userPopoverAvatarAction: 'open',
|
||||||
|
userPopoverOverlay: false,
|
||||||
|
sidebarColumnWidth: '25rem',
|
||||||
|
contentColumnWidth: '45rem',
|
||||||
|
notifsColumnWidth: '25rem',
|
||||||
|
emojiReactionsScale: undefined,
|
||||||
|
textSize: undefined, // instance default
|
||||||
|
emojiSize: undefined, // instance default
|
||||||
|
navbarSize: undefined, // instance default
|
||||||
|
panelHeaderSize: undefined, // instance default
|
||||||
|
forcedRoundness: undefined, // instance default
|
||||||
|
navbarColumnStretch: false,
|
||||||
|
greentext: undefined, // instance default
|
||||||
|
useAtIcon: undefined, // instance default
|
||||||
|
mentionLinkDisplay: undefined, // instance default
|
||||||
|
mentionLinkShowTooltip: undefined, // instance default
|
||||||
|
mentionLinkShowAvatar: undefined, // instance default
|
||||||
|
mentionLinkFadeDomain: undefined, // instance default
|
||||||
|
mentionLinkShowYous: undefined, // instance default
|
||||||
|
mentionLinkBoldenYou: undefined, // instance default
|
||||||
|
hidePostStats: undefined, // instance default
|
||||||
|
hideBotIndication: undefined, // instance default
|
||||||
|
hideUserStats: undefined, // instance default
|
||||||
|
virtualScrolling: undefined, // instance default
|
||||||
|
sensitiveByDefault: undefined, // instance default
|
||||||
|
conversationDisplay: undefined, // instance default
|
||||||
|
conversationTreeAdvanced: undefined, // instance default
|
||||||
|
conversationOtherRepliesButton: undefined, // instance default
|
||||||
|
conversationTreeFadeAncestors: undefined, // instance default
|
||||||
|
showExtraNotifications: undefined, // instance default
|
||||||
|
showExtraNotificationsTip: undefined, // instance default
|
||||||
|
showChatsInExtraNotifications: undefined, // instance default
|
||||||
|
showAnnouncementsInExtraNotifications: undefined, // instance default
|
||||||
|
showFollowRequestsInExtraNotifications: undefined, // instance default
|
||||||
|
maxDepthInThread: undefined, // instance default
|
||||||
|
autocompleteSelect: undefined, // instance default
|
||||||
|
closingDrawerMarksAsSeen: undefined, // instance default
|
||||||
|
unseenAtTop: undefined, // instance default
|
||||||
|
ignoreInactionableSeen: undefined, // instance default
|
||||||
|
unsavedPostAction: undefined, // instance default
|
||||||
|
autoSaveDraft: undefined, // instance default
|
||||||
|
useAbsoluteTimeFormat: undefined, // instance default
|
||||||
|
absoluteTimeFormatMinAge: undefined, // instance default
|
||||||
|
absoluteTime12h: undefined, // instance default
|
||||||
|
imageCompression: true
|
||||||
|
}
|
|
@ -11,6 +11,8 @@ import {
|
||||||
closeAllDesktopNotifications
|
closeAllDesktopNotifications
|
||||||
} from '../services/desktop_notification_utils/desktop_notification_utils.js'
|
} from '../services/desktop_notification_utils/desktop_notification_utils.js'
|
||||||
|
|
||||||
|
import { useReportsStore } from '../stores/reports.js'
|
||||||
|
|
||||||
const emptyNotifications = () => ({
|
const emptyNotifications = () => ({
|
||||||
desktopNotificationSilence: true,
|
desktopNotificationSilence: true,
|
||||||
maxId: 0,
|
maxId: 0,
|
||||||
|
@ -94,7 +96,7 @@ export const notifications = {
|
||||||
|
|
||||||
validNotifications.forEach(notification => {
|
validNotifications.forEach(notification => {
|
||||||
if (notification.type === 'pleroma:report') {
|
if (notification.type === 'pleroma:report') {
|
||||||
dispatch('addReport', notification.report)
|
useReportsStore().addReport(notification.report)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notification.type === 'pleroma:emoji_reaction') {
|
if (notification.type === 'pleroma:emoji_reaction') {
|
||||||
|
|
|
@ -13,7 +13,6 @@ import {
|
||||||
omitBy
|
omitBy
|
||||||
} from 'lodash'
|
} from 'lodash'
|
||||||
import apiService from '../services/api/api.service.js'
|
import apiService from '../services/api/api.service.js'
|
||||||
import { useReportsStore } from '../stores/reports.js'
|
|
||||||
|
|
||||||
const emptyTl = (userId = 0) => ({
|
const emptyTl = (userId = 0) => ({
|
||||||
statuses: [],
|
statuses: [],
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { muteWordHits } from '../status_parser/status_parser.js'
|
import { muteWordHits } from '../status_parser/status_parser.js'
|
||||||
import { showDesktopNotification } from '../desktop_notification_utils/desktop_notification_utils.js'
|
import { showDesktopNotification } from '../desktop_notification_utils/desktop_notification_utils.js'
|
||||||
import { useI18nStore } from '../../stores/i18n.js'
|
import { useI18nStore } from '../../stores/i18n.js'
|
||||||
|
import { useAnnouncementsStore } from 'src/stores/announcements'
|
||||||
|
|
||||||
import FaviconService from 'src/services/favicon_service/favicon_service.js'
|
import FaviconService from 'src/services/favicon_service/favicon_service.js'
|
||||||
|
|
||||||
|
@ -169,7 +170,7 @@ export const countExtraNotifications = (store) => {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
mergedConfig.showChatsInExtraNotifications ? rootGetters.unreadChatCount : 0,
|
mergedConfig.showChatsInExtraNotifications ? rootGetters.unreadChatCount : 0,
|
||||||
mergedConfig.showAnnouncementsInExtraNotifications ? rootGetters.unreadAnnouncementCount : 0,
|
mergedConfig.showAnnouncementsInExtraNotifications ? useAnnouncementsStore().unreadAnnouncementCount : 0,
|
||||||
mergedConfig.showFollowRequestsInExtraNotifications ? rootGetters.followRequestCount : 0
|
mergedConfig.showFollowRequestsInExtraNotifications ? rootGetters.followRequestCount : 0
|
||||||
].reduce((a, c) => a + c, 0)
|
].reduce((a, c) => a + c, 0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import { init, getEngineChecksum } from '../theme_data/theme_data_3.service.js'
|
import { init, getEngineChecksum } from '../theme_data/theme_data_3.service.js'
|
||||||
import { getCssRules } from '../theme_data/css_utils.js'
|
import { getCssRules } from '../theme_data/css_utils.js'
|
||||||
import { defaultState } from '../../modules/config.js'
|
import { defaultState } from 'src/modules/default_config_state.js'
|
||||||
import { chunk } from 'lodash'
|
import { chunk } from 'lodash'
|
||||||
import pako from 'pako'
|
import pako from 'pako'
|
||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
|
|
||||||
|
console.log('CONFIG', defaultState)
|
||||||
|
|
||||||
// On platforms where this is not supported, it will return undefined
|
// On platforms where this is not supported, it will return undefined
|
||||||
// Otherwise it will return an array
|
// Otherwise it will return an array
|
||||||
const supportsAdoptedStyleSheets = !!document.adoptedStyleSheets
|
const supportsAdoptedStyleSheets = !!document.adoptedStyleSheets
|
||||||
|
@ -212,6 +214,7 @@ const extractStyleConfig = ({
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(defaultState)
|
||||||
const defaultStyleConfig = extractStyleConfig(defaultState)
|
const defaultStyleConfig = extractStyleConfig(defaultState)
|
||||||
|
|
||||||
export const applyConfig = (input, i18n) => {
|
export const applyConfig = (input, i18n) => {
|
||||||
|
|
|
@ -1,10 +1,31 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
import { CURRENT_VERSION, generatePreset } from 'src/services/theme_data/theme_data.service.js'
|
||||||
|
import { getResourcesIndex, applyTheme, tryLoadCache } from '../services/style_setter/style_setter.js'
|
||||||
|
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
|
||||||
|
import { deserialize } from '../services/theme_data/iss_deserializer.js'
|
||||||
|
|
||||||
export const useInterfaceStore = defineStore('interface', {
|
export const useInterfaceStore = defineStore('interface', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
|
localFonts: null,
|
||||||
|
themeApplied: false,
|
||||||
|
themeChangeInProgress: false,
|
||||||
|
themeVersion: 'v3',
|
||||||
|
styleNameUsed: null,
|
||||||
|
styleDataUsed: null,
|
||||||
|
useStylePalette: false, // hack for applying styles from appearance tab
|
||||||
|
paletteNameUsed: null,
|
||||||
|
paletteDataUsed: null,
|
||||||
|
themeNameUsed: null,
|
||||||
|
themeDataUsed: null,
|
||||||
|
temporaryChangesTimeoutId: null, // used for temporary options that revert after a timeout
|
||||||
|
temporaryChangesConfirm: () => {}, // used for applying temporary options
|
||||||
|
temporaryChangesRevert: () => {}, // used for reverting temporary options
|
||||||
settingsModalState: 'hidden',
|
settingsModalState: 'hidden',
|
||||||
settingsModalLoaded: false,
|
settingsModalLoadedUser: false,
|
||||||
|
settingsModalLoadedAdmin: false,
|
||||||
settingsModalTargetTab: null,
|
settingsModalTargetTab: null,
|
||||||
|
settingsModalMode: 'user',
|
||||||
settings: {
|
settings: {
|
||||||
currentSaveStateNotice: null,
|
currentSaveStateNotice: null,
|
||||||
noticeClearTimeout: null,
|
noticeClearTimeout: null,
|
||||||
|
@ -46,10 +67,17 @@ export const useInterfaceStore = defineStore('interface', {
|
||||||
closeSettingsModal () {
|
closeSettingsModal () {
|
||||||
this.settingsModalState = 'hidden'
|
this.settingsModalState = 'hidden'
|
||||||
},
|
},
|
||||||
openSettingsModal () {
|
openSettingsModal (value) {
|
||||||
|
this.settingsModalMode = value
|
||||||
this.settingsModalState = 'visible'
|
this.settingsModalState = 'visible'
|
||||||
if (!this.settingsModalLoaded) {
|
if (value === 'user') {
|
||||||
this.settingsModalLoaded = true
|
if (!this.settingsModalLoadedUser) {
|
||||||
|
this.settingsModalLoadedUser = true
|
||||||
|
}
|
||||||
|
} else if (value === 'admin') {
|
||||||
|
if (!this.settingsModalLoadedAdmin) {
|
||||||
|
this.settingsModalLoadedAdmin = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
togglePeekSettingsModal () {
|
togglePeekSettingsModal () {
|
||||||
|
@ -121,6 +149,500 @@ export const useInterfaceStore = defineStore('interface', {
|
||||||
},
|
},
|
||||||
setLastTimeline (value) {
|
setLastTimeline (value) {
|
||||||
this.lastTimeline = value
|
this.lastTimeline = value
|
||||||
|
},
|
||||||
|
async fetchPalettesIndex () {
|
||||||
|
try {
|
||||||
|
const value = await getResourcesIndex('/static/palettes/index.json')
|
||||||
|
window.vuex.commit('setInstanceOption', { name: 'palettesIndex', value })
|
||||||
|
return value
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not fetch palettes index', e)
|
||||||
|
window.vuex.commit('setInstanceOption', { name: 'palettesIndex', value: { _error: e } })
|
||||||
|
return Promise.resolve({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setPalette (value) {
|
||||||
|
this.resetThemeV3Palette()
|
||||||
|
this.resetThemeV2()
|
||||||
|
|
||||||
|
window.vuex.commit('setOption', { name: 'palette', value })
|
||||||
|
|
||||||
|
this.applyTheme({ recompile: true })
|
||||||
|
},
|
||||||
|
setPaletteCustom (value) {
|
||||||
|
this.resetThemeV3Palette()
|
||||||
|
this.resetThemeV2()
|
||||||
|
|
||||||
|
window.vuex.commit('setOption', { name: 'paletteCustomData', value })
|
||||||
|
|
||||||
|
this.applyTheme({ recompile: true })
|
||||||
|
},
|
||||||
|
async fetchStylesIndex () {
|
||||||
|
try {
|
||||||
|
const value = await getResourcesIndex(
|
||||||
|
'/static/styles/index.json',
|
||||||
|
deserialize
|
||||||
|
)
|
||||||
|
window.vuex.commit('setInstanceOption', { name: 'stylesIndex', value })
|
||||||
|
return value
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not fetch styles index', e)
|
||||||
|
window.vuex.commit('setInstanceOption', { name: 'stylesIndex', value: { _error: e } })
|
||||||
|
return Promise.resolve({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setStyle (value) {
|
||||||
|
this.resetThemeV3()
|
||||||
|
this.resetThemeV2()
|
||||||
|
this.resetThemeV3Palette()
|
||||||
|
|
||||||
|
window.vuex.commit('setOption', { name: 'style', value })
|
||||||
|
this.useStylePalette = true
|
||||||
|
|
||||||
|
this.applyTheme({ recompile: true }).then(() => {
|
||||||
|
this.useStylePalette = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setStyleCustom (value) {
|
||||||
|
this.resetThemeV3()
|
||||||
|
this.resetThemeV2()
|
||||||
|
this.resetThemeV3Palette()
|
||||||
|
|
||||||
|
window.vuex.commit('setOption', { name: 'styleCustomData', value })
|
||||||
|
|
||||||
|
this.useStylePalette = true
|
||||||
|
this.applyTheme({ recompile: true }).then(() => {
|
||||||
|
this.useStylePalette = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async fetchThemesIndex () {
|
||||||
|
try {
|
||||||
|
const value = await getResourcesIndex('/static/styles.json')
|
||||||
|
window.vuex.commit('setInstanceOption', { name: 'themesIndex', value })
|
||||||
|
return value
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not fetch themes index', e)
|
||||||
|
window.vuex.commit('setInstanceOption', { name: 'themesIndex', value: { _error: e } })
|
||||||
|
return Promise.resolve({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setTheme (value) {
|
||||||
|
this.resetThemeV3()
|
||||||
|
this.resetThemeV3Palette()
|
||||||
|
this.resetThemeV2()
|
||||||
|
|
||||||
|
window.vuex.commit('setOption', { name: 'theme', value })
|
||||||
|
|
||||||
|
this.applyTheme({ recompile: true })
|
||||||
|
},
|
||||||
|
setThemeCustom (value) {
|
||||||
|
this.resetThemeV3()
|
||||||
|
this.resetThemeV3Palette()
|
||||||
|
this.resetThemeV2()
|
||||||
|
|
||||||
|
window.vuex.commit('setOption', { name: 'customTheme', value })
|
||||||
|
window.vuex.commit('setOption', { name: 'customThemeSource', value })
|
||||||
|
|
||||||
|
this.applyTheme({ recompile: true })
|
||||||
|
},
|
||||||
|
resetThemeV3 () {
|
||||||
|
window.vuex.commit('setOption', { name: 'style', value: null })
|
||||||
|
window.vuex.commit('setOption', { name: 'styleCustomData', value: null })
|
||||||
|
},
|
||||||
|
resetThemeV3Palette () {
|
||||||
|
window.vuex.commit('setOption', { name: 'palette', value: null })
|
||||||
|
window.vuex.commit('setOption', { name: 'paletteCustomData', value: null })
|
||||||
|
},
|
||||||
|
resetThemeV2 () {
|
||||||
|
window.vuex.commit('setOption', { name: 'theme', value: null })
|
||||||
|
window.vuex.commit('setOption', { name: 'customTheme', value: null })
|
||||||
|
window.vuex.commit('setOption', { name: 'customThemeSource', value: null })
|
||||||
|
},
|
||||||
|
async getThemeData () {
|
||||||
|
const getData = async (resource, index, customData, name) => {
|
||||||
|
const capitalizedResource = resource[0].toUpperCase() + resource.slice(1)
|
||||||
|
const result = {}
|
||||||
|
|
||||||
|
if (customData) {
|
||||||
|
result.nameUsed = 'custom' // custom data overrides name
|
||||||
|
result.dataUsed = customData
|
||||||
|
} else {
|
||||||
|
result.nameUsed = name
|
||||||
|
|
||||||
|
if (result.nameUsed == null) {
|
||||||
|
result.dataUsed = null
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
let fetchFunc = index[result.nameUsed]
|
||||||
|
// Fallbacks
|
||||||
|
if (!fetchFunc) {
|
||||||
|
if (resource === 'style' || resource === 'palette') {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
const newName = Object.keys(index)[0]
|
||||||
|
fetchFunc = index[newName]
|
||||||
|
console.warn(`${capitalizedResource} with id '${this.styleNameUsed}' not found, trying back to '${newName}'`)
|
||||||
|
if (!fetchFunc) {
|
||||||
|
console.warn(`${capitalizedResource} doesn't have a fallback, defaulting to stock.`)
|
||||||
|
fetchFunc = () => Promise.resolve(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.dataUsed = await fetchFunc()
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
style: instanceStyleName,
|
||||||
|
palette: instancePaletteName
|
||||||
|
} = window.vuex.state.instance
|
||||||
|
|
||||||
|
let {
|
||||||
|
theme: instanceThemeV2Name,
|
||||||
|
themesIndex,
|
||||||
|
stylesIndex,
|
||||||
|
palettesIndex
|
||||||
|
} = window.vuex.state.instance
|
||||||
|
|
||||||
|
const {
|
||||||
|
style: userStyleName,
|
||||||
|
styleCustomData: userStyleCustomData,
|
||||||
|
palette: userPaletteName,
|
||||||
|
paletteCustomData: userPaletteCustomData
|
||||||
|
} = window.vuex.state.config
|
||||||
|
|
||||||
|
let {
|
||||||
|
theme: userThemeV2Name,
|
||||||
|
customTheme: userThemeV2Snapshot,
|
||||||
|
customThemeSource: userThemeV2Source
|
||||||
|
} = window.vuex.state.config
|
||||||
|
|
||||||
|
let majorVersionUsed
|
||||||
|
|
||||||
|
console.debug(
|
||||||
|
`User V3 palette: ${userPaletteName}, style: ${userStyleName} , custom: ${!!userStyleCustomData}`
|
||||||
|
)
|
||||||
|
console.debug(
|
||||||
|
`User V2 name: ${userThemeV2Name}, source: ${!!userThemeV2Source}, snapshot: ${!!userThemeV2Snapshot}`
|
||||||
|
)
|
||||||
|
|
||||||
|
console.debug(`Instance V3 palette: ${instancePaletteName}, style: ${instanceStyleName}`)
|
||||||
|
console.debug('Instance V2 theme: ' + instanceThemeV2Name)
|
||||||
|
|
||||||
|
if (userPaletteName || userPaletteCustomData ||
|
||||||
|
userStyleName || userStyleCustomData ||
|
||||||
|
(
|
||||||
|
// User V2 overrides instance V3
|
||||||
|
(instancePaletteName ||
|
||||||
|
instanceStyleName) &&
|
||||||
|
instanceThemeV2Name == null &&
|
||||||
|
userThemeV2Name == null
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// Palette and/or style overrides V2 themes
|
||||||
|
instanceThemeV2Name = null
|
||||||
|
userThemeV2Name = null
|
||||||
|
userThemeV2Source = null
|
||||||
|
userThemeV2Snapshot = null
|
||||||
|
|
||||||
|
majorVersionUsed = 'v3'
|
||||||
|
} else if (
|
||||||
|
(userThemeV2Name ||
|
||||||
|
userThemeV2Snapshot ||
|
||||||
|
userThemeV2Source ||
|
||||||
|
instanceThemeV2Name)
|
||||||
|
) {
|
||||||
|
majorVersionUsed = 'v2'
|
||||||
|
} else {
|
||||||
|
// if all fails fallback to v3
|
||||||
|
majorVersionUsed = 'v3'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (majorVersionUsed === 'v3') {
|
||||||
|
const result = await Promise.all([
|
||||||
|
this.fetchPalettesIndex(),
|
||||||
|
this.fetchStylesIndex()
|
||||||
|
])
|
||||||
|
|
||||||
|
palettesIndex = result[0]
|
||||||
|
stylesIndex = result[1]
|
||||||
|
} else {
|
||||||
|
// Promise.all just to be uniform with v3
|
||||||
|
const result = await Promise.all([
|
||||||
|
this.fetchThemesIndex()
|
||||||
|
])
|
||||||
|
|
||||||
|
themesIndex = result[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
this.themeVersion = majorVersionUsed
|
||||||
|
|
||||||
|
console.debug('Version used', majorVersionUsed)
|
||||||
|
|
||||||
|
if (majorVersionUsed === 'v3') {
|
||||||
|
this.themeDataUsed = null
|
||||||
|
this.themeNameUsed = null
|
||||||
|
|
||||||
|
const style = await getData(
|
||||||
|
'style',
|
||||||
|
stylesIndex,
|
||||||
|
userStyleCustomData,
|
||||||
|
userStyleName || instanceStyleName
|
||||||
|
)
|
||||||
|
this.styleNameUsed = style.nameUsed
|
||||||
|
this.styleDataUsed = style.dataUsed
|
||||||
|
|
||||||
|
let firstStylePaletteName = null
|
||||||
|
style
|
||||||
|
.dataUsed
|
||||||
|
?.filter(x => x.component === '@palette')
|
||||||
|
.map(x => {
|
||||||
|
const cleanDirectives = Object.fromEntries(
|
||||||
|
Object
|
||||||
|
.entries(x.directives)
|
||||||
|
.filter(([k, v]) => k)
|
||||||
|
)
|
||||||
|
|
||||||
|
return { name: x.variant, ...cleanDirectives }
|
||||||
|
})
|
||||||
|
.forEach(palette => {
|
||||||
|
const key = 'style.' + palette.name.toLowerCase().replace(/ /g, '_')
|
||||||
|
if (!firstStylePaletteName) firstStylePaletteName = key
|
||||||
|
palettesIndex[key] = () => Promise.resolve(palette)
|
||||||
|
})
|
||||||
|
|
||||||
|
const palette = await getData(
|
||||||
|
'palette',
|
||||||
|
palettesIndex,
|
||||||
|
userPaletteCustomData,
|
||||||
|
this.useStylePalette ? firstStylePaletteName : (userPaletteName || instancePaletteName)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (this.useStylePalette) {
|
||||||
|
window.vuex.commit('setOption', { name: 'palette', value: firstStylePaletteName })
|
||||||
|
}
|
||||||
|
|
||||||
|
this.paletteNameUsed = palette.nameUsed
|
||||||
|
this.paletteDataUsed = palette.dataUsed
|
||||||
|
|
||||||
|
if (this.paletteDataUsed) {
|
||||||
|
this.paletteDataUsed.link = this.paletteDataUsed.link || this.paletteDataUsed.accent
|
||||||
|
this.paletteDataUsed.accent = this.paletteDataUsed.accent || this.paletteDataUsed.link
|
||||||
|
}
|
||||||
|
if (Array.isArray(this.paletteDataUsed)) {
|
||||||
|
const [
|
||||||
|
name,
|
||||||
|
bg,
|
||||||
|
fg,
|
||||||
|
text,
|
||||||
|
link,
|
||||||
|
cRed = '#FF0000',
|
||||||
|
cGreen = '#00FF00',
|
||||||
|
cBlue = '#0000FF',
|
||||||
|
cOrange = '#E3FF00'
|
||||||
|
] = palette.dataUsed
|
||||||
|
this.paletteDataUsed = {
|
||||||
|
name,
|
||||||
|
bg,
|
||||||
|
fg,
|
||||||
|
text,
|
||||||
|
link,
|
||||||
|
accent: link,
|
||||||
|
cRed,
|
||||||
|
cBlue,
|
||||||
|
cGreen,
|
||||||
|
cOrange
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.debug('Palette data used', palette.dataUsed)
|
||||||
|
} else {
|
||||||
|
this.styleNameUsed = null
|
||||||
|
this.styleDataUsed = null
|
||||||
|
this.paletteNameUsed = null
|
||||||
|
this.paletteDataUsed = null
|
||||||
|
|
||||||
|
const theme = await getData(
|
||||||
|
'theme',
|
||||||
|
themesIndex,
|
||||||
|
userThemeV2Source || userThemeV2Snapshot,
|
||||||
|
userThemeV2Name || instanceThemeV2Name
|
||||||
|
)
|
||||||
|
this.themeNameUsed = theme.nameUsed
|
||||||
|
this.themeDataUsed = theme.dataUsed
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async setThemeApplied () {
|
||||||
|
this.themeApplied = true
|
||||||
|
},
|
||||||
|
async applyTheme (
|
||||||
|
{ recompile = false } = {}
|
||||||
|
) {
|
||||||
|
const {
|
||||||
|
forceThemeRecompilation,
|
||||||
|
themeDebug,
|
||||||
|
theme3hacks
|
||||||
|
} = window.vuex.state.config
|
||||||
|
this.themeChangeInProgress = true
|
||||||
|
// If we're not not forced to recompile try using
|
||||||
|
// cache (tryLoadCache return true if load successful)
|
||||||
|
|
||||||
|
const forceRecompile = forceThemeRecompilation || recompile
|
||||||
|
if (!forceRecompile && !themeDebug && await tryLoadCache()) {
|
||||||
|
this.themeChangeInProgress = false
|
||||||
|
return this.setThemeApplied()
|
||||||
|
}
|
||||||
|
window.splashUpdate('splash.theme')
|
||||||
|
await this.getThemeData()
|
||||||
|
|
||||||
|
try {
|
||||||
|
const paletteIss = (() => {
|
||||||
|
if (!this.paletteDataUsed) return null
|
||||||
|
const result = {
|
||||||
|
component: 'Root',
|
||||||
|
directives: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Object
|
||||||
|
.entries(this.paletteDataUsed)
|
||||||
|
.filter(([k]) => k !== 'name')
|
||||||
|
.forEach(([k, v]) => {
|
||||||
|
let issRootDirectiveName
|
||||||
|
switch (k) {
|
||||||
|
case 'background':
|
||||||
|
issRootDirectiveName = 'bg'
|
||||||
|
break
|
||||||
|
case 'foreground':
|
||||||
|
issRootDirectiveName = 'fg'
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
issRootDirectiveName = k
|
||||||
|
}
|
||||||
|
result.directives['--' + issRootDirectiveName] = 'color | ' + v
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
})()
|
||||||
|
|
||||||
|
const theme2ruleset = this.themeDataUsed && convertTheme2To3(normalizeThemeData(this.themeDataUsed))
|
||||||
|
const hacks = []
|
||||||
|
|
||||||
|
Object.entries(theme3hacks).forEach(([key, value]) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'fonts': {
|
||||||
|
Object.entries(theme3hacks.fonts).forEach(([fontKey, font]) => {
|
||||||
|
if (!font?.family) return
|
||||||
|
switch (fontKey) {
|
||||||
|
case 'interface':
|
||||||
|
hacks.push({
|
||||||
|
component: 'Root',
|
||||||
|
directives: {
|
||||||
|
'--font': 'generic | ' + font.family
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
|
case 'input':
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const rulesetArray = [
|
||||||
|
theme2ruleset,
|
||||||
|
this.styleDataUsed,
|
||||||
|
paletteIss,
|
||||||
|
hacks
|
||||||
|
].filter(x => x)
|
||||||
|
|
||||||
|
return applyTheme(
|
||||||
|
rulesetArray.flat(),
|
||||||
|
() => this.setThemeApplied(),
|
||||||
|
() => {
|
||||||
|
this.themeChangeInProgress = false
|
||||||
|
},
|
||||||
|
themeDebug
|
||||||
|
)
|
||||||
|
} catch (e) {
|
||||||
|
window.splashError(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const normalizeThemeData = (input) => {
|
||||||
|
let themeData, themeSource
|
||||||
|
|
||||||
|
if (input.themeFileVerison === 1) {
|
||||||
|
// this might not be even used at all, some leftover of unimplemented code in V2 editor
|
||||||
|
return generatePreset(input).theme
|
||||||
|
} else if (
|
||||||
|
Object.prototype.hasOwnProperty.call(input, '_pleroma_theme_version') ||
|
||||||
|
Object.prototype.hasOwnProperty.call(input, 'source') ||
|
||||||
|
Object.prototype.hasOwnProperty.call(input, 'theme')
|
||||||
|
) {
|
||||||
|
// We got passed a full theme file
|
||||||
|
themeData = input.theme
|
||||||
|
themeSource = input.source
|
||||||
|
} else if (
|
||||||
|
Object.prototype.hasOwnProperty.call(input, 'themeEngineVersion') ||
|
||||||
|
Object.prototype.hasOwnProperty.call(input, 'colors')
|
||||||
|
) {
|
||||||
|
// We got passed a source/snapshot
|
||||||
|
themeData = input
|
||||||
|
themeSource = input
|
||||||
|
}
|
||||||
|
// New theme presets don't have 'theme' property, they use 'source'
|
||||||
|
|
||||||
|
let out // shout, shout let it all out
|
||||||
|
if (themeSource && themeSource.themeEngineVersion === CURRENT_VERSION) {
|
||||||
|
// There are some themes in wild that have completely broken source
|
||||||
|
out = { ...(themeData || {}), ...themeSource }
|
||||||
|
} else {
|
||||||
|
out = themeData
|
||||||
|
}
|
||||||
|
|
||||||
|
// generatePreset here basically creates/updates "snapshot",
|
||||||
|
// while also fixing the 2.2 -> 2.3 colors/shadows/etc
|
||||||
|
return generatePreset(out).theme
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue