diff options
| author | tamaina <tamaina@hotmail.co.jp> | 2021-02-06 18:55:53 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-06 18:55:53 +0900 |
| commit | 40bfa3ef0407f83484031bfe74dcecb149c202a0 (patch) | |
| tree | 8128fa49e2041e00f6b130cb150f6571cf2a5ec7 /src/client/sw | |
| parent | Resolve #7096 (diff) | |
| download | misskey-40bfa3ef0407f83484031bfe74dcecb149c202a0.tar.gz misskey-40bfa3ef0407f83484031bfe74dcecb149c202a0.tar.bz2 misskey-40bfa3ef0407f83484031bfe74dcecb149c202a0.zip | |
Resurrect Service Worker (#7108)
* Resolve #7106
* fix lint
* fix lint
* save lang in idb
* fix lint
* fix
* cache locale file
* fix lint
* :v:
* wip
* fix [wip]
* fix [wip]
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
Diffstat (limited to 'src/client/sw')
| -rw-r--r-- | src/client/sw/compose-notification.ts | 13 | ||||
| -rw-r--r-- | src/client/sw/i18n.ts | 5 | ||||
| -rw-r--r-- | src/client/sw/sw.ts | 89 |
3 files changed, 93 insertions, 14 deletions
diff --git a/src/client/sw/compose-notification.ts b/src/client/sw/compose-notification.ts index 17421db5c8..e9586dd574 100644 --- a/src/client/sw/compose-notification.ts +++ b/src/client/sw/compose-notification.ts @@ -1,8 +1,17 @@ +/** + * Notification composer of Service Worker + */ +declare var self: ServiceWorkerGlobalScope; + import { getNoteSummary } from '../../misc/get-note-summary'; import getUserName from '../../misc/get-user-name'; -import { i18n } from '@/sw/i18n'; -export default async function(type, data): Promise<[string, NotificationOptions]> { +export default async function(type, data, i18n): Promise<[string, NotificationOptions] | null | undefined> { + if (!i18n) { + console.log('no i18n'); + return; + } + switch (type) { case 'driveFileCreated': // TODO (Server Side) return [i18n.t('_notification.fileUploaded'), { diff --git a/src/client/sw/i18n.ts b/src/client/sw/i18n.ts deleted file mode 100644 index 9b3e3b2f4d..0000000000 --- a/src/client/sw/i18n.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { I18n } from '@/i18n'; - -export const i18n = new I18n({ - // TODO -}); diff --git a/src/client/sw/sw.ts b/src/client/sw/sw.ts index 91d668c27b..c92cae1292 100644 --- a/src/client/sw/sw.ts +++ b/src/client/sw/sw.ts @@ -3,17 +3,30 @@ */ declare var self: ServiceWorkerGlobalScope; +import { get, set } from 'idb-keyval'; import composeNotification from '@/sw/compose-notification'; +import { I18n } from '@/scripts/i18n'; +//#region Variables const version = _VERSION_; const cacheName = `mk-cache-${version}`; - const apiUrl = `${location.origin}/api/`; -// インストールされたとき -self.addEventListener('install', ev => { - console.info('installed'); +let lang: string; +let i18n: I18n<any>; +let pushesPool: any[] = []; +//#endregion + +//#region Startup +get('lang').then(async prelang => { + if (!prelang) return; + lang = prelang; + return fetchLocale(); +}); +//#endregion +//#region Lifecycle: Install +self.addEventListener('install', ev => { ev.waitUntil( caches.open(cacheName) .then(cache => { @@ -24,7 +37,9 @@ self.addEventListener('install', ev => { .then(() => self.skipWaiting()) ); }); +//#endregion +//#region Lifecycle: Activate self.addEventListener('activate', ev => { ev.waitUntil( caches.keys() @@ -36,7 +51,9 @@ self.addEventListener('activate', ev => { .then(() => self.clients.claim()) ); }); +//#endregion +//#region When: Fetching self.addEventListener('fetch', ev => { if (ev.request.method !== 'GET' || ev.request.url.startsWith(apiUrl)) return; ev.respondWith( @@ -49,8 +66,9 @@ self.addEventListener('fetch', ev => { }) ); }); +//#endregion -// プッシュ通知を受け取ったとき +//#region When: Caught Notification self.addEventListener('push', ev => { // クライアント取得 ev.waitUntil(self.clients.matchAll({ @@ -59,8 +77,65 @@ self.addEventListener('push', ev => { // クライアントがあったらストリームに接続しているということなので通知しない if (clients.length != 0) return; - const { type, body } = ev.data.json(); + const { type, body } = ev.data?.json(); + + // localeを読み込めておらずi18nがundefinedだった場合はpushesPoolにためておく + if (!i18n) return pushesPool.push({ type, body }); - return self.registration.showNotification(...(await composeNotification(type, body))); + const n = await composeNotification(type, body, i18n); + if (n) return self.registration.showNotification(...n); })); }); +//#endregion + +//#region When: Caught a message from the client +self.addEventListener('message', ev => { + switch(ev.data) { + case 'clear': + return; // TODO + default: + break; + } + + if (typeof ev.data === 'object') { + // E.g. '[object Array]' → 'array' + const otype = Object.prototype.toString.call(ev.data).slice(8, -1).toLowerCase(); + + if (otype === 'object') { + if (ev.data.msg === 'initialize') { + lang = ev.data.lang; + set('lang', lang); + fetchLocale(); + } + } + } +}); +//#endregion + +//#region Function: (Re)Load i18n instance +async function fetchLocale() { + //#region localeファイルの読み込み + // Service Workerは何度も起動しそのたびにlocaleを読み込むので、CacheStorageを使う + const localeUrl = `/assets/locales/${lang}.${version}.json`; + let localeRes = await caches.match(localeUrl); + + if (!localeRes) { + localeRes = await fetch(localeUrl); + const clone = localeRes?.clone(); + if (!clone?.clone().ok) return; + + caches.open(cacheName).then(cache => cache.put(localeUrl, clone)); + } + + i18n = new I18n(await localeRes.json()); + //#endregion + + //#region i18nをきちんと読み込んだ後にやりたい処理 + for (const { type, body } of pushesPool) { + const n = await composeNotification(type, body, i18n); + if (n) self.registration.showNotification(...n); + } + pushesPool = []; + //#endregion +} +//#endregion |