fix/enhance(sw): プッシュ通知 (バックグラウンドで開いている場合も通知, リアクション通知はノートにつき1つに) (#9977)
* fix(sw): クライアントがあってもpush notificationを無視しない 「プッシュ通知を更新しました」の原因になるため * enhance(sw): リアクション通知は1つのノートにつき1つしか表示しない Safari対応で、通知tagは能動的に閉じるように * revert closeNotificationsByTags
This commit is contained in:
parent
36170a11f5
commit
8c883653c9
2 changed files with 17 additions and 15 deletions
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue