diff --git a/src/lib/language.js b/src/lib/language.js new file mode 100644 index 000000000..f8904dd07 --- /dev/null +++ b/src/lib/language.js @@ -0,0 +1,14 @@ +import { useI18nStore } from 'src/stores/i18n.js' + +export const piniaLanguagePlugin = ({ store, options }) => { + if (store.$id === 'sync_config') { + store.$onAction(({ name, args }) => { + if (name === 'setPreference') { + const { path, value } = args[0] + if (path === 'simple.interfaceLanguage') { + useI18nStore().setLanguage(value) + } + } + }) + } +} diff --git a/src/lib/push_notifications_plugin.js b/src/lib/push_notifications_plugin.js index 9732a82c9..7d44625c2 100644 --- a/src/lib/push_notifications_plugin.js +++ b/src/lib/push_notifications_plugin.js @@ -1,37 +1,92 @@ import { useInstanceStore } from 'src/stores/instance.js' import { useInterfaceStore } from 'src/stores/interface.js' +import { useSyncConfigStore } from 'src/stores/sync_config.js' -export default (store) => { +export const piniaPushNotificationsPlugin = ({ store }) => { + if ( + store.$id !== 'sync_config' && + store.$id !== 'instance' && + store.$id !== 'interface' + ) + return + + store.$onAction(({ name: actionName, args }) => { + if ( + store.$id === 'interface' && + actionName !== 'setNotificationPermission' && + actionName !== 'setLoginStatus' + ) + return + + // Initial state + let vapidPublicKey = useInstanceStore().vapidPublicKey + let enabled = useSyncConfigStore().mergedConfig.webPushNotifications + let permissionGranted = + useInterfaceStore().notificationPermission === 'granted' + let permissionPresent = + useInterfaceStore().notificationPermission !== undefined + let user = !!window.vuex.state.users.currentUser + + if (store.$id === 'instance') { + if (actionName === 'set' && args[0].path === 'vapidPublicKey') { + const { value } = args[0] + vapidPublicKey = value + } + } + + if (!vapidPublicKey || !permissionPresent) { + return + } + + if (store.$id === 'interface') { + if (actionName === 'setNotificationPermission') { + permissionGranted = args[0] === 'granted' + } else if (actionName === 'setLoginStatus') { + user = args[0] + } else { + return + } + } else if (store.$id === 'sync_config') { + if ( + actionName === 'setPreference' && + args[0].path === 'simple.webPushNotifications' + ) { + const { value } = args[0] + enabled = value + } else { + return + } + } + + if (permissionGranted && enabled && user) { + return window.vuex.dispatch('registerPushNotifications') + } else { + return window.vuex.dispatch('unregisterPushNotifications') + } + }) +} + +export const vuexPushNotificationsPlugin = (store) => { store.subscribe((mutation, state) => { + // Initial state const vapidPublicKey = useInstanceStore().vapidPublicKey - const webPushNotification = state.config.webPushNotifications - const permission = useInterfaceStore().notificationPermission === 'granted' + const enabled = useSyncConfigStore().mergedConfig.webPushNotifications + const permissionGranted = + useInterfaceStore().notificationPermission === 'granted' + const permissionPresent = + useInterfaceStore().notificationPermission !== undefined const user = state.users.currentUser - const isUserMutation = mutation.type === 'setCurrentUser' - const isVapidMutation = - mutation.type === 'setInstanceOption' && - mutation.payload.name === 'vapidPublicKey' - const isPermMutation = - mutation.type === 'setNotificationPermission' && - mutation.payload === 'granted' - const isUserConfigMutation = - mutation.type === 'setOption' && - mutation.payload.name === 'webPushNotifications' - const isVisibilityMutation = - mutation.type === 'setOption' && - mutation.payload.name === 'notificationVisibility' + if (!permissionPresent || !vapidPublicKey) return if ( - isUserMutation || - isVapidMutation || - isPermMutation || - isUserConfigMutation || - isVisibilityMutation + mutation.type === 'setCurrentUser' || + mutation.type === 'clearCurrentUser' ) { - if (user && vapidPublicKey && permission && webPushNotification) { + console.log(!!user, permissionGranted, enabled) + if (user && permissionGranted && enabled) { return store.dispatch('registerPushNotifications') - } else if (isUserConfigMutation && !webPushNotification) { + } else { return store.dispatch('unregisterPushNotifications') } } diff --git a/src/lib/style.js b/src/lib/style.js new file mode 100644 index 000000000..96603925a --- /dev/null +++ b/src/lib/style.js @@ -0,0 +1,29 @@ +import { applyStyleConfig } from 'src/services/style_setter/style_setter.js' + +const APPEARANCE_SETTINGS_KEYS = new Set( + [ + 'sidebarColumnWidth', + 'contentColumnWidth', + 'notifsColumnWidth', + 'themeEditorMinWidth', + 'textSize', + 'navbarSize', + 'panelHeaderSize', + 'forcedRoundness', + 'emojiSize', + 'emojiReactionsScale', + ].map((x) => 'simple.' + x), +) + +export const piniaStylePlugin = ({ store, options }) => { + if (store.$id === 'sync_config') { + store.$onAction(({ name, args, after }) => { + if (name === 'setPreference') { + const { path } = args[0] + if (APPEARANCE_SETTINGS_KEYS.has(path)) { + after(() => applyStyleConfig(store.mergedConfig)) + } + } + }) + } +} diff --git a/src/main.js b/src/main.js index 91653973d..a4269b4a7 100644 --- a/src/main.js +++ b/src/main.js @@ -20,9 +20,15 @@ import messages from './i18n/messages.js' import createPersistedState, { piniaPersistPlugin, } from './lib/persisted_state.js' -import pushNotifications from './lib/push_notifications_plugin.js' +import { + piniaPushNotificationsPlugin, + vuexPushNotificationsPlugin, +} from './lib/push_notifications_plugin.js' import vuexModules from './modules/index.js' +import { piniaLanguagePlugin } from 'src/lib/language.js' +import { piniaStylePlugin } from 'src/lib/style.js' + const currentLocale = (window.navigator.language || 'en').split('-')[0] const i18n = createI18n({ @@ -35,7 +41,7 @@ const i18n = createI18n({ messages.setLanguage(i18n.global, currentLocale) const persistedStateOptions = { - paths: ['serverSideStorage.cache', 'config', 'users.lastLoginName', 'oauth'], + paths: ['syncConfig.cache', 'config', 'users.lastLoginName', 'oauth'], } ;(async () => { @@ -66,9 +72,12 @@ const persistedStateOptions = { try { let storageError - const plugins = [pushNotifications] + const plugins = [vuexPushNotificationsPlugin] const pinia = createPinia() pinia.use(piniaPersistPlugin()) + pinia.use(piniaLanguagePlugin) + pinia.use(piniaStylePlugin) + pinia.use(piniaPushNotificationsPlugin) try { const persistedState = await createPersistedState(persistedStateOptions)