nanka iroiro
This commit is contained in:
parent
e0dc391cf6
commit
de472fdc79
|
@ -7,21 +7,21 @@ import { getNoteSummary } from '@/misc/get-note-summary';
|
||||||
import getUserName from '@/misc/get-user-name';
|
import getUserName from '@/misc/get-user-name';
|
||||||
import { swLang } from '@client/sw/lang';
|
import { swLang } from '@client/sw/lang';
|
||||||
import { I18n } from '@/misc/i18n';
|
import { I18n } from '@/misc/i18n';
|
||||||
import { pushNotificationData } from '@/types';
|
import { pushNotificationDataMap } from '@client/sw/types';
|
||||||
|
import { apiFetch } from './operations';
|
||||||
|
import { getAccountFromId } from '@client/scripts/get-account-from-id';
|
||||||
|
|
||||||
export async function createNotification(data: pushNotificationData) {
|
export async function createNotification<K extends keyof pushNotificationDataMap>(data: pushNotificationDataMap[K]) {
|
||||||
const n = await composeNotification(data);
|
const n = await composeNotification(data);
|
||||||
|
|
||||||
if (n) await self.registration.showNotification(...n);
|
if (n) await self.registration.showNotification(...n);
|
||||||
else await createEmptyNotification();
|
else await createEmptyNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function composeNotification(data: pushNotificationData): Promise<[string, NotificationOptions] | null | undefined> {
|
async function composeNotification<K extends keyof pushNotificationDataMap>(data: pushNotificationDataMap[K]): Promise<[string, NotificationOptions] | null | undefined> {
|
||||||
if (!swLang.i18n) swLang.fetchLocale();
|
if (!swLang.i18n) swLang.fetchLocale();
|
||||||
const i18n = await swLang.i18n as I18n<any>;
|
const i18n = await swLang.i18n as I18n<any>;
|
||||||
const { t } = i18n;
|
const { t } = i18n;
|
||||||
const { body } = data;
|
|
||||||
|
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
/*
|
/*
|
||||||
case 'driveFileCreated': // TODO (Server Side)
|
case 'driveFileCreated': // TODO (Server Side)
|
||||||
|
@ -32,13 +32,17 @@ async function composeNotification(data: pushNotificationData): Promise<[string,
|
||||||
}];
|
}];
|
||||||
*/
|
*/
|
||||||
case 'notification':
|
case 'notification':
|
||||||
switch (body.type) {
|
switch (data.body.type) {
|
||||||
case 'follow':
|
case 'follow':
|
||||||
|
// users/showの型定義をswos.apiへ当てはめるのが困難なのでapiFetch.requestを直接使用
|
||||||
|
const account = await getAccountFromId(data.userId);
|
||||||
|
if (!account) return null;
|
||||||
|
const userDetail = apiFetch.request('users/show', { userId: data.body.userId }, account?.token);
|
||||||
return [t('_notification.youWereFollowed'), {
|
return [t('_notification.youWereFollowed'), {
|
||||||
body: getUserName(body.user),
|
body: getUserName(data.body.user),
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
data,
|
data,
|
||||||
actions: [
|
actions: userDetail.isFollowing ? [] : [
|
||||||
{
|
{
|
||||||
action: 'follow',
|
action: 'follow',
|
||||||
title: t('_notification._actions.followBack')
|
title: t('_notification._actions.followBack')
|
||||||
|
@ -47,9 +51,9 @@ async function composeNotification(data: pushNotificationData): Promise<[string,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
case 'mention':
|
case 'mention':
|
||||||
return [t('_notification.youGotMention', { name: getUserName(body.user) }), {
|
return [t('_notification.youGotMention', { name: getUserName(data.body.user) }), {
|
||||||
body: getNoteSummary(body.note, i18n.locale),
|
body: getNoteSummary(data.body.note, i18n.locale),
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
data,
|
data,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
|
@ -60,9 +64,9 @@ async function composeNotification(data: pushNotificationData): Promise<[string,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
case 'reply':
|
case 'reply':
|
||||||
return [t('_notification.youGotReply', { name: getUserName(body.user) }), {
|
return [t('_notification.youGotReply', { name: getUserName(data.body.user) }), {
|
||||||
body: getNoteSummary(body.note, i18n.locale),
|
body: getNoteSummary(data.body.note, i18n.locale),
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
data,
|
data,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
|
@ -73,22 +77,22 @@ async function composeNotification(data: pushNotificationData): Promise<[string,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
case 'renote':
|
case 'renote':
|
||||||
return [t('_notification.youRenoted', { name: getUserName(body.user) }), {
|
return [t('_notification.youRenoted', { name: getUserName(data.body.user) }), {
|
||||||
body: getNoteSummary(body.note.renote, i18n.locale),
|
body: getNoteSummary(data.body.note.renote, i18n.locale),
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
data,
|
data,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
action: 'showUser',
|
action: 'showUser',
|
||||||
title: getUserName(body.user)
|
title: getUserName(data.body.user)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}];
|
}];
|
||||||
|
|
||||||
case 'quote':
|
case 'quote':
|
||||||
return [t('_notification.youGotQuote', { name: getUserName(body.user) }), {
|
return [t('_notification.youGotQuote', { name: getUserName(data.body.user) }), {
|
||||||
body: getNoteSummary(body.note, i18n.locale),
|
body: getNoteSummary(data.body.note, i18n.locale),
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
data,
|
data,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
|
@ -103,29 +107,29 @@ async function composeNotification(data: pushNotificationData): Promise<[string,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
case 'reaction':
|
case 'reaction':
|
||||||
return [`${body.reaction} ${getUserName(body.user)}`, {
|
return [`${data.body.reaction} ${getUserName(data.body.user)}`, {
|
||||||
body: getNoteSummary(body.note, i18n.locale),
|
body: getNoteSummary(data.body.note, i18n.locale),
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
data,
|
data,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
action: 'showUser',
|
action: 'showUser',
|
||||||
title: getUserName(body.user)
|
title: getUserName(data.body.user)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}];
|
}];
|
||||||
|
|
||||||
case 'pollVote':
|
case 'pollVote':
|
||||||
return [t('_notification.youGotPoll', { name: getUserName(body.user) }), {
|
return [t('_notification.youGotPoll', { name: getUserName(data.body.user) }), {
|
||||||
body: getNoteSummary(body.note, i18n.locale),
|
body: getNoteSummary(data.body.note, i18n.locale),
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
data,
|
data,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
case 'receiveFollowRequest':
|
case 'receiveFollowRequest':
|
||||||
return [t('_notification.youReceivedFollowRequest'), {
|
return [t('_notification.youReceivedFollowRequest'), {
|
||||||
body: getUserName(body.user),
|
body: getUserName(data.body.user),
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
data,
|
data,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
|
@ -141,14 +145,14 @@ async function composeNotification(data: pushNotificationData): Promise<[string,
|
||||||
|
|
||||||
case 'followRequestAccepted':
|
case 'followRequestAccepted':
|
||||||
return [t('_notification.yourFollowRequestAccepted'), {
|
return [t('_notification.yourFollowRequestAccepted'), {
|
||||||
body: getUserName(body.user),
|
body: getUserName(data.body.user),
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
data,
|
data,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
case 'groupInvited':
|
case 'groupInvited':
|
||||||
return [t('_notification.youWereInvitedToGroup', { userName: getUserName(body.user) }), {
|
return [t('_notification.youWereInvitedToGroup', { userName: getUserName(data.body.group) }), {
|
||||||
body: body.invitation.group.name,
|
body: data.body.invitation.group.name,
|
||||||
data,
|
data,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
|
@ -163,9 +167,9 @@ async function composeNotification(data: pushNotificationData): Promise<[string,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
case 'app':
|
case 'app':
|
||||||
return [body.header, {
|
return [data.body.header || data.body.body, {
|
||||||
body: body.body,
|
body: data.body.header && data.body.body,
|
||||||
icon: body.icon,
|
icon: data.body.icon,
|
||||||
data
|
data
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -173,17 +177,17 @@ async function composeNotification(data: pushNotificationData): Promise<[string,
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
case 'unreadMessagingMessage':
|
case 'unreadMessagingMessage':
|
||||||
if (body.groupId === null) {
|
if (data.body.groupId === null) {
|
||||||
return [t('_notification.youGotMessagingMessageFromUser', { name: getUserName(body.user) }), {
|
return [t('_notification.youGotMessagingMessageFromUser', { name: getUserName(data.body.user) }), {
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
tag: `messaging:user:${body.userId}`,
|
tag: `messaging:user:${data.body.userId}`,
|
||||||
data,
|
data,
|
||||||
renotify: true,
|
renotify: true,
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
return [t('_notification.youGotMessagingMessageFromGroup', { name: body.group.name }), {
|
return [t('_notification.youGotMessagingMessageFromGroup', { name: data.body.group.name }), {
|
||||||
icon: body.user.avatarUrl,
|
icon: data.body.user.avatarUrl,
|
||||||
tag: `messaging:group:${body.groupId}`,
|
tag: `messaging:group:${data.body.groupId}`,
|
||||||
data,
|
data,
|
||||||
renotify: true,
|
renotify: true,
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
declare var self: ServiceWorkerGlobalScope;
|
declare var self: ServiceWorkerGlobalScope;
|
||||||
|
|
||||||
import { get } from 'idb-keyval';
|
import { get } from 'idb-keyval';
|
||||||
import { pushNotificationData } from '../../types';
|
import { pushNotificationDataMap } from '@client/sw/types';
|
||||||
import { api } from './operations';
|
import { api } from './operations';
|
||||||
|
|
||||||
type Accounts = {
|
type Accounts = {
|
||||||
|
@ -30,7 +30,7 @@ class SwNotificationReadManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// プッシュ通知の既読をサーバーに送信
|
// プッシュ通知の既読をサーバーに送信
|
||||||
public async read(data: pushNotificationData) {
|
public async read<K extends keyof pushNotificationDataMap>(data: pushNotificationDataMap[K]) {
|
||||||
if (data.type !== 'notification' || !(data.userId in this.accounts)) return;
|
if (data.type !== 'notification' || !(data.userId in this.accounts)) return;
|
||||||
|
|
||||||
const account = this.accounts[data.userId];
|
const account = this.accounts[data.userId];
|
||||||
|
|
|
@ -4,29 +4,19 @@
|
||||||
*/
|
*/
|
||||||
declare var self: ServiceWorkerGlobalScope;
|
declare var self: ServiceWorkerGlobalScope;
|
||||||
|
|
||||||
|
import * as Misskey from 'misskey-js';
|
||||||
import { SwMessage, swMessageOrderType } from './types';
|
import { SwMessage, swMessageOrderType } from './types';
|
||||||
import { getAcct } from '@/misc/acct';
|
import { getAcct } from '@/misc/acct';
|
||||||
import { getAccountFromId } from '@client/scripts/get-account-from-id';
|
import { getAccountFromId } from '@client/scripts/get-account-from-id';
|
||||||
import { appendLoginId } from '@client/scripts/login-id';
|
import { appendLoginId } from '@client/scripts/login-id';
|
||||||
|
|
||||||
export async function api(endpoint: string, userId: string, options: any = {}) {
|
export const apiFetch = new Misskey.api.APIClient({ origin, fetch });
|
||||||
|
|
||||||
|
export async function api<E extends keyof Misskey.Endpoints>(endpoint: E, userId: string, options?: Misskey.Endpoints[E]['req']) {
|
||||||
const account = await getAccountFromId(userId);
|
const account = await getAccountFromId(userId);
|
||||||
if (!account) return;
|
if (!account) return;
|
||||||
|
|
||||||
return fetch(`${origin}/api/${endpoint}`, {
|
return apiFetch.request(endpoint, options, account.token);
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
i: account.token,
|
|
||||||
...options
|
|
||||||
}),
|
|
||||||
credentials: 'omit',
|
|
||||||
cache: 'no-cache',
|
|
||||||
}).then(async res => {
|
|
||||||
if (!res.ok) Error(`Error while fetching: ${await res.text()}`);
|
|
||||||
|
|
||||||
if (res.status === 200) return res.json();
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// rendered acctからユーザーを開く
|
// rendered acctからユーザーを開く
|
||||||
|
@ -59,14 +49,7 @@ export async function openPost(options: any, loginId: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 self.clients.matchAll({
|
const client = await findClient();
|
||||||
type: 'window'
|
|
||||||
}).then(clients => {
|
|
||||||
for (const c of clients) {
|
|
||||||
if (c.url.indexOf('?zen') < 0) return c;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (client) {
|
if (client) {
|
||||||
client.postMessage({ type: 'order', ...query, order, loginId, url } as SwMessage);
|
client.postMessage({ type: 'order', ...query, order, loginId, url } as SwMessage);
|
||||||
|
@ -75,3 +58,13 @@ export async function openClient(order: swMessageOrderType, url: string, loginId
|
||||||
|
|
||||||
return self.clients.openWindow(appendLoginId(url, loginId));
|
return self.clients.openWindow(appendLoginId(url, loginId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function findClient() {
|
||||||
|
const clients = await self.clients.matchAll({
|
||||||
|
type: 'window'
|
||||||
|
});
|
||||||
|
for (const c of clients) {
|
||||||
|
if (c.url.indexOf('?zen') < 0) return c;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ declare var self: ServiceWorkerGlobalScope;
|
||||||
import { createEmptyNotification, createNotification } from '@client/sw/create-notification';
|
import { createEmptyNotification, createNotification } from '@client/sw/create-notification';
|
||||||
import { swLang } from '@client/sw/lang';
|
import { swLang } from '@client/sw/lang';
|
||||||
import { swNotificationRead } from '@client/sw/notification-read';
|
import { swNotificationRead } from '@client/sw/notification-read';
|
||||||
import { pushNotificationData } from '@/types';
|
import { pushNotificationDataMap } from '@client/sw/types';
|
||||||
import * as ope from './operations';
|
import * as swos from './operations';
|
||||||
import { getAcct } from '@/misc/acct';
|
import { getAcct } from '@/misc/acct';
|
||||||
|
|
||||||
//#region Lifecycle: Install
|
//#region Lifecycle: Install
|
||||||
|
@ -45,11 +45,11 @@ self.addEventListener('push', ev => {
|
||||||
ev.waitUntil(self.clients.matchAll({
|
ev.waitUntil(self.clients.matchAll({
|
||||||
includeUncontrolled: true,
|
includeUncontrolled: true,
|
||||||
type: 'window'
|
type: 'window'
|
||||||
}).then(async clients => {
|
}).then(async <K extends keyof pushNotificationDataMap>(clients: readonly WindowClient[]) => {
|
||||||
// // クライアントがあったらストリームに接続しているということなので通知しない
|
// // クライアントがあったらストリームに接続しているということなので通知しない
|
||||||
// if (clients.length != 0) return;
|
// if (clients.length != 0) return;
|
||||||
|
|
||||||
const data: pushNotificationData = ev.data?.json();
|
const data: pushNotificationDataMap[K] = ev.data?.json();
|
||||||
|
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
// case 'driveFileCreated':
|
// case 'driveFileCreated':
|
||||||
|
@ -103,7 +103,7 @@ self.addEventListener('push', ev => {
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Notification
|
//#region Notification
|
||||||
self.addEventListener('notificationclick', ev => {
|
self.addEventListener('notificationclick', <K extends keyof pushNotificationDataMap>(ev: NotificationEvent) => {
|
||||||
ev.waitUntil((async () => {
|
ev.waitUntil((async () => {
|
||||||
|
|
||||||
if (_DEV_) {
|
if (_DEV_) {
|
||||||
|
@ -111,85 +111,90 @@ self.addEventListener('notificationclick', ev => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const { action, notification } = ev;
|
const { action, notification } = ev;
|
||||||
const data: pushNotificationData = notification.data;
|
const data: pushNotificationDataMap[K] = notification.data;
|
||||||
const { type, userId: id, body } = data;
|
const { userId: id } = data;
|
||||||
let client: WindowClient | null = null;
|
let client: WindowClient | null = null;
|
||||||
let close = true;
|
|
||||||
|
|
||||||
|
switch (data.type) {
|
||||||
|
case 'notification':
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'follow':
|
case 'follow':
|
||||||
client = await ope.api('following/create', id, { userId: body.userId });
|
await swos.api('following/create', id, { userId: data.body.userId });
|
||||||
break;
|
break;
|
||||||
case 'showUser':
|
case 'showUser':
|
||||||
client = await ope.openUser(getAcct(body.user), id);
|
if ('user' in data.body) client = await swos.openUser(getAcct(data.body.user), id);
|
||||||
if (body.type !== 'renote') close = false;
|
|
||||||
break;
|
break;
|
||||||
case 'reply':
|
case 'reply':
|
||||||
client = await ope.openPost({ reply: body.note }, id);
|
if ('note' in data.body) client = await swos.openPost({ reply: data.body.note }, id);
|
||||||
break;
|
break;
|
||||||
case 'renote':
|
case 'renote':
|
||||||
await ope.api('notes/create', id, { renoteId: body.note.id });
|
if ('note' in data.body) await swos.api('notes/create', id, { renoteId: data.body.note.id });
|
||||||
break;
|
break;
|
||||||
case 'accept':
|
case 'accept':
|
||||||
if (body.type === 'receiveFollowRequest') {
|
switch (data.body.type) {
|
||||||
await ope.api('following/requests/accept', id, { userId: body.userId });
|
case 'receiveFollowRequest':
|
||||||
} else if (body.type === 'groupInvited') {
|
await swos.api('following/requests/accept', id, { userId: data.body.userId });
|
||||||
await ope.api('users/groups/invitations/accept', id, { invitationId: body.invitation.id });
|
break;
|
||||||
|
case 'groupInvited':
|
||||||
|
await swos.api('users/groups/invitations/accept', id, { invitationId: data.body.invitation.id });
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'reject':
|
case 'reject':
|
||||||
if (body.type === 'receiveFollowRequest') {
|
switch (data.body.type) {
|
||||||
await ope.api('following/requests/reject', id, { userId: body.userId });
|
case 'receiveFollowRequest':
|
||||||
} else if (body.type === 'groupInvited') {
|
await swos.api('following/requests/reject', id, { userId: data.body.userId });
|
||||||
await ope.api('users/groups/invitations/reject', id, { invitationId: body.invitation.id });
|
break;
|
||||||
|
case 'groupInvited':
|
||||||
|
await swos.api('users/groups/invitations/reject', id, { invitationId: data.body.invitation.id });
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'showFollowRequests':
|
case 'showFollowRequests':
|
||||||
client = await ope.openClient('push', '/my/follow-requests', id);
|
client = await swos.openClient('push', '/my/follow-requests', id);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (type === 'unreadMessagingMessage') {
|
switch (data.body.type) {
|
||||||
client = await ope.openChat(body, id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (body.type) {
|
|
||||||
case 'receiveFollowRequest':
|
case 'receiveFollowRequest':
|
||||||
client = await ope.openClient('push', '/my/follow-requests', id);
|
client = await swos.openClient('push', '/my/follow-requests', id);
|
||||||
break;
|
break;
|
||||||
case 'groupInvited':
|
case 'groupInvited':
|
||||||
client = await ope.openClient('push', '/my/groups', id);
|
client = await swos.openClient('push', '/my/groups', id);
|
||||||
break;
|
break;
|
||||||
case 'reaction':
|
case 'reaction':
|
||||||
client = await ope.openNote(body.note.id, id);
|
client = await swos.openNote(data.body.note.id, id);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if ('note' in body) {
|
if ('note' in data.body) {
|
||||||
client = await ope.openNote(body.note.id, id);
|
client = await swos.openNote(data.body.note.id, id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ('user' in body) {
|
if ('user' in data.body) {
|
||||||
client = await ope.openUser(getAcct(body.data.user), id);
|
client = await swos.openUser(getAcct(data.body.user), id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 'unreadMessagingMessage':
|
||||||
|
client = await swos.openChat(data.body, id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (client) {
|
if (client) {
|
||||||
client.focus();
|
client.focus();
|
||||||
}
|
}
|
||||||
if (type === 'notification') {
|
if (data.type === 'notification') {
|
||||||
swNotificationRead.then(that => that.read(data));
|
swNotificationRead.then(that => that.read(data));
|
||||||
}
|
}
|
||||||
if (close) {
|
|
||||||
notification.close();
|
notification.close();
|
||||||
}
|
|
||||||
|
|
||||||
})());
|
})());
|
||||||
});
|
});
|
||||||
|
|
||||||
self.addEventListener('notificationclose', ev => {
|
self.addEventListener('notificationclose', <K extends keyof pushNotificationDataMap>(ev: NotificationEvent) => {
|
||||||
const data: pushNotificationData = ev.notification.data;
|
const data: pushNotificationDataMap[K] = ev.notification.data;
|
||||||
|
|
||||||
if (data.type === 'notification') {
|
if (data.type === 'notification') {
|
||||||
swNotificationRead.then(that => that.read(data));
|
swNotificationRead.then(that => that.read(data));
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import * as Misskey from 'misskey-js';
|
||||||
|
|
||||||
export type swMessageOrderType = 'post' | 'push';
|
export type swMessageOrderType = 'post' | 'push';
|
||||||
|
|
||||||
export type SwMessage = {
|
export type SwMessage = {
|
||||||
|
@ -7,3 +9,23 @@ export type SwMessage = {
|
||||||
url: string;
|
url: string;
|
||||||
[x: string]: any;
|
[x: string]: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Defined also @/services/push-notification.ts#L7-L14
|
||||||
|
type pushNotificationDataSourceMap = {
|
||||||
|
notification: Misskey.entities.Notification;
|
||||||
|
unreadMessagingMessage: Misskey.entities.MessagingMessage;
|
||||||
|
readNotifications: { notificationIds: string[] };
|
||||||
|
readAllNotifications: undefined;
|
||||||
|
readAllMessagingMessages: undefined;
|
||||||
|
readAllMessagingMessagesOfARoom: { userId: string } | { groupId: string };
|
||||||
|
};
|
||||||
|
|
||||||
|
export type pushNotificationData<K extends keyof pushNotificationDataSourceMap> = {
|
||||||
|
type: K;
|
||||||
|
body: pushNotificationDataSourceMap[K];
|
||||||
|
userId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type pushNotificationDataMap = {
|
||||||
|
[K in keyof pushNotificationDataSourceMap]: pushNotificationData<K>;
|
||||||
|
};
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { User } from '@/models/entities/user';
|
export default function(user: { name?: string | null, username: string }): string {
|
||||||
|
|
||||||
export default function(user: User): string {
|
|
||||||
return user.name || user.username;
|
return user.name || user.username;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ import config from '@/config/index';
|
||||||
import { SwSubscriptions } from '@/models/index';
|
import { SwSubscriptions } from '@/models/index';
|
||||||
import { fetchMeta } from '@/misc/fetch-meta';
|
import { fetchMeta } from '@/misc/fetch-meta';
|
||||||
import { Packed } from '@/misc/schema';
|
import { Packed } from '@/misc/schema';
|
||||||
import { pushNotificationData } from '@/types';
|
|
||||||
|
|
||||||
|
// Defined also @client/sw/types.ts#L14-L21
|
||||||
type pushNotificationsTypes = {
|
type pushNotificationsTypes = {
|
||||||
'notification': Packed<'Notification'>;
|
'notification': Packed<'Notification'>;
|
||||||
'unreadMessagingMessage': Packed<'MessagingMessage'>;
|
'unreadMessagingMessage': Packed<'MessagingMessage'>;
|
||||||
|
@ -40,7 +40,7 @@ export async function pushNotification<T extends keyof pushNotificationsTypes>(u
|
||||||
|
|
||||||
push.sendNotification(pushSubscription, JSON.stringify({
|
push.sendNotification(pushSubscription, JSON.stringify({
|
||||||
type, body, userId
|
type, body, userId
|
||||||
} as pushNotificationData), {
|
}), {
|
||||||
proxy: config.proxy
|
proxy: config.proxy
|
||||||
}).catch((err: any) => {
|
}).catch((err: any) => {
|
||||||
//swLogger.info(err.statusCode);
|
//swLogger.info(err.statusCode);
|
||||||
|
|
17
src/types.ts
17
src/types.ts
|
@ -3,20 +3,3 @@ export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote
|
||||||
export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const;
|
export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const;
|
||||||
|
|
||||||
export const mutedNoteReasons = ['word', 'manual', 'spam', 'other'] as const;
|
export const mutedNoteReasons = ['word', 'manual', 'spam', 'other'] as const;
|
||||||
|
|
||||||
export type pushNotificationData = {
|
|
||||||
type: 'notification' | 'unreadMessagingMessage' | 'readNotifications' | 'readAllMessagingMessagesOfARoom' | 'readAllNotifications' | 'readAllMessagingMessages';
|
|
||||||
body: {
|
|
||||||
[x: string]: any;
|
|
||||||
id?: string;
|
|
||||||
type?: typeof notificationTypes[number];
|
|
||||||
notificationIds?: string[];
|
|
||||||
user?: any;
|
|
||||||
userId?: string | null;
|
|
||||||
note?: any;
|
|
||||||
choice?: number;
|
|
||||||
reaction?: string;
|
|
||||||
invitation?: any;
|
|
||||||
};
|
|
||||||
userId: string;
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue