From ec4d5857d80938758ce64930159be2c941d4e30f Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 26 Dec 2020 14:11:08 +0900 Subject: Fix service worker generation --- src/client/scripts/compose-notification.ts | 95 ------------------------------ src/client/sw.ts | 67 --------------------- src/client/sw/compose-notification.ts | 90 ++++++++++++++++++++++++++++ src/client/sw/i18n.ts | 3 + src/client/sw/sw.ts | 66 +++++++++++++++++++++ webpack.config.ts | 2 +- 6 files changed, 160 insertions(+), 163 deletions(-) delete mode 100644 src/client/scripts/compose-notification.ts delete mode 100644 src/client/sw.ts create mode 100644 src/client/sw/compose-notification.ts create mode 100644 src/client/sw/i18n.ts create mode 100644 src/client/sw/sw.ts diff --git a/src/client/scripts/compose-notification.ts b/src/client/scripts/compose-notification.ts deleted file mode 100644 index 1552d45e4e..0000000000 --- a/src/client/scripts/compose-notification.ts +++ /dev/null @@ -1,95 +0,0 @@ -import getNoteSummary from '../../misc/get-note-summary'; -import getUserName from '../../misc/get-user-name'; -import { clientDb, get, bulkGet } from '../db'; - -const getTranslation = (text: string): Promise => get(text, clientDb.i18n); - -export default async function(type, data): Promise<[string, NotificationOptions]> { - const contexts = ['deletedNote', 'invisibleNote', 'withNFiles', 'poll']; - const locale = Object.fromEntries(await bulkGet(contexts, clientDb.i18n) as [string, string][]); - - switch (type) { - case 'driveFileCreated': // TODO (Server Side) - return [await getTranslation('_notification.fileUploaded'), { - body: data.name, - icon: data.url - }]; - case 'notification': - switch (data.type) { - case 'mention': - return [(await getTranslation('_notification.youGotMention')).replace('{name}', getUserName(data.user)), { - body: getNoteSummary(data.note, locale), - icon: data.user.avatarUrl - }]; - - case 'reply': - return [(await getTranslation('_notification.youGotReply')).replace('{name}', getUserName(data.user)), { - body: getNoteSummary(data.note, locale), - icon: data.user.avatarUrl - }]; - - case 'renote': - return [(await getTranslation('_notification.youRenoted')).replace('{name}', getUserName(data.user)), { - body: getNoteSummary(data.note, locale), - icon: data.user.avatarUrl - }]; - - case 'quote': - return [(await getTranslation('_notification.youGotQuote')).replace('{name}', getUserName(data.user)), { - body: getNoteSummary(data.note, locale), - icon: data.user.avatarUrl - }]; - - case 'reaction': - return [`${data.reaction} ${getUserName(data.user)}`, { - body: getNoteSummary(data.note, locale), - icon: data.user.avatarUrl - }]; - - case 'pollVote': - return [(await getTranslation('_notification.youGotPoll')).replace('{name}', getUserName(data.user)), { - body: getNoteSummary(data.note, locale), - icon: data.user.avatarUrl - }]; - - case 'follow': - return [await getTranslation('_notification.youWereFollowed'), { - body: getUserName(data.user), - icon: data.user.avatarUrl - }]; - - case 'receiveFollowRequest': - return [await getTranslation('_notification.youReceivedFollowRequest'), { - body: getUserName(data.user), - icon: data.user.avatarUrl - }]; - - case 'followRequestAccepted': - return [await getTranslation('_notification.yourFollowRequestAccepted'), { - body: getUserName(data.user), - icon: data.user.avatarUrl - }]; - - case 'groupInvited': - return [await getTranslation('_notification.youWereInvitedToGroup'), { - body: data.group.name - }]; - - default: - return null; - } - case 'unreadMessagingMessage': - if (data.groupId === null) { - return [(await getTranslation('_notification.youGotMessagingMessageFromUser')).replace('{name}', getUserName(data.user)), { - icon: data.user.avatarUrl, - tag: `messaging:user:${data.user.id}` - }]; - } - return [(await getTranslation('_notification.youGotMessagingMessageFromGroup')).replace('{name}', data.group.name), { - icon: data.user.avatarUrl, - tag: `messaging:group:${data.group.id}` - }]; - default: - return null; - } -} diff --git a/src/client/sw.ts b/src/client/sw.ts deleted file mode 100644 index 01ed216029..0000000000 --- a/src/client/sw.ts +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Service Worker - */ -declare var self: ServiceWorkerGlobalScope; - -import composeNotification from '@/scripts/compose-notification'; - -// eslint-disable-next-line no-undef -const version = _VERSION_; -const cacheName = `mk-cache-${version}`; - -const apiUrl = `${location.origin}/api/`; - -// インストールされたとき -self.addEventListener('install', ev => { - console.info('installed'); - - ev.waitUntil( - caches.open(cacheName) - .then(cache => { - return cache.addAll([ - `/?v=${version}` - ]); - }) - .then(() => self.skipWaiting()) - ); -}); - -self.addEventListener('activate', ev => { - ev.waitUntil( - caches.keys() - .then(cacheNames => Promise.all( - cacheNames - .filter((v) => v !== cacheName) - .map(name => caches.delete(name)) - )) - .then(() => self.clients.claim()) - ); -}); - -self.addEventListener('fetch', ev => { - if (ev.request.method !== 'GET' || ev.request.url.startsWith(apiUrl)) return; - ev.respondWith( - caches.match(ev.request) - .then(response => { - return response || fetch(ev.request); - }) - .catch(() => { - return caches.match(`/?v=${version}`); - }) - ); -}); - -// プッシュ通知を受け取ったとき -self.addEventListener('push', ev => { - // クライアント取得 - ev.waitUntil(self.clients.matchAll({ - includeUncontrolled: true - }).then(async clients => { - // クライアントがあったらストリームに接続しているということなので通知しない - if (clients.length != 0) return; - - const { type, body } = ev.data.json(); - - return self.registration.showNotification(...(await composeNotification(type, body))); - })); -}); diff --git a/src/client/sw/compose-notification.ts b/src/client/sw/compose-notification.ts new file mode 100644 index 0000000000..0863d7ef8b --- /dev/null +++ b/src/client/sw/compose-notification.ts @@ -0,0 +1,90 @@ +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]> { + switch (type) { + case 'driveFileCreated': // TODO (Server Side) + return [i18n.t('_notification.fileUploaded'), { + body: data.name, + icon: data.url + }]; + case 'notification': + switch (data.type) { + case 'mention': + return [i18n.t('_notification.youGotMention', { name: getUserName(data.user) }), { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'reply': + return [i18n.t('_notification.youGotReply', { name: getUserName(data.user) }), { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'renote': + return [i18n.t('_notification.youRenoted', { name: getUserName(data.user) }), { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'quote': + return [i18n.t('_notification.youGotQuote', { name: getUserName(data.user) }), { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'reaction': + return [`${data.reaction} ${getUserName(data.user)}`, { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'pollVote': + return [i18n.t('_notification.youGotPoll', { name: getUserName(data.user) }), { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'follow': + return [i18n.t('_notification.youWereFollowed'), { + body: getUserName(data.user), + icon: data.user.avatarUrl + }]; + + case 'receiveFollowRequest': + return [i18n.t('_notification.youReceivedFollowRequest'), { + body: getUserName(data.user), + icon: data.user.avatarUrl + }]; + + case 'followRequestAccepted': + return [i18n.t('_notification.yourFollowRequestAccepted'), { + body: getUserName(data.user), + icon: data.user.avatarUrl + }]; + + case 'groupInvited': + return [i18n.t('_notification.youWereInvitedToGroup'), { + body: data.group.name + }]; + + default: + return null; + } + case 'unreadMessagingMessage': + if (data.groupId === null) { + return [i18n.t('_notification.youGotMessagingMessageFromUser', { name: getUserName(data.user) }), { + icon: data.user.avatarUrl, + tag: `messaging:user:${data.user.id}` + }]; + } + return [i18n.t('_notification.youGotMessagingMessageFromGroup', { name: data.group.name }), { + icon: data.user.avatarUrl, + tag: `messaging:group:${data.group.id}` + }]; + default: + return null; + } +} diff --git a/src/client/sw/i18n.ts b/src/client/sw/i18n.ts new file mode 100644 index 0000000000..524a205b2f --- /dev/null +++ b/src/client/sw/i18n.ts @@ -0,0 +1,3 @@ +import { I18n } from '@/i18n'; + +export const i18n = new I18n(_LOCALE_); diff --git a/src/client/sw/sw.ts b/src/client/sw/sw.ts new file mode 100644 index 0000000000..91d668c27b --- /dev/null +++ b/src/client/sw/sw.ts @@ -0,0 +1,66 @@ +/** + * Service Worker + */ +declare var self: ServiceWorkerGlobalScope; + +import composeNotification from '@/sw/compose-notification'; + +const version = _VERSION_; +const cacheName = `mk-cache-${version}`; + +const apiUrl = `${location.origin}/api/`; + +// インストールされたとき +self.addEventListener('install', ev => { + console.info('installed'); + + ev.waitUntil( + caches.open(cacheName) + .then(cache => { + return cache.addAll([ + `/?v=${version}` + ]); + }) + .then(() => self.skipWaiting()) + ); +}); + +self.addEventListener('activate', ev => { + ev.waitUntil( + caches.keys() + .then(cacheNames => Promise.all( + cacheNames + .filter((v) => v !== cacheName) + .map(name => caches.delete(name)) + )) + .then(() => self.clients.claim()) + ); +}); + +self.addEventListener('fetch', ev => { + if (ev.request.method !== 'GET' || ev.request.url.startsWith(apiUrl)) return; + ev.respondWith( + caches.match(ev.request) + .then(response => { + return response || fetch(ev.request); + }) + .catch(() => { + return caches.match(`/?v=${version}`); + }) + ); +}); + +// プッシュ通知を受け取ったとき +self.addEventListener('push', ev => { + // クライアント取得 + ev.waitUntil(self.clients.matchAll({ + includeUncontrolled: true + }).then(async clients => { + // クライアントがあったらストリームに接続しているということなので通知しない + if (clients.length != 0) return; + + const { type, body } = ev.data.json(); + + return self.registration.showNotification(...(await composeNotification(type, body))); + })); +}); diff --git a/webpack.config.ts b/webpack.config.ts index 2d6ecd1d58..4efbeeb04b 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -38,7 +38,7 @@ module.exports = Object.keys(isProduction ? locales : { }).map(lang => ({ entry: { app: './src/client/init.ts', - sw: './src/client/sw.ts' + sw: './src/client/sw/sw.ts' }, module: { rules: [{ -- cgit v1.2.3-freya