Merge branch 'optimize' into shigusegubu-themes3

This commit is contained in:
Henry Jameson 2026-06-02 23:53:30 +03:00
commit 23b6366d53
7 changed files with 182 additions and 36 deletions

View file

@ -1,9 +1,7 @@
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,
@ -16,15 +14,18 @@ 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 }) => {
export const devSwPlugin = ({ swSrc, swDest, transformSW, alias }) => {
const swFullSrc = resolve(projectRoot, swSrc)
return {
name: 'dev-sw-plugin', apply: 'serve',
name: 'dev-sw-plugin',
apply: 'serve',
configResolved() {
/* no-op */
},
@ -32,35 +33,173 @@ export const devSwPlugin = ({ swSrc, swDest }) => {
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 = () => {
return {
name: 'sw-messages-plugin',
resolveId(id) {
if (id === swMessagesName) {
Object.values(i18nFiles).forEach((f) => {
this.addWatchFile(f)
})
return swMessagesNameResolved
} else {
return null
}
},
async load(id) {
if (id === swMessagesNameResolved) {
return await getSWMessagesAsText()
}
return null
},
}
}
export const swMessagesPlugin = () => {
const swMessagesName = 'virtual:pleroma-fe/service_worker_messages'
const swMessagesNameResolved = '\0' + swMessagesName
return {
name: 'sw-messages-plugin',
resolveId: {
filter: { id: exactRegex(swMessagesName) },
handler() {
return swMessagesNameResolved
}
},
load: {
filter: { id: exactRegex(swMessagesNameResolved) },
async handler () {
return await getSWMessagesAsText()
}
},
}
}

View file

@ -66,6 +66,7 @@ const MobileNav = {
countExtraNotifications(
this.$store,
useMergedConfigStore().mergedConfig,
useAnnouncementsStore().unreadAnnouncementCount,
)
)
},

View file

@ -115,6 +115,7 @@ const Notifications = {
return countExtraNotifications(
this.$store,
useMergedConfigStore().mergedConfig,
useAnnouncementsStore().unreadAnnouncementCount,
)
},
unseenCountTitle() {

View file

@ -9,6 +9,7 @@ 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'
@ -123,6 +124,7 @@ 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

View file

@ -2,7 +2,6 @@ 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'
@ -76,6 +75,7 @@ export const maybeShowNotification = (
notificationVisibility,
muteFilters,
notification,
i18n,
) => {
const rootState = store.rootState || store.state
@ -89,7 +89,7 @@ export const maybeShowNotification = (
const notificationObject = prepareNotificationObject(
notification,
useI18nStore().i18n,
i18n,
)
showDesktopNotification(rootState, notificationObject)
}
@ -193,7 +193,7 @@ export const prepareNotificationObject = (notification, i18n) => {
return notifObj
}
export const countExtraNotifications = (store, mergedConfig) => {
export const countExtraNotifications = (store, mergedConfig, unreadAnnouncementCount) => {
const rootGetters = store.rootGetters || store.getters
if (!mergedConfig.showExtraNotifications) {
@ -205,7 +205,7 @@ export const countExtraNotifications = (store, mergedConfig) => {
? rootGetters.unreadChatCount
: 0,
mergedConfig.showAnnouncementsInExtraNotifications
? useAnnouncementsStore().unreadAnnouncementCount
? unreadAnnouncementCount
: 0,
mergedConfig.showFollowRequestsInExtraNotifications
? rootGetters.followRequestCount

View file

@ -1,8 +1,9 @@
/* 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'
@ -33,7 +34,7 @@ function getWindowClients() {
}
const setSettings = async () => {
const piniaState = await storage.getItem('pinia-local-sync_config')
const piniaState = {}
const locale = piniaState.prefsStorage.simple.interfaceLanguage || 'en'
i18n.locale = locale
const notificationsNativeArray = Object.entries(

View file

@ -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 = '<projectRoot>/config/local.json'
const normalizeTarget = (target) => {
@ -142,6 +142,9 @@ 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',
@ -160,8 +163,7 @@ export default defineConfig(async ({ mode, command }) => {
'node_modules/.cache/stylelintcache',
),
}),
swMessagesPlugin(),
devSwPlugin({ swSrc, swDest }),
...(mode === 'test' ? [mswPlugin()] : []),
],
optimizeDeps: {
// For unknown reasons, during vitest, vite will re-optimize the following
@ -206,9 +208,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)) {