pass 2 + emoji store separation

This commit is contained in:
Henry Jameson 2026-01-29 01:45:31 +02:00
commit 4156b1597a
12 changed files with 372 additions and 119 deletions

View file

@ -22,7 +22,8 @@ import {
import { useAnnouncementsStore } from 'src/stores/announcements'
import { useAuthFlowStore } from 'src/stores/auth_flow'
import { useI18nStore } from 'src/stores/i18n'
import { useInterfaceStore } from 'src/stores/interface'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useOAuthStore } from 'src/stores/oauth'
import App from '../App.vue'
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
@ -78,29 +79,29 @@ const getInstanceConfig = async ({ store }) => {
const textlimit = data.max_toot_chars
const vapidPublicKey = data.pleroma.vapid_public_key
store.dispatch('setInstanceOption', {
name: 'pleromaExtensionsAvailable',
useInstanceStore().set({
name: 'featureSet.pleromaExtensionsAvailable',
value: data.pleroma,
})
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'textlimit',
value: textlimit,
})
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'accountApprovalRequired',
value: data.approval_required,
})
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'birthdayRequired',
value: !!data.pleroma?.metadata.birthday_required,
})
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'birthdayMinAge',
value: data.pleroma?.metadata.birthday_min_age || 0,
})
if (vapidPublicKey) {
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'vapidPublicKey',
value: vapidPublicKey,
})
@ -161,14 +162,14 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
config = Object.assign({}, staticConfig, apiConfig)
}
const copyInstanceOption = (name) => {
const copyInstanceOption = (path) => {
if (typeof config[name] !== 'undefined') {
store.dispatch('setInstanceOption', { name, value: config[name] })
useInstanceStore().set({ path, value: config[name] })
}
}
Object.keys(staticOrApiConfigDefault).forEach(copyInstanceOption)
Object.keys(instanceDefaultConfig).forEach(copyInstanceOption)
Object.keys(staticOrApiConfigDefault).map(k => `instanceIdentity.${k}`).forEach(copyInstanceOption)
Object.keys(instanceDefaultConfig).map(k => `prefsStorage.${k}`).forEach(copyInstanceOption)
useAuthFlowStore().setInitialStrategy(config.loginMethod)
}
@ -178,7 +179,7 @@ const getTOS = async ({ store }) => {
const res = await window.fetch('/static/terms-of-service.html')
if (res.ok) {
const html = await res.text()
store.dispatch('setInstanceOption', { name: 'tos', value: html })
useInstanceStore().set({ name: 'tos', value: html })
} else {
throw res
}
@ -192,7 +193,7 @@ const getInstancePanel = async ({ store }) => {
const res = await preloadFetch('/instance/panel.html')
if (res.ok) {
const html = await res.text()
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'instanceSpecificPanelContent',
value: html,
})
@ -227,7 +228,7 @@ const getStickers = async ({ store }) => {
).sort((a, b) => {
return a.meta.title.localeCompare(b.meta.title)
})
store.dispatch('setInstanceOption', { name: 'stickers', value: stickers })
useInstanceStore().set({ name: 'stickers', value: stickers })
} else {
throw res
}
@ -248,7 +249,7 @@ const getAppSecret = async ({ store }) => {
const resolveStaffAccounts = ({ store, accounts }) => {
const nicknames = accounts.map((uri) => uri.split('/').pop())
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'staffAccounts',
value: nicknames,
})
@ -262,159 +263,163 @@ const getNodeInfo = async ({ store }) => {
const data = await res.json()
const metadata = data.metadata
const features = metadata.features
store.dispatch('setInstanceOption', {
name: 'name',
useInstanceStore().set({
path: 'name',
value: metadata.nodeName,
})
store.dispatch('setInstanceOption', {
name: 'registrationOpen',
useInstanceStore().set({
path: 'registrationOpen',
value: data.openRegistrations,
})
store.dispatch('setInstanceOption', {
name: 'mediaProxyAvailable',
useInstanceStore().set({
path: 'featureSet.mediaProxyAvailable',
value: features.includes('media_proxy'),
})
store.dispatch('setInstanceOption', {
name: 'safeDM',
useInstanceStore().set({
path: 'featureSet.safeDM',
value: features.includes('safe_dm_mentions'),
})
store.dispatch('setInstanceOption', {
name: 'shoutAvailable',
useInstanceStore().set({
path: 'featureSet.shoutAvailable',
value: features.includes('chat'),
})
store.dispatch('setInstanceOption', {
name: 'pleromaChatMessagesAvailable',
useInstanceStore().set({
path: 'featureSet.pleromaChatMessagesAvailable',
value: features.includes('pleroma_chat_messages'),
})
store.dispatch('setInstanceOption', {
name: 'pleromaCustomEmojiReactionsAvailable',
useInstanceStore().set({
path: 'featureSet.pleromaCustomEmojiReactionsAvailable',
value:
features.includes('pleroma_custom_emoji_reactions') ||
features.includes('custom_emoji_reactions'),
})
store.dispatch('setInstanceOption', {
name: 'pleromaBookmarkFoldersAvailable',
useInstanceStore().set({
path: 'featureSet.pleromaBookmarkFoldersAvailable',
value: features.includes('pleroma:bookmark_folders'),
})
store.dispatch('setInstanceOption', {
name: 'gopherAvailable',
useInstanceStore().set({
path: 'featureSet.gopherAvailable',
value: features.includes('gopher'),
})
store.dispatch('setInstanceOption', {
name: 'pollsAvailable',
useInstanceStore().set({
path: 'featureSet.pollsAvailable',
value: features.includes('polls'),
})
store.dispatch('setInstanceOption', {
name: 'editingAvailable',
useInstanceStore().set({
path: 'featureSet.editingAvailable',
value: features.includes('editing'),
})
store.dispatch('setInstanceOption', {
name: 'pollLimits',
value: metadata.pollLimits,
})
store.dispatch('setInstanceOption', {
name: 'mailerEnabled',
useInstanceStore().set({
path: 'featureSet.mailerEnabled',
value: metadata.mailerEnabled,
})
store.dispatch('setInstanceOption', {
name: 'quotingAvailable',
useInstanceStore().set({
path: 'featureSet.quotingAvailable',
value: features.includes('quote_posting'),
})
store.dispatch('setInstanceOption', {
name: 'groupActorAvailable',
useInstanceStore().set({
path: 'featureSet.groupActorAvailable',
value: features.includes('pleroma:group_actors'),
})
store.dispatch('setInstanceOption', {
name: 'blockExpiration',
useInstanceStore().set({
path: 'featureSet.blockExpiration',
value: features.includes('pleroma:block_expiration'),
})
store.dispatch('setInstanceOption', {
name: 'localBubbleInstances',
useInstanceStore().set({
path: 'localBubbleInstances',
value: metadata.localBubbleInstances ?? [],
})
useInstanceStore().set({
path: 'featureSet.localBubble',
value: (metadata.localBubbleInstances ?? []).length > 0,
})
useInstanceStore().set({
path: 'limits.pollLimits',
value: metadata.pollLimits,
})
const uploadLimits = metadata.uploadLimits
store.dispatch('setInstanceOption', {
name: 'uploadlimit',
useInstanceStore().set({
name: 'limits.uploadlimit',
value: parseInt(uploadLimits.general),
})
store.dispatch('setInstanceOption', {
name: 'avatarlimit',
useInstanceStore().set({
name: 'limits.avatarlimit',
value: parseInt(uploadLimits.avatar),
})
store.dispatch('setInstanceOption', {
name: 'backgroundlimit',
useInstanceStore().set({
name: 'limits.backgroundlimit',
value: parseInt(uploadLimits.background),
})
store.dispatch('setInstanceOption', {
name: 'bannerlimit',
useInstanceStore().set({
name: 'limits.bannerlimit',
value: parseInt(uploadLimits.banner),
})
store.dispatch('setInstanceOption', {
name: 'fieldsLimits',
useInstanceStore().set({
name: 'limits.fieldsLimits',
value: metadata.fieldsLimits,
})
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'restrictedNicknames',
value: metadata.restrictedNicknames,
})
store.dispatch('setInstanceOption', {
name: 'postFormats',
useInstanceStore().set({
name: 'featureSet.postFormats',
value: metadata.postFormats,
})
const suggestions = metadata.suggestions
store.dispatch('setInstanceOption', {
name: 'suggestionsEnabled',
useInstanceStore().set({
name: 'featureSet.suggestionsEnabled',
value: suggestions.enabled,
})
store.dispatch('setInstanceOption', {
name: 'suggestionsWeb',
useInstanceStore().set({
name: 'featureSet.suggestionsWeb',
value: suggestions.web,
})
const software = data.software
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'backendVersion',
value: software.version,
})
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'backendRepository',
value: software.repository,
})
const priv = metadata.private
store.dispatch('setInstanceOption', { name: 'private', value: priv })
useInstanceStore().set({ name: 'private', value: priv })
const frontendVersion = window.___pleromafe_commit_hash
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'frontendVersion',
value: frontendVersion,
})
const federation = metadata.federation
store.dispatch('setInstanceOption', {
name: 'tagPolicyAvailable',
useInstanceStore().set({
name: 'featureSet.tagPolicyAvailable',
value:
typeof federation.mrf_policies === 'undefined'
? false
: metadata.federation.mrf_policies.includes('TagPolicy'),
})
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'federationPolicy',
value: federation,
})
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'federating',
value:
typeof federation.enabled === 'undefined' ? true : federation.enabled,
})
const accountActivationRequired = metadata.accountActivationRequired
store.dispatch('setInstanceOption', {
useInstanceStore().set({
name: 'accountActivationRequired',
value: accountActivationRequired,
})
@ -526,7 +531,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
typeof overrides.target !== 'undefined'
? overrides.target
: window.location.origin
store.dispatch('setInstanceOption', { name: 'server', value: server })
useInstanceStore().set({ name: 'server', value: server })
await setConfig({ store })
try {

View file

@ -131,7 +131,7 @@ const EmojiInput = {
},
computed: {
padEmoji() {
return this.$store.getters.mergedConfig.padEmoji
return useEmojiStore().mergedConfig.padEmoji
},
defaultCandidateIndex() {
return this.$store.getters.mergedConfig.autocompleteSelect ? 0 : -1

View file

@ -2,7 +2,7 @@
* suggest - generates a suggestor function to be used by emoji-input
* data: object providing source information for specific types of suggestions:
* data.emoji - optional, an array of all emoji available i.e.
* (getters.standardEmojiList + state.instance.customEmoji)
* (useEmojiStore().standardEmojiList + state.instance.customEmoji)
* data.users - optional, an array of all known users
* updateUsersList - optional, a function to search and append to users
*

View file

@ -3,6 +3,7 @@ import { defineAsyncComponent } from 'vue'
import Popover from 'src/components/popover/popover.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useEmojiStore } from 'src/stores/emoji.js'
import { ensureFinalFallback } from '../../i18n/languages.js'
import Checkbox from '../checkbox/checkbox.vue'
import StillImage from '../still-image/still-image.vue'
@ -359,7 +360,7 @@ const EmojiPicker = {
if (this.hideCustomEmoji || this.hideCustomEmojiInPicker) {
return {}
}
const emojis = this.$store.getters.groupedCustomEmojis
const emojis = useEmojiStore().groupedCustomEmojis
if (emojis.unpacked) {
emojis.unpacked.text = this.$t('emoji.unpacked')
}
@ -369,7 +370,7 @@ const EmojiPicker = {
return Object.keys(this.allCustomGroups)[0]
},
unicodeEmojiGroups() {
return this.$store.getters.standardEmojiGroupList.map((group) => ({
return useEmojiStore().standardEmojiGroupList.map((group) => ({
id: `standard-${group.id}`,
text: this.$t(`emoji.unicode_groups.${group.id}`),
icon: UNICODE_EMOJI_GROUP_ICON[group.id],

View file

@ -7,6 +7,7 @@ import Gallery from 'src/components/gallery/gallery.vue'
import Popover from 'src/components/popover/popover.vue'
import { pollFormToMasto } from 'src/services/poll/poll.service.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useEmojiStore } from 'src/stores/emoji.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useMediaViewerStore } from 'src/stores/media_viewer.js'
import { propsToNative } from '../../services/attributes_helper/attributes_helper.service.js'
@ -259,8 +260,8 @@ const PostStatusForm = {
emojiUserSuggestor() {
return suggestor({
emoji: [
...this.$store.getters.standardEmojiList,
...useInstanceStore().customEmoji,
...useEmojiStore().standardEmojiList,
...useEmojiStore().customEmoji,
],
store: this.$store,
})
@ -268,16 +269,16 @@ const PostStatusForm = {
emojiSuggestor() {
return suggestor({
emoji: [
...this.$store.getters.standardEmojiList,
...useInstanceStore().customEmoji,
...useEmojiStore().standardEmojiList,
...useEmojiStore().customEmoji,
],
})
},
emoji() {
return this.$store.getters.standardEmojiList || []
return useEmojiStore().standardEmojiList || []
},
customEmoji() {
return useInstanceStore().customEmoji || []
return useEmojiStore().customEmoji || []
},
statusLength() {
return this.newStatus.status.length

View file

@ -3,6 +3,8 @@ import { set } from 'lodash'
import { useI18nStore } from 'src/stores/i18n.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useEmojiStore } from 'src/stores/emoji.js'
import messages from '../i18n/messages'
import localeService from '../services/locale/locale.service.js'
import { applyConfig } from '../services/style_setter/style_setter.js'
@ -43,24 +45,23 @@ export const instanceDefaultProperties = Object.keys(instanceDefaultConfig)
const config = {
state: { ...defaultState },
getters: {
defaultConfig(state, getters, rootState) {
const { instance } = rootState
defaultConfig() {
return {
...defaultState,
...Object.fromEntries(
instanceDefaultProperties.map((key) => [key, instance[key]]),
instanceDefaultProperties.map((key) => [key, useInstanceStore()[key]]),
),
}
},
mergedConfig(state, getters, rootState, rootGetters) {
const { defaultConfig } = rootGetters
return {
...defaultConfig,
// Do not override with undefined
...Object.fromEntries(
Object.entries(state).filter(([, v]) => v !== undefined),
),
}
mergedConfig(state) {
const instancePrefs = useInstanceStore().prefsStorage
const result = Object.fromEntries(
Object.entries(defaultState).map(([k, v]) => [
k,
v ?? instancePrefs[k],
]),
)
return result
},
},
mutations: {
@ -177,7 +178,7 @@ const config = {
}
case 'interfaceLanguage':
messages.setLanguage(useI18nStore().i18n, value)
dispatch('loadUnicodeEmojiData', value)
useEmojiStore().loadUnicodeEmojiData(value)
Cookies.set(
BACKEND_LANGUAGE_COOKIE_NAME,
localeService.internalToBackendLocaleMulti(value),

View file

@ -18,7 +18,7 @@ export const staticOrApiConfigDefault = {
redirectRootLogin: '/main/friends',
redirectRootNoLogin: '/main/all',
hideSitename: false,
nsfwCensorImage: undefined,
nsfwCensorImage: null,
showFeaturesPanel: true,
showInstanceSpecificPanel: false,
}

View file

@ -3,14 +3,12 @@ import api from './api.js'
import chats from './chats.js'
import config from './config.js'
import drafts from './drafts.js'
import instance from './instance.js'
import notifications from './notifications.js'
import profileConfig from './profileConfig.js'
import statuses from './statuses.js'
import users from './users.js'
export default {
instance,
statuses,
notifications,
users,

View file

@ -12,6 +12,7 @@ import {
import { declarations } from 'src/modules/config_declaration'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useEmojiStore } from 'src/stores/emoji.js'
import { useOAuthStore } from 'src/stores/oauth.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import apiService from '../services/api/api.service.js'
@ -702,7 +703,7 @@ const users = {
useServerSideStorageStore().setServerSideStorage(user)
commit('addNewUsers', [user])
dispatch('fetchEmoji')
useEmojiStore().fetchEmoji()
getNotificationPermission().then((permission) =>
useInterfaceStore().setNotificationPermission(permission),

246
src/stores/emoji.js Normal file
View file

@ -0,0 +1,246 @@
import { defineStore } from 'pinia'
import { useInstanceStore } from 'src/stores/instance.js'
import { ensureFinalFallback } from 'src/i18n/languages.js'
import { annotationsLoader } from 'virtual:pleroma-fe/emoji-annotations'
const defaultState = {
// Custom emoji from server
customEmoji: [],
customEmojiFetched: false,
// Unicode emoji from bundle
emoji: {},
emojiFetched: false,
unicodeEmojiAnnotations: {},
}
const SORTED_EMOJI_GROUP_IDS = [
'smileys-and-emotion',
'people-and-body',
'animals-and-nature',
'food-and-drink',
'travel-and-places',
'activities',
'objects',
'symbols',
'flags',
]
const REGIONAL_INDICATORS = (() => {
const start = 0x1f1e6
const end = 0x1f1ff
const A = 'A'.codePointAt(0)
const res = new Array(end - start + 1)
for (let i = start; i <= end; ++i) {
const letter = String.fromCodePoint(A + i - start)
res[i - start] = {
replacement: String.fromCodePoint(i),
imageUrl: false,
displayText: 'regional_indicator_' + letter,
displayTextI18n: {
key: 'emoji.regional_indicator',
args: { letter },
},
}
}
return res
})()
const loadAnnotations = (lang) => {
return annotationsLoader[lang]().then((k) => k.default)
}
const injectAnnotations = (emoji, annotations) => {
const availableLangs = Object.keys(annotations)
return {
...emoji,
annotations: availableLangs.reduce((acc, cur) => {
acc[cur] = annotations[cur][emoji.replacement]
return acc
}, {}),
}
}
const injectRegionalIndicators = (groups) => {
groups.symbols.push(...REGIONAL_INDICATORS)
return groups
}
export const useEmojiStore = defineStore('emoji', {
state: () => ({ ...defaultState }),
getters: {
groupedCustomEmojis(state) {
const packsOf = (emoji) => {
const packs = emoji.tags
.filter((k) => k.startsWith('pack:'))
.map((k) => {
const packName = k.slice(5) // remove 'pack:' prefix
return {
id: `custom-${packName}`,
text: packName,
}
})
if (!packs.length) {
return [
{
id: 'unpacked',
},
]
} else {
return packs
}
}
return this.customEmoji.reduce((res, emoji) => {
packsOf(emoji).forEach(({ id: packId, text: packName }) => {
if (!res[packId]) {
res[packId] = {
id: packId,
text: packName,
image: emoji.imageUrl,
emojis: [],
}
}
res[packId].emojis.push(emoji)
})
return res
}, {})
},
standardEmojiList(state) {
return SORTED_EMOJI_GROUP_IDS.map((groupId) =>
(this.emoji[groupId] || []).map((k) =>
injectAnnotations(k, this.unicodeEmojiAnnotations),
),
).reduce((a, b) => a.concat(b), [])
},
standardEmojiGroupList(state) {
return SORTED_EMOJI_GROUP_IDS.map((groupId) => ({
id: groupId,
emojis: (this.emoji[groupId] || []).map((k) =>
injectAnnotations(k, this.unicodeEmojiAnnotations),
),
}))
},
},
actions: {
async getStaticEmoji() {
try {
// See build/emojis_plugin for more details
const values = (await import('/src/assets/emoji.json')).default
const emoji = Object.keys(values).reduce((res, groupId) => {
res[groupId] = values[groupId].map((e) => ({
displayText: e.slug,
imageUrl: false,
replacement: e.emoji,
}))
return res
}, {})
this.emoji = injectRegionalIndicators(emoji)
} catch (e) {
console.warn("Can't load static emoji\n", e)
}
},
loadUnicodeEmojiData(language) {
const langList = ensureFinalFallback(language)
return Promise.all(
langList.map(async (lang) => {
if (!this.unicodeEmojiAnnotations[lang]) {
try {
const annotations = await loadAnnotations(lang)
this.unicodeEmojiAnnotations[lang] = annotations
} catch (e) {
console.warn(
`Error loading unicode emoji annotations for ${lang}: `,
e,
)
// ignore
}
}
}),
)
},
async getCustomEmoji() {
try {
let res = await window.fetch('/api/v1/pleroma/emoji')
if (!res.ok) {
res = await window.fetch('/api/pleroma/emoji.json')
}
if (res.ok) {
const result = await res.json()
const values = Array.isArray(result)
? Object.assign({}, ...result)
: result
const caseInsensitiveStrCmp = (a, b) => {
const la = a.toLowerCase()
const lb = b.toLowerCase()
return la > lb ? 1 : la < lb ? -1 : 0
}
const noPackLast = (a, b) => {
const aNull = a === ''
const bNull = b === ''
if (aNull === bNull) {
return 0
} else if (aNull && !bNull) {
return 1
} else {
return -1
}
}
const byPackThenByName = (a, b) => {
const packOf = (emoji) =>
(emoji.tags.filter((k) => k.startsWith('pack:'))[0] || '').slice(
5,
)
const packOfA = packOf(a)
const packOfB = packOf(b)
return (
noPackLast(packOfA, packOfB) ||
caseInsensitiveStrCmp(packOfA, packOfB) ||
caseInsensitiveStrCmp(a.displayText, b.displayText)
)
}
const emoji = Object.entries(values)
.map(([key, value]) => {
const imageUrl = value.image_url
return {
displayText: key,
imageUrl: imageUrl
? useInstanceStore().server + imageUrl
: value,
tags: imageUrl
? value.tags.sort((a, b) => (a > b ? 1 : 0))
: ['utf'],
replacement: `:${key}: `,
}
// Technically could use tags but those are kinda useless right now,
// should have been "pack" field, that would be more useful
})
.sort(byPackThenByName)
this.customEmoji = emoji
} else {
throw res
}
} catch (e) {
console.warn("Can't load custom emojis\n", e)
}
},
fetchEmoji() {
if (!this.customEmojiFetched) {
this.getCustomEmoji().then(() => (this.customEmojiFetched = true))
}
if (!this.emojiFetched) {
this.getStaticEmoji().then(() => (this.emojiFetched = true))
}
},
},
})

View file

@ -129,10 +129,10 @@ export const useInstanceStore = defineStore('instance', {
},
},
actions: {
set({ path, value }) {
if (get(defaultState, path) === undefined)
console.error(`Unknown instance option ${path}, value: ${value}`)
set(this, path, value)
set({ path, name, value }) {
if (get(defaultState, path ?? name) === undefined)
console.error(`Unknown instance option ${path ?? name}, value: ${value}`)
set(this, path ?? name, value)
switch (name) {
case 'name':
useInterfaceStore().setPageTitle()

View file

@ -87,7 +87,7 @@ export const useInterfaceStore = defineStore('interface', {
},
setPageTitle(option = '') {
try {
document.title = `${option} ${window.vuex.useInstanceStore().name}`
document.title = `${option} ${useInstanceStore().name}`
} catch (error) {
console.error(`${error}`)
}
@ -222,14 +222,14 @@ export const useInterfaceStore = defineStore('interface', {
async fetchPalettesIndex() {
try {
const value = await getResourcesIndex('/static/palettes/index.json')
window.vuex.commit('setInstanceOption', {
useInstanceStore().set({
name: 'palettesIndex',
value,
})
return value
} catch (e) {
console.error('Could not fetch palettes index', e)
window.vuex.commit('setInstanceOption', {
useInstanceStore().set({
name: 'palettesIndex',
value: { _error: e },
})
@ -258,11 +258,11 @@ export const useInterfaceStore = defineStore('interface', {
'/static/styles/index.json',
deserialize,
)
window.vuex.commit('setInstanceOption', { name: 'stylesIndex', value })
useInstanceStore().set({ name: 'stylesIndex', value })
return value
} catch (e) {
console.error('Could not fetch styles index', e)
window.vuex.commit('setInstanceOption', {
useInstanceStore().set({
name: 'stylesIndex',
value: { _error: e },
})
@ -296,11 +296,11 @@ export const useInterfaceStore = defineStore('interface', {
async fetchThemesIndex() {
try {
const value = await getResourcesIndex('/static/styles.json')
window.vuex.commit('setInstanceOption', { name: 'themesIndex', value })
useInstanceStore().set({ name: 'themesIndex', value })
return value
} catch (e) {
console.error('Could not fetch themes index', e)
window.vuex.commit('setInstanceOption', {
useInstanceStore().set({
name: 'themesIndex',
value: { _error: e },
})
@ -386,14 +386,14 @@ export const useInterfaceStore = defineStore('interface', {
}
const { style: instanceStyleName, palette: instancePaletteName } =
window.vuex.useInstanceStore()
useInstanceStore()
let {
theme: instanceThemeV2Name,
themesIndex,
stylesIndex,
palettesIndex,
} = window.vuex.useInstanceStore()
} = useInstanceStore()
const {
style: userStyleName,