diff options
| author | tamaina <tamaina@hotmail.co.jp> | 2023-04-11 14:11:39 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-11 14:11:39 +0900 |
| commit | 3a90bcc03cc166632fb64aa76130b63a0ad37a64 (patch) | |
| tree | e5e6e6e07eb30d1369142d86546b6ab419d31a1b /packages/sw/src | |
| parent | fix #10554 チャンネルの検索用ページとAPIの追加 (#10555) (diff) | |
| download | misskey-3a90bcc03cc166632fb64aa76130b63a0ad37a64.tar.gz misskey-3a90bcc03cc166632fb64aa76130b63a0ad37a64.tar.bz2 misskey-3a90bcc03cc166632fb64aa76130b63a0ad37a64.zip | |
sw: なんかもうめっちゃ変えた (#10570)
* sw: なんかいろいろ
* remove debug code
* never renotify
* update changelog.md
Diffstat (limited to 'packages/sw/src')
| -rw-r--r-- | packages/sw/src/scripts/create-notification.ts | 34 | ||||
| -rw-r--r-- | packages/sw/src/scripts/operations.ts | 27 | ||||
| -rw-r--r-- | packages/sw/src/sw.ts | 35 | ||||
| -rw-r--r-- | packages/sw/src/types.ts | 2 |
4 files changed, 74 insertions, 24 deletions
diff --git a/packages/sw/src/scripts/create-notification.ts b/packages/sw/src/scripts/create-notification.ts index 8e214c9850..4d27858253 100644 --- a/packages/sw/src/scripts/create-notification.ts +++ b/packages/sw/src/scripts/create-notification.ts @@ -21,7 +21,7 @@ const iconUrl = (name: BadgeNames) => `/static-assets/tabler-badges/${name}.png` * 1. Find the icon and download png from https://tabler-icons.io/ * 2. vips resize ~/Downloads/icon-name.png vipswork.png 0.4; vips scRGB2BW vipswork.png ~/icon-name.png"[compression=9,strip]"; rm vipswork.png; * 3. mv ~/icon-name.png ~/misskey/packages/backend/assets/tabler-badges/ - * 4. Add 'icon-name' to badgeNames + * 4. Add 'icon-name' to BadgeNames * 5. Add `badge: iconUrl('icon-name'),` */ @@ -168,14 +168,6 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif }]; } - case 'pollEnded': - return [t('_notification.pollEnded'), { - body: data.body.note.text || '', - badge: iconUrl('chart-arrows'), - tag: `poll:${data.body.note.id}`, - data, - }]; - case 'receiveFollowRequest': return [t('_notification.youReceivedFollowRequest'), { body: getUserName(data.body.user), @@ -202,6 +194,14 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif data, }]; + case 'achievementEarned': + return [t('_notification.achievementEarned'), { + body: t(`_achievements._types._${data.body.achievement}.title`), + badge: iconUrl('medal'), + data, + tag: `achievement:${data.body.achievement}`, + }]; + case 'app': return [data.body.header ?? data.body.body, { body: data.body.header ? data.body.body : '', @@ -233,17 +233,29 @@ export async function createEmptyNotification() { const { t } = i18n; await globalThis.registration.showNotification( - t('_notification.emptyPushNotificationMessage'), + (new URL(origin)).host, { + body: `Misskey v${_VERSION_}`, silent: true, badge: iconUrl('null'), tag: 'read_notification', + actions: [ + { + action: 'markAllAsRead', + title: t('markAllAsRead'), + }, + { + action: 'settings', + title: t('notificationSettings'), + }, + ], + data: {}, }, ); setTimeout(async () => { try { - await closeNotificationsByTags(['user_visible_auto_notification', 'read_notification']); + await closeNotificationsByTags(['user_visible_auto_notification']); } finally { res(); } diff --git a/packages/sw/src/scripts/operations.ts b/packages/sw/src/scripts/operations.ts index 0978cf9a31..2fd02f9dcb 100644 --- a/packages/sw/src/scripts/operations.ts +++ b/packages/sw/src/scripts/operations.ts @@ -4,7 +4,6 @@ */ import * as Misskey from 'misskey-js'; import { SwMessage, SwMessageOrderType } from '@/types'; -import { acct as getAcct } from '@/filters/user'; import { getAccountFromId } from '@/scripts/get-account-from-id'; import { getUrlWithLoginId } from '@/scripts/login-id'; @@ -17,13 +16,27 @@ export async function api<E extends keyof Misskey.Endpoints>(endpoint: E, userId return cli.request(endpoint, options, account.token); } +// mark-all-as-read送出を1秒間隔に制限する +const readBlockingStatus = new Map<string, boolean>(); +export function sendMarkAllAsRead(userId: string): Promise<null | undefined | void> { + if (readBlockingStatus.get(userId)) return Promise.resolve(); + readBlockingStatus.set(userId, true); + return new Promise(resolve => { + setTimeout(() => { + readBlockingStatus.set(userId, false); + api('notifications/mark-all-as-read', userId) + .then(resolve, resolve); + }, 1000); + }); +} + // rendered acctからユーザーを開く -export function openUser(acct: string, loginId: string) { +export function openUser(acct: string, loginId?: string) { return openClient('push', `/@${acct}`, loginId, { acct }); } // noteIdからノートを開く -export function openNote(noteId: string, loginId: string) { +export function openNote(noteId: string, loginId?: string) { return openClient('push', `/notes/${noteId}`, loginId, { noteId }); } @@ -33,7 +46,7 @@ export function openAntenna(antennaId: string, loginId: string) { } // post-formのオプションから投稿フォームを開く -export async function openPost(options: any, loginId: string) { +export async function openPost(options: any, loginId?: string) { // クエリを作成しておく let url = '/share?'; if (options.initialText) url += `text=${options.initialText}&`; @@ -43,7 +56,7 @@ export async function openPost(options: any, loginId: string) { return openClient('post', url, loginId, { options }); } -export async function openClient(order: SwMessageOrderType, url: string, loginId: string, query: any = {}) { +export async function openClient(order: SwMessageOrderType, url: string, loginId?: string, query: any = {}) { const client = await findClient(); if (client) { @@ -51,7 +64,7 @@ export async function openClient(order: SwMessageOrderType, url: string, loginId return client; } - return globalThis.clients.openWindow(getUrlWithLoginId(url, loginId)); + return globalThis.clients.openWindow(loginId ? getUrlWithLoginId(url, loginId) : url); } export async function findClient() { @@ -59,7 +72,7 @@ export async function findClient() { type: 'window', }); for (const c of clients) { - if (!new URL(c.url).searchParams.has('zen')) return c; + if (!(new URL(c.url)).searchParams.has('zen')) return c; } return null; } diff --git a/packages/sw/src/sw.ts b/packages/sw/src/sw.ts index 56050987a0..c1cde8b3c2 100644 --- a/packages/sw/src/sw.ts +++ b/packages/sw/src/sw.ts @@ -1,9 +1,9 @@ import { createEmptyNotification, createNotification } from '@/scripts/create-notification'; import { swLang } from '@/scripts/lang'; -import { api } from '@/scripts/operations'; import { PushNotificationDataMap } from '@/types'; import * as swos from '@/scripts/operations'; import { acct as getAcct } from '@/filters/user'; +import { get } from 'idb-keyval'; globalThis.addEventListener('install', ev => { //ev.waitUntil(globalThis.skipWaiting()); @@ -54,6 +54,10 @@ globalThis.addEventListener('push', ev => { if ((new Date()).getTime() - data.dateTime > 1000 * 60 * 60 * 24) break; return createNotification(data); + case 'readAllNotifications': + await globalThis.registration.getNotifications() + .then(notifications => notifications.forEach(n => n.close())); + break; } await createEmptyNotification(); @@ -68,7 +72,7 @@ globalThis.addEventListener('notificationclick', (ev: ServiceWorkerGlobalScopeEv } const { action, notification } = ev; - const data: PushNotificationDataMap[keyof PushNotificationDataMap] = notification.data; + const data: PushNotificationDataMap[keyof PushNotificationDataMap] = notification.data ?? {}; const { userId: loginId } = data; let client: WindowClient | null = null; @@ -124,13 +128,29 @@ globalThis.addEventListener('notificationclick', (ev: ServiceWorkerGlobalScopeEv break; case 'unreadAntennaNote': client = await swos.openAntenna(data.body.antenna.id, loginId); + break; + default: + switch (action) { + case 'markAllAsRead': + await globalThis.registration.getNotifications() + .then(notifications => notifications.forEach(n => n.close())); + await get('accounts').then(accounts => { + return Promise.all(accounts.map(async account => { + await swos.sendMarkAllAsRead(account.id); + })); + }); + break; + case 'settings': + client = await swos.openClient('push', '/settings/notifications', loginId); + break; + } } if (client) { client.focus(); } if (data.type === 'notification') { - api('notifications/mark-all-as-read', data.userId); + await swos.sendMarkAllAsRead(loginId); } notification.close(); @@ -140,9 +160,12 @@ globalThis.addEventListener('notificationclick', (ev: ServiceWorkerGlobalScopeEv globalThis.addEventListener('notificationclose', (ev: ServiceWorkerGlobalScopeEventMap['notificationclose']) => { const data: PushNotificationDataMap[keyof PushNotificationDataMap] = ev.notification.data; - if (data.type === 'notification') { - api('notifications/mark-all-as-read', data.userId); - } + ev.waitUntil((async () => { + if (data.type === 'notification') { + await swos.sendMarkAllAsRead(data.userId); + } + return; + })()); }); globalThis.addEventListener('message', (ev: ServiceWorkerGlobalScopeEventMap['message']) => { diff --git a/packages/sw/src/types.ts b/packages/sw/src/types.ts index 7b653e94b7..204ec6198d 100644 --- a/packages/sw/src/types.ts +++ b/packages/sw/src/types.ts @@ -17,6 +17,7 @@ type PushNotificationDataSourceMap = { antenna: { id: string, name: string }; note: Misskey.entities.Note; }; + readAllNotifications: undefined; }; export type PushNotificationData<K extends keyof PushNotificationDataSourceMap> = { @@ -37,6 +38,7 @@ export type BadgeNames = | 'at' | 'chart-arrows' | 'circle-check' + | 'medal' | 'messages' | 'plus' | 'quote' |