diff --git a/build/sw_plugin.js b/build/sw_plugin.js index ba92993a7..ee952d229 100644 --- a/build/sw_plugin.js +++ b/build/sw_plugin.js @@ -1,7 +1,9 @@ import { readFile } from 'node:fs/promises' import { dirname, resolve } from 'node:path' import { fileURLToPath } from 'node:url' +import * as esbuild from 'esbuild' import { build } from 'vite' +import { exactRegex } from '@rolldown/pluginutils' import { generateServiceWorkerMessages, @@ -14,18 +16,15 @@ const getSWMessagesAsText = async () => { } const projectRoot = dirname(dirname(fileURLToPath(import.meta.url))) -const swEnvName = 'virtual:pleroma-fe/service_worker_env' -const swEnvNameResolved = '\0' + swEnvName const getDevSwEnv = () => `self.serviceWorkerOption = { assets: [] };` const getProdSwEnv = ({ assets }) => `self.serviceWorkerOption = { assets: ${JSON.stringify(assets)} };` -export const devSwPlugin = ({ swSrc, swDest, transformSW, alias }) => { +export const devSwPlugin = ({ swSrc, swDest }) => { const swFullSrc = resolve(projectRoot, swSrc) return { - name: 'dev-sw-plugin', - apply: 'serve', + name: 'dev-sw-plugin', apply: 'serve', configResolved() { /* no-op */ }, @@ -33,173 +32,35 @@ export const devSwPlugin = ({ swSrc, swDest, transformSW, alias }) => { const name = id.startsWith('/') ? id.slice(1) : id if (name === swDest) { return swFullSrc - } else if (name === swEnvName) { - return swEnvNameResolved } return null }, async load(id) { if (id === swFullSrc) { return readFile(swFullSrc, 'utf-8') - } else if (id === swEnvNameResolved) { - return getDevSwEnv() } return null }, - /** - * vite does not bundle the service worker - * during dev, and firefox does not support ESM as service worker - * https://bugzilla.mozilla.org/show_bug.cgi?id=1360870 - */ - async transform(code, id) { - if (id === swFullSrc && transformSW) { - const res = await build({ - entryPoints: [swSrc], - bundle: true, - write: false, - outfile: 'sw-pleroma.js', - plugins: [ - { - name: 'vite-like-root-resolve', - setup(b) { - b.onResolve({ filter: new RegExp(/^\//) }, (args) => ({ - path: resolve(projectRoot, args.path.slice(1)), - })) - }, - }, - { - name: 'sw-messages', - setup(b) { - b.onResolve( - { filter: new RegExp('^' + swMessagesName + '$') }, - (args) => ({ - path: args.path, - namespace: 'sw-messages', - }), - ) - b.onLoad( - { filter: /.*/, namespace: 'sw-messages' }, - async () => ({ - contents: await getSWMessagesAsText(), - }), - ) - }, - }, - { - name: 'sw-env', - setup(b) { - b.onResolve( - { filter: new RegExp('^' + swEnvName + '$') }, - (args) => ({ - path: args.path, - namespace: 'sw-env', - }), - ) - b.onLoad({ filter: /.*/, namespace: 'sw-env' }, () => ({ - contents: getDevSwEnv(), - })) - }, - }, - ], - }) - const text = res.outputFiles[0].text - return text - } - }, } } -// Idea taken from -// https://github.com/vite-pwa/vite-plugin-pwa/blob/main/src/plugins/build.ts -// rollup does not support compiling to iife if we want to code-split; -// however, we must compile the service worker to iife because of browser support. -// Run another vite build just for the service worker targeting iife at -// the end of the build. -export const buildSwPlugin = ({ swSrc, swDest }) => { - let config - return { - name: 'build-sw-plugin', - enforce: 'post', - apply: 'build', - configResolved(resolvedConfig) { - config = { - define: resolvedConfig.define, - resolve: resolvedConfig.resolve, - plugins: [swMessagesPlugin()], - publicDir: false, - build: { - ...resolvedConfig.build, - lib: { - entry: swSrc, - formats: ['iife'], - name: 'sw_pleroma', - }, - emptyOutDir: true, - rolldownOptions: { - output: { - entryFileNames: swDest, - }, - }, - }, - configFile: false, - } - }, - generateBundle: { - order: 'post', - sequential: true, - async handler(_, bundle) { - const assets = Object.keys(bundle) - .filter((name) => !/\.map$/.test(name)) - .map((name) => '/' + name) - config.plugins.push({ - name: 'build-sw-env-plugin', - resolveId(id) { - if (id === swEnvName) { - return swEnvNameResolved - } - return null - }, - load(id) { - if (id === swEnvNameResolved) { - return getProdSwEnv({ assets }) - } - return null - }, - }) - }, - }, - closeBundle: { - order: 'post', - sequential: true, - async handler() { - console.info('Building service worker for production') - await build(config) - }, - }, - } -} - -const swMessagesName = 'virtual:pleroma-fe/service_worker_messages' -const swMessagesNameResolved = '\0' + swMessagesName - export const swMessagesPlugin = () => { + const swMessagesName = 'virtual:pleroma-fe/service_worker_messages' + const swMessagesNameResolved = '\0' + swMessagesName + return { name: 'sw-messages-plugin', - resolveId(id) { - if (id === swMessagesName) { - Object.values(i18nFiles).forEach((f) => { - this.addWatchFile(f) - }) + resolveId: { + filter: { id: exactRegex(swMessagesName) }, + handler() { return swMessagesNameResolved - } else { - return null } }, - async load(id) { - if (id === swMessagesNameResolved) { + load: { + filter: { id: exactRegex(swMessagesNameResolved) }, + async handler () { return await getSWMessagesAsText() } - return null }, } } diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js index 8aafd2709..d25430a65 100644 --- a/src/components/mobile_nav/mobile_nav.js +++ b/src/components/mobile_nav/mobile_nav.js @@ -66,7 +66,6 @@ const MobileNav = { countExtraNotifications( this.$store, useMergedConfigStore().mergedConfig, - useAnnouncementsStore().unreadAnnouncementCount, ) ) }, diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 9c50e645a..96263d93b 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -115,7 +115,6 @@ const Notifications = { return countExtraNotifications( this.$store, useMergedConfigStore().mergedConfig, - useAnnouncementsStore().unreadAnnouncementCount, ) }, unseenCountTitle() { diff --git a/src/modules/notifications.js b/src/modules/notifications.js index d501b39db..bf1e4b9c0 100644 --- a/src/modules/notifications.js +++ b/src/modules/notifications.js @@ -9,7 +9,6 @@ import { maybeShowNotification, } from '../services/notification_utils/notification_utils.js' -import { useI18nStore } from 'src/stores/i18n.js' import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useReportsStore } from 'src/stores/reports.js' import { useSyncConfigStore } from 'src/stores/sync_config.js' @@ -124,7 +123,6 @@ export const notifications = { useMergedConfigStore().mergedConfig.notificationVisibility, Object.values(useSyncConfigStore().prefsStorage.simple.muteFilters), notification, - useI18nStore().i18n, ) } else if (notification.seen) { state.idStore[notification.id].seen = true diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index 1149d7b9b..921600094 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -2,6 +2,7 @@ import { showDesktopNotification } from '../desktop_notification_utils/desktop_n import { muteFilterHits } from '../status_parser/status_parser.js' import { useAnnouncementsStore } from 'src/stores/announcements.js' +import { useI18nStore } from 'src/stores/i18n.js' import FaviconService from 'src/services/favicon_service/favicon_service.js' @@ -75,7 +76,6 @@ export const maybeShowNotification = ( notificationVisibility, muteFilters, notification, - i18n, ) => { const rootState = store.rootState || store.state @@ -89,7 +89,7 @@ export const maybeShowNotification = ( const notificationObject = prepareNotificationObject( notification, - i18n, + useI18nStore().i18n, ) showDesktopNotification(rootState, notificationObject) } @@ -193,7 +193,7 @@ export const prepareNotificationObject = (notification, i18n) => { return notifObj } -export const countExtraNotifications = (store, mergedConfig, unreadAnnouncementCount) => { +export const countExtraNotifications = (store, mergedConfig) => { const rootGetters = store.rootGetters || store.getters if (!mergedConfig.showExtraNotifications) { @@ -205,7 +205,7 @@ export const countExtraNotifications = (store, mergedConfig, unreadAnnouncementC ? rootGetters.unreadChatCount : 0, mergedConfig.showAnnouncementsInExtraNotifications - ? unreadAnnouncementCount + ? useAnnouncementsStore().unreadAnnouncementCount : 0, mergedConfig.showFollowRequestsInExtraNotifications ? rootGetters.followRequestCount diff --git a/src/sw.js b/src/sw.js index cd0d6bb38..f1c1b75d2 100644 --- a/src/sw.js +++ b/src/sw.js @@ -1,9 +1,8 @@ /* eslint-env serviceworker */ -import 'virtual:pleroma-fe/service_worker_env' - import { createI18n } from 'vue-i18n' +import { storage } from 'src/lib/storage.js' import { INSTANCE_DEFAULT_CONFIG } from 'src/modules/default_config_state.js' import { parseNotification } from 'src/services/entity_normalizer/entity_normalizer.service.js' import { prepareNotificationObject } from 'src/services/notification_utils/notification_utils.js' @@ -34,7 +33,7 @@ function getWindowClients() { } const setSettings = async () => { - const piniaState = {} + const piniaState = await storage.getItem('pinia-local-sync_config') const locale = piniaState.prefsStorage.simple.interfaceLanguage || 'en' i18n.locale = locale const notificationsNativeArray = Object.entries( diff --git a/vite.config.js b/vite.config.js index 49a014abb..f79f2327a 100644 --- a/vite.config.js +++ b/vite.config.js @@ -11,12 +11,12 @@ import { configDefaults } from 'vitest/config' import { getCommitHash } from './build/commit_hash.js' import copyPlugin from './build/copy_plugin.js' import emojisPlugin from './build/emojis_plugin.js' -import mswPlugin from './build/msw_plugin.js' import { - buildSwPlugin, devSwPlugin, swMessagesPlugin, } from './build/sw_plugin.js' +import { VitePWA } from 'vite-plugin-pwa' + const localConfigPath = '/config/local.json' const normalizeTarget = (target) => { @@ -142,9 +142,6 @@ export default defineConfig(async ({ mode, command }) => { // outDir: 'custom-dir', // optional, defaults to Vite's build.outDir }, }), - devSwPlugin({ swSrc, swDest, transformSW, alias }), - buildSwPlugin({ swSrc, swDest }), - swMessagesPlugin(), emojisPlugin(), copyPlugin({ inUrl: '/static/ruffle', @@ -163,7 +160,8 @@ export default defineConfig(async ({ mode, command }) => { 'node_modules/.cache/stylelintcache', ), }), - ...(mode === 'test' ? [mswPlugin()] : []), + swMessagesPlugin(), + devSwPlugin({ swSrc, swDest }), ], optimizeDeps: { // For unknown reasons, during vitest, vite will re-optimize the following @@ -208,9 +206,9 @@ export default defineConfig(async ({ mode, command }) => { devtools: {}, // enable devtools mode input: { main: 'index.html', + sw: 'src/sw.js', }, output: { - inlineDynamicImports: false, entryFileNames(chunkInfo) { const id = chunkInfo.facadeModuleId if (id.endsWith(swSrc)) {