fix/enhance(sw): プッシュ通知 (バックグラウンドで開いている場合も通知, リアクション通知はノートにつき1つに) (#9977)

* fix(sw): クライアントがあってもpush notificationを無視しない
「プッシュ通知を更新しました」の原因になるため

* enhance(sw): リアクション通知は1つのノートにつき1つしか表示しない
Safari対応で、通知tagは能動的に閉じるように

* revert closeNotificationsByTags
This commit is contained in:
tamaina 2023-02-18 17:48:20 +09:00 committed by GitHub
parent 36170a11f5
commit 8c883653c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 15 deletions

View file

@ -10,6 +10,12 @@ import { getAccountFromId } from '@/scripts/get-account-from-id';
import { char2fileName } from '@/scripts/twemoji-base'; import { char2fileName } from '@/scripts/twemoji-base';
import * as url from '@/scripts/url'; import * as url from '@/scripts/url';
const closeNotificationsByTags = async (tags: string[]) => {
for (const n of (await Promise.all(tags.map(tag => globalThis.registration.getNotifications({ tag })))).flat()) {
n.close();
}
}
const iconUrl = (name: badgeNames) => `/static-assets/tabler-badges/${name}.png`; const iconUrl = (name: badgeNames) => `/static-assets/tabler-badges/${name}.png`;
/* How to add a new badge: /* How to add a new badge:
* 1. Find the icon and download png from https://tabler-icons.io/ * 1. Find the icon and download png from https://tabler-icons.io/
@ -161,6 +167,7 @@ async function composeNotification(data: pushNotificationDataMap[keyof pushNotif
badge = iconUrl('plus'); badge = iconUrl('plus');
} }
const tag = `reaction:${data.body.note.id}`;
return [`${reaction} ${getUserName(data.body.user)}`, { return [`${reaction} ${getUserName(data.body.user)}`, {
body: data.body.note.text ?? '', body: data.body.note.text ?? '',
icon: data.body.user.avatarUrl, icon: data.body.user.avatarUrl,
@ -176,10 +183,11 @@ async function composeNotification(data: pushNotificationDataMap[keyof pushNotif
} }
case 'pollEnded': case 'pollEnded':
const tag = `poll:${data.body.note.id}`;
return [t('_notification.pollEnded'), { return [t('_notification.pollEnded'), {
body: data.body.note.text || '', body: data.body.note.text || '',
badge: iconUrl('chart-arrows'), badge: iconUrl('chart-arrows'),
tag: `poll:${data.body.note.id}`, tag,
data, data,
}]; }];
@ -220,11 +228,12 @@ async function composeNotification(data: pushNotificationDataMap[keyof pushNotif
return null; return null;
} }
case 'unreadAntennaNote': case 'unreadAntennaNote':
const tag = `antenna:${data.body.antenna.id}`;
return [t('_notification.unreadAntennaNote', { name: data.body.antenna.name }), { return [t('_notification.unreadAntennaNote', { name: data.body.antenna.name }), {
body: `${getUserName(data.body.note.user)}: ${data.body.note.text ?? ''}`, body: `${getUserName(data.body.note.user)}: ${data.body.note.text ?? ''}`,
icon: data.body.note.user.avatarUrl, icon: data.body.note.user.avatarUrl,
badge: iconUrl('antenna'), badge: iconUrl('antenna'),
tag: `antenna:${data.body.antenna.id}`, tag,
data, data,
renotify: true, renotify: true,
}]; }];
@ -248,16 +257,11 @@ export async function createEmptyNotification() {
}, },
); );
res();
setTimeout(async () => { setTimeout(async () => {
for (const n of try {
[ await closeNotificationsByTags(['user_visible_auto_notification', 'read_notification']);
...(await globalThis.registration.getNotifications({ tag: 'user_visible_auto_notification' })), } finally {
...(await globalThis.registration.getNotifications({ tag: 'read_notification' })), res();
]
) {
n.close();
} }
}, 1000); }, 1000);
}); });

View file

@ -53,9 +53,6 @@ globalThis.addEventListener('push', ev => {
// 1日以上経過している場合は無視 // 1日以上経過している場合は無視
if ((new Date()).getTime() - data.dateTime > 1000 * 60 * 60 * 24) break; if ((new Date()).getTime() - data.dateTime > 1000 * 60 * 60 * 24) break;
// クライアントがあったらストリームに接続しているということなので通知しない
if (clients.length !== 0) break;
return createNotification(data); return createNotification(data);
case 'readAllNotifications': case 'readAllNotifications':
for (const n of await globalThis.registration.getNotifications()) { for (const n of await globalThis.registration.getNotifications()) {
@ -83,7 +80,8 @@ globalThis.addEventListener('push', ev => {
break; break;
} }
return createEmptyNotification(); await createEmptyNotification();
return;
})); }));
}); });