From 7d19cc2d53639de166da331c28e2b2263e7f86f0 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 3 Feb 2025 00:14:44 +0200 Subject: [PATCH] cleanup and fixes --- src/boot/after_store.js | 6 +-- .../bookmark_folder_edit.js | 2 +- .../extra_notifications.js | 4 +- src/components/font_control/font_control.js | 2 +- .../post_status_form/post_status_form.js | 7 +++- .../post_status_form/post_status_form.vue | 2 +- .../quick_filter_settings.js | 7 ++-- .../quick_view_settings.js | 7 ++-- .../settings_modal/admin_tabs/emoji_tab.js | 2 +- .../admin_tabs/frontends_tab.js | 4 +- .../settings_modal_admin_content.js | 2 +- .../settings_modal/tabs/appearance_tab.js | 40 ++++++++----------- .../tabs/style_tab/style_tab.js | 10 ++--- .../tabs/theme_tab/theme_tab.js | 4 +- src/main.js | 3 -- src/modules/statuses.js | 3 +- src/stores/interface.js | 32 +++++++++++++-- 17 files changed, 80 insertions(+), 57 deletions(-) diff --git a/src/boot/after_store.js b/src/boot/after_store.js index b61fb38eb..8b2583983 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -403,9 +403,9 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => { // Little thing to get out of invalid theme state window.resetThemes = () => { - store.dispatch('resetThemeV3') - store.dispatch('resetThemeV3Palette') - store.dispatch('resetThemeV2') + useInterfaceStore().resetThemeV3() + useInterfaceStore().resetThemeV3Palette() + useInterfaceStore().resetThemeV2() } app.use(vClickOutside) diff --git a/src/components/bookmark_folder_edit/bookmark_folder_edit.js b/src/components/bookmark_folder_edit/bookmark_folder_edit.js index 95c015764..4ed440eb7 100644 --- a/src/components/bookmark_folder_edit/bookmark_folder_edit.js +++ b/src/components/bookmark_folder_edit/bookmark_folder_edit.js @@ -63,7 +63,7 @@ const BookmarkFolderEdit = { this.$router.push({ name: 'bookmark-folders' }) }) .catch((e) => { - this.$store.dispatch('pushGlobalNotice', { + this.$store.useInterfaceStore().pushGlobalNotice({ messageKey: 'bookmark_folders.error', messageArgs: [e.message], level: 'error' diff --git a/src/components/extra_notifications/extra_notifications.js b/src/components/extra_notifications/extra_notifications.js index a0371fe11..7ccd4d9ee 100644 --- a/src/components/extra_notifications/extra_notifications.js +++ b/src/components/extra_notifications/extra_notifications.js @@ -9,6 +9,8 @@ import { faBullhorn } from '@fortawesome/free-solid-svg-icons' +import { useInterfaceStore } from '../../stores/interface' + library.add( faUserPlus, faComments, @@ -42,7 +44,7 @@ const ExtraNotifications = { }, methods: { openNotificationSettings () { - return this.$store.dispatch('openSettingsModalTab', 'notifications') + return useInterfaceStore().openSettingsModalTab('notifications') }, dismissConfigurationTip () { return this.$store.dispatch('setOption', { name: 'showExtraNotificationsTip', value: false }) diff --git a/src/components/font_control/font_control.js b/src/components/font_control/font_control.js index e860a94e3..ffc866788 100644 --- a/src/components/font_control/font_control.js +++ b/src/components/font_control/font_control.js @@ -26,7 +26,7 @@ export default { 'name', 'label', 'modelValue', 'fallback', 'options', 'no-inherit' ], mounted () { - this.$store.dispatch('queryLocalFonts') + useInterfaceStore().queryLocalFonts() }, emits: ['update:modelValue'], data () { diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index c0fe31e9a..84b3cd447 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -15,7 +15,7 @@ import { pollFormToMasto } from 'src/services/poll/poll.service.js' import { reject, map, uniqBy, debounce } from 'lodash' import suggestor from '../emoji_input/suggestor.js' import { mapGetters } from 'vuex' -import { mapState } from 'pinia' +import { mapState, mapActions } from 'pinia' import Checkbox from '../checkbox/checkbox.vue' import Select from '../select/select.vue' import DraftCloser from 'src/components/draft_closer/draft_closer.vue' @@ -32,7 +32,9 @@ import { faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons' -import { useInterfaceStore } from '../../stores/interface.js' + +import { useInterfaceStore } from 'src/stores/interface.js' +import { useMediaViewerStore } from 'src/stores/media_viewer.js' library.add( faSmileBeam, @@ -395,6 +397,7 @@ const PostStatusForm = { this.removeBeforeUnloadListener() }, methods: { + ...mapActions(useMediaViewerStore, ['increment']), statusChanged () { this.autoPreview() this.updateIdempotencyKey() diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 53f236536..e5eaa3af8 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -386,7 +386,7 @@ :nsfw="false" :attachments="newStatus.files" :descriptions="newStatus.mediaDescriptions" - :set-media="() => $store.dispatch('setMedia', newStatus.files)" + :set-media="() => setMedia()" :editable="true" :edit-attachment="editAttachment" :remove-attachment="removeMediaFile" diff --git a/src/components/quick_filter_settings/quick_filter_settings.js b/src/components/quick_filter_settings/quick_filter_settings.js index 14e883360..f725d0fde 100644 --- a/src/components/quick_filter_settings/quick_filter_settings.js +++ b/src/components/quick_filter_settings/quick_filter_settings.js @@ -1,5 +1,6 @@ import Popover from '../popover/popover.vue' -import { mapGetters, mapState } from 'vuex' +import { mapGetters } from 'vuex' +import { mapState } from 'pinia' import { library } from '@fortawesome/fontawesome-svg-core' import { faFilter, faFont, faWrench } from '@fortawesome/free-solid-svg-icons' import { useInterfaceStore } from '../../stores/interface' @@ -29,8 +30,8 @@ const QuickFilterSettings = { }, computed: { ...mapGetters(['mergedConfig']), - ...mapState({ - mobileLayout: state => state.interface.layoutType === 'mobile' + ...mapState(useInterfaceStore, { + mobileLayout: state => state.layoutType === 'mobile' }), triggerAttrs () { if (this.mobileLayout) { diff --git a/src/components/quick_view_settings/quick_view_settings.js b/src/components/quick_view_settings/quick_view_settings.js index 89ed083c2..e2bd3993f 100644 --- a/src/components/quick_view_settings/quick_view_settings.js +++ b/src/components/quick_view_settings/quick_view_settings.js @@ -1,6 +1,7 @@ import Popover from 'src/components/popover/popover.vue' import QuickFilterSettings from 'src/components/quick_filter_settings/quick_filter_settings.vue' -import { mapGetters, mapState } from 'vuex' +import { mapGetters } from 'vuex' +import { mapState } from 'pinia' import { library } from '@fortawesome/fontawesome-svg-core' import { faList, faFolderTree, faBars, faWrench } from '@fortawesome/free-solid-svg-icons' import { useInterfaceStore } from '../../stores/interface' @@ -30,8 +31,8 @@ const QuickViewSettings = { }, computed: { ...mapGetters(['mergedConfig']), - ...mapState({ - mobileLayout: state => state.interface.layoutType === 'mobile' + ...mapState(useInterfaceStore, { + mobileLayout: state => state.layoutType === 'mobile' }), loggedIn () { return !!this.$store.state.users.currentUser diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.js b/src/components/settings_modal/admin_tabs/emoji_tab.js index 58e1468f8..aa3ba363d 100644 --- a/src/components/settings_modal/admin_tabs/emoji_tab.js +++ b/src/components/settings_modal/admin_tabs/emoji_tab.js @@ -232,7 +232,7 @@ const EmojiTab = { }) }, displayError (msg) { - this.$store.dispatch('pushGlobalNotice', { + this.$store.useInterfaceStore().pushGlobalNotice({ messageKey: 'admin_dash.emoji.error', messageArgs: [msg], level: 'error' diff --git a/src/components/settings_modal/admin_tabs/frontends_tab.js b/src/components/settings_modal/admin_tabs/frontends_tab.js index f57310eec..6d983104b 100644 --- a/src/components/settings_modal/admin_tabs/frontends_tab.js +++ b/src/components/settings_modal/admin_tabs/frontends_tab.js @@ -80,7 +80,7 @@ const FrontendsTab = { this.$store.dispatch('loadFrontendsStuff') if (response.error) { const reason = await response.error.json() - this.$store.dispatch('pushGlobalNotice', { + this.$store.useInterfaceStore().pushGlobalNotice({ level: 'error', messageKey: 'admin_dash.frontend.failure_installing_frontend', messageArgs: { @@ -90,7 +90,7 @@ const FrontendsTab = { timeout: 5000 }) } else { - this.$store.dispatch('pushGlobalNotice', { + this.$store.useInterfaceStore().pushGlobalNotice({ level: 'success', messageKey: 'admin_dash.frontend.success_installing_frontend', messageArgs: { diff --git a/src/components/settings_modal/settings_modal_admin_content.js b/src/components/settings_modal/settings_modal_admin_content.js index fb34eb81d..593318ec4 100644 --- a/src/components/settings_modal/settings_modal_admin_content.js +++ b/src/components/settings_modal/settings_modal_admin_content.js @@ -80,7 +80,7 @@ const SettingsModalAdminContent = { } // Clear the state of target tab, so that next time settings is opened // it doesn't force it. - this.$store.dispatch('clearSettingsModalTargetTab') + useInterfaceStore().clearSettingsModalTargetTab() } }, mounted () { diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js index 000e01ee1..7376819ed 100644 --- a/src/components/settings_modal/tabs/appearance_tab.js +++ b/src/components/settings_modal/tabs/appearance_tab.js @@ -4,11 +4,9 @@ import IntegerSetting from '../helpers/integer_setting.vue' import FloatSetting from '../helpers/float_setting.vue' import UnitSetting, { defaultHorizontalUnits } from '../helpers/unit_setting.vue' import PaletteEditor from 'src/components/palette_editor/palette_editor.vue' - +import Preview from './theme_tab/theme_preview.vue' import FontControl from 'src/components/font_control/font_control.vue' -import { useInterfaceStore, normalizeThemeData } from 'src/stores/interface' - import { newImporter } from 'src/services/export_import/export_import.js' import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js' import { init } from 'src/services/theme_data/theme_data_3.service.js' @@ -20,17 +18,15 @@ import { deserialize } from 'src/services/theme_data/iss_deserializer.js' import SharedComputedObject from '../helpers/shared_computed_object.js' import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue' + +import { mapActions } from 'pinia' +import { useInterfaceStore, normalizeThemeData } from 'src/stores/interface' + import { library } from '@fortawesome/fontawesome-svg-core' import { faGlobe } from '@fortawesome/free-solid-svg-icons' -import Preview from './theme_tab/theme_preview.vue' - -// helper for debugging -// eslint-disable-next-line no-unused-vars -const toValue = (x) => JSON.parse(JSON.stringify(x === undefined ? 'null' : x)) - library.add( faGlobe ) @@ -90,7 +86,7 @@ const AppearanceTab = { PaletteEditor }, mounted () { - this.$store.dispatch('getThemeData') + useInterfaceStore().getThemeData() const updateIndex = (resource) => { const capitalizedResource = resource[0].toUpperCase() + resource.slice(1) @@ -100,7 +96,7 @@ const AppearanceTab = { if (currentIndex) { promise = Promise.resolve(currentIndex) } else { - promise = this.$store.dispatch(`fetch${capitalizedResource}sIndex`) + promise = useInterfaceStore()[`fetch${capitalizedResource}sIndex`]() } return promise.then(index => { @@ -311,14 +307,14 @@ const AppearanceTab = { }, onImport (parsed, filename) { if (filename.endsWith('.json')) { - this.$store.dispatch('setThemeCustom', parsed.source || parsed.theme) + useInterfaceStore().setThemeCustom(parsed.source || parsed.theme) } else if (filename.endsWith('.iss')) { - this.$store.dispatch('setStyleCustom', parsed) + useInterfaceStore().setStyleCustom(parsed) } }, onImportFailure (result) { console.error('Failure importing theme:', result) - this.$store.dispatch('pushGlobalNotice', { messageKey: 'settings.invalid_theme_imported', level: 'error' }) + this.$store.useInterfaceStore().pushGlobalNotice({ messageKey: 'settings.invalid_theme_imported', level: 'error' }) }, importValidator (parsed, filename) { if (filename.endsWith('.json')) { @@ -340,22 +336,20 @@ const AppearanceTab = { isPaletteActive (key) { return key === (this.mergedConfig.palette || this.$store.state.instance.palette) }, - setStyle (name) { - this.$store.dispatch('setStyle', name) - }, - setTheme (name) { - this.$store.dispatch('setTheme', name) - }, + ...mapActions(useInterfaceStore, [ + 'setStyle', + 'setTheme' + ]), setPalette (name, data) { - this.$store.dispatch('setPalette', name) + useInterfaceStore().setPalette(name) this.userPalette = data }, setPaletteCustom (data) { - this.$store.dispatch('setPaletteCustom', data) + useInterfaceStore().setPaletteCustom(data) this.userPalette = data }, resetTheming (name) { - this.$store.dispatch('setStyle', 'stock') + useInterfaceStore().setStyle('stock') }, previewTheme (key, version, input) { let theme3 diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.js b/src/components/settings_modal/tabs/style_tab/style_tab.js index 31541da60..131da30f2 100644 --- a/src/components/settings_modal/tabs/style_tab/style_tab.js +++ b/src/components/settings_modal/tabs/style_tab/style_tab.js @@ -1,5 +1,4 @@ import { ref, reactive, computed, watch, watchEffect, provide, getCurrentInstance } from 'vue' -import { useStore } from 'vuex' import { useInterfaceStore } from 'src/stores/interface' import { get, set, unset, throttle } from 'lodash' @@ -81,14 +80,13 @@ export default { }, setup (props, context) { const exports = {} - const store = useStore() const interfaceStore = useInterfaceStore() // All rules that are made by editor const allEditedRules = ref(interfaceStore.styleDataUsed || {}) const styleDataUsed = computed(() => interfaceStore.styleDataUsed) watch([styleDataUsed], (value) => { - onImport(store.state.interface.styleDataUsed) + onImport(interfaceStore.styleDataUsed) }, { once: true }) exports.isActive = computed(() => { @@ -642,7 +640,7 @@ export default { parser (string) { return deserialize(string) }, onImportFailure (result) { console.error('Failure importing style:', result) - this.$store.dispatch('pushGlobalNotice', { messageKey: 'settings.invalid_theme_imported', level: 'error' }) + this.$store.useInterfaceStore().pushGlobalNotice({ messageKey: 'settings.invalid_theme_imported', level: 'error' }) }, onImport }) @@ -666,7 +664,7 @@ export default { }) exports.clearStyle = () => { - onImport(store.state.interface.styleDataUsed) + onImport(interfaceStore().styleDataUsed) } exports.exportStyle = () => { @@ -678,7 +676,7 @@ export default { } exports.applyStyle = () => { - store.dispatch('setStyleCustom', exportRules.value) + useInterfaceStore().setStyleCustom(exportRules.value) } const overallPreviewRules = ref([]) diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index 0666f86d5..588cebd3c 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -127,7 +127,7 @@ export default { if (currentIndex) { promise = Promise.resolve(currentIndex) } else { - promise = this.$store.dispatch('fetchThemesIndex') + promise = useInterfaceStore().fetchThemesIndex() } promise.then(themesIndex => { @@ -493,7 +493,7 @@ export default { } }, setCustomTheme () { - this.$store.dispatch('setThemeV2', { + useInterfaceStore().setThemeV2({ customTheme: { ignore: true, themeFileVersion: this.selectedVersion, diff --git a/src/main.js b/src/main.js index 68ca0ed0a..5aa9c1828 100644 --- a/src/main.js +++ b/src/main.js @@ -117,9 +117,6 @@ const persistedStateOptions = { // strict: process.env.NODE_ENV !== 'production' }) window.vuex = store - if (storageError) { - 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 }) } catch (e) { diff --git a/src/modules/statuses.js b/src/modules/statuses.js index 50507fa28..f05f93abe 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -13,6 +13,7 @@ import { omitBy } from 'lodash' import apiService from '../services/api/api.service.js' +import { useInterfaceStore } from 'src/stores/interface' const emptyTl = (userId = 0) => ({ statuses: [], @@ -510,7 +511,7 @@ const statuses = { commit('setDeleted', { status }) }) .catch((e) => { - dispatch('pushGlobalNotice', { + useInterfaceStore().pushGlobalNotice({ level: 'error', messageKey: 'status.delete_error', messageArgs: [e.message], diff --git a/src/stores/interface.js b/src/stores/interface.js index cf14b7acd..8656a756a 100644 --- a/src/stores/interface.js +++ b/src/stores/interface.js @@ -35,7 +35,8 @@ export const useInterfaceStore = defineStore('interface', { cssFilter: window.CSS && window.CSS.supports && ( window.CSS.supports('filter', 'drop-shadow(0 0)') || window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)') - ) + ), + localFonts: typeof window.queryLocalFonts === 'function' }, layoutType: 'normal', globalNotices: [], @@ -95,9 +96,9 @@ export const useInterfaceStore = defineStore('interface', { clearSettingsModalTargetTab () { this.settingsModalTargetTab = null }, - openSettingsModalTab (value) { + openSettingsModalTab (value, mode = 'user') { this.settingsModalTargetTab = value - this.openSettingsModal() + this.openSettingsModal(mode) }, removeGlobalNotice (notice) { this.globalNotices = this.globalNotices.filter(n => n !== notice) @@ -147,6 +148,31 @@ export const useInterfaceStore = defineStore('interface', { this.layoutType = wideLayout ? 'wide' : normalOrMobile } }, + setFontsList (value) { + this.localFonts = [...(new Set(value.map(font => font.family))).values()] + }, + queryLocalFonts () { + if (this.localFonts !== null) return + this.setFontsList([]) + + if (!this.browserSupport.localFonts) { + return + } + window + .queryLocalFonts() + .then((fonts) => { + this.setFontsList(fonts) + }) + .catch((e) => { + this.pushGlobalNotice({ + messageKey: 'settings.style.themes3.font.font_list_unavailable', + messageArgs: { + error: e + }, + level: 'error' + }) + }) + }, setLastTimeline (value) { this.lastTimeline = value },