add account localization and switchable rooms
Centralize control and OBS copy in a shared TOML catalog, persist the selected locale per account, and broadcast language changes to component streams. Allow account owners to atomically switch their Bilibili room and restart the shared listener without changing component URLs.
This commit is contained in:
@@ -8,27 +8,74 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { parse } from 'smol-toml'
|
||||
|
||||
// A new URL makes the browser check and stage every deployed service worker.
|
||||
// The waiting worker is still activated explicitly by the user in the console.
|
||||
const pwaBuildId = Date.now().toString(36)
|
||||
const serviceWorkerSource = readFileSync(new URL('./pwa/control-sw.js', import.meta.url), 'utf8')
|
||||
const i18nResource = parse(
|
||||
readFileSync(new URL('../../resources/i18n.toml', import.meta.url), 'utf8'),
|
||||
) as unknown as {
|
||||
default_language: string
|
||||
locales: Record<string, { messages: Record<string, string> }>
|
||||
}
|
||||
const defaultLanguage = i18nResource.default_language
|
||||
const defaultMessages = i18nResource.locales[defaultLanguage].messages
|
||||
const manifest = {
|
||||
id: '/control',
|
||||
name: defaultMessages['pwa.manifest.name'],
|
||||
short_name: defaultMessages['pwa.manifest.short_name'],
|
||||
description: defaultMessages['pwa.manifest.description'],
|
||||
lang: defaultLanguage,
|
||||
dir: 'auto',
|
||||
start_url: '/control/?source=pwa',
|
||||
scope: '/control/',
|
||||
display: 'standalone',
|
||||
orientation: 'any',
|
||||
background_color: '#03121a',
|
||||
theme_color: '#0a302f',
|
||||
categories: ['utilities', 'productivity'],
|
||||
icons: [
|
||||
{ src: '/pwa/icon-192.png', sizes: '192x192', type: 'image/png', purpose: 'any' },
|
||||
{ src: '/pwa/icon-512.png', sizes: '512x512', type: 'image/png', purpose: 'any' },
|
||||
{
|
||||
src: '/pwa/icon-maskable-512.png',
|
||||
sizes: '512x512',
|
||||
type: 'image/png',
|
||||
purpose: 'maskable',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
{
|
||||
name: 'control-pwa-assets',
|
||||
transformIndexHtml(html) {
|
||||
return html
|
||||
.replaceAll('__DEFAULT_LANGUAGE__', defaultLanguage)
|
||||
.replaceAll('__APP_NAME__', defaultMessages['pwa.manifest.name'])
|
||||
.replaceAll('__APP_SHORT_NAME__', defaultMessages['pwa.manifest.short_name'])
|
||||
.replaceAll('__APP_DESCRIPTION__', defaultMessages['pwa.manifest.description'])
|
||||
},
|
||||
generateBundle() {
|
||||
this.emitFile({
|
||||
type: 'asset',
|
||||
fileName: 'control/sw.js',
|
||||
source: serviceWorkerSource.replaceAll('__PWA_BUILD_ID__', pwaBuildId),
|
||||
})
|
||||
this.emitFile({
|
||||
type: 'asset',
|
||||
fileName: 'control/manifest.webmanifest',
|
||||
source: JSON.stringify(manifest, null, 2),
|
||||
})
|
||||
},
|
||||
},
|
||||
],
|
||||
define: {
|
||||
__PWA_BUILD_ID__: JSON.stringify(pwaBuildId),
|
||||
__I18N_RESOURCE__: JSON.stringify(i18nResource),
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user