Improve ServiceWorker notification
This commit is contained in:
parent
b0408d1d6e
commit
87fc6522fb
|
@ -20,34 +20,6 @@ export default function(type, data): Notification {
|
||||||
icon: data.url + '?thumbnail&size=64'
|
icon: data.url + '?thumbnail&size=64'
|
||||||
};
|
};
|
||||||
|
|
||||||
case 'mention':
|
|
||||||
return {
|
|
||||||
title: `${getUserName(data.user)}さんから:`,
|
|
||||||
body: getNoteSummary(data),
|
|
||||||
icon: data.user.avatarUrl + '?thumbnail&size=64'
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'reply':
|
|
||||||
return {
|
|
||||||
title: `${getUserName(data.user)}さんから返信:`,
|
|
||||||
body: getNoteSummary(data),
|
|
||||||
icon: data.user.avatarUrl + '?thumbnail&size=64'
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'quote':
|
|
||||||
return {
|
|
||||||
title: `${getUserName(data.user)}さんが引用:`,
|
|
||||||
body: getNoteSummary(data),
|
|
||||||
icon: data.user.avatarUrl + '?thumbnail&size=64'
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'reaction':
|
|
||||||
return {
|
|
||||||
title: `${getUserName(data.user)}: ${getReactionEmoji(data.reaction)}:`,
|
|
||||||
body: getNoteSummary(data.note),
|
|
||||||
icon: data.user.avatarUrl + '?thumbnail&size=64'
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'unread_messaging_message':
|
case 'unread_messaging_message':
|
||||||
return {
|
return {
|
||||||
title: `${getUserName(data.user)}さんからメッセージ:`,
|
title: `${getUserName(data.user)}さんからメッセージ:`,
|
||||||
|
@ -62,6 +34,40 @@ export default function(type, data): Notification {
|
||||||
icon: data.parent.avatarUrl + '?thumbnail&size=64'
|
icon: data.parent.avatarUrl + '?thumbnail&size=64'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case 'notification':
|
||||||
|
switch (data.type) {
|
||||||
|
case 'mention':
|
||||||
|
return {
|
||||||
|
title: `${getUserName(data.user)}さんから:`,
|
||||||
|
body: getNoteSummary(data),
|
||||||
|
icon: data.user.avatarUrl + '?thumbnail&size=64'
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'reply':
|
||||||
|
return {
|
||||||
|
title: `${getUserName(data.user)}さんから返信:`,
|
||||||
|
body: getNoteSummary(data),
|
||||||
|
icon: data.user.avatarUrl + '?thumbnail&size=64'
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'quote':
|
||||||
|
return {
|
||||||
|
title: `${getUserName(data.user)}さんが引用:`,
|
||||||
|
body: getNoteSummary(data),
|
||||||
|
icon: data.user.avatarUrl + '?thumbnail&size=64'
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'reaction':
|
||||||
|
return {
|
||||||
|
title: `${getUserName(data.user)}: ${getReactionEmoji(data.reaction)}:`,
|
||||||
|
body: getNoteSummary(data.note),
|
||||||
|
icon: data.user.avatarUrl + '?thumbnail&size=64'
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,6 +115,15 @@ function registerNotifications(stream: HomeStreamManager) {
|
||||||
});
|
});
|
||||||
|
|
||||||
function attach(connection) {
|
function attach(connection) {
|
||||||
|
connection.on('notification', notification => {
|
||||||
|
const _n = composeNotification('notification', notification);
|
||||||
|
const n = new Notification(_n.title, {
|
||||||
|
body: _n.body,
|
||||||
|
icon: _n.icon
|
||||||
|
});
|
||||||
|
setTimeout(n.close.bind(n), 6000);
|
||||||
|
});
|
||||||
|
|
||||||
connection.on('drive_file_created', file => {
|
connection.on('drive_file_created', file => {
|
||||||
const _n = composeNotification('drive_file_created', file);
|
const _n = composeNotification('drive_file_created', file);
|
||||||
const n = new Notification(_n.title, {
|
const n = new Notification(_n.title, {
|
||||||
|
@ -124,33 +133,6 @@ function registerNotifications(stream: HomeStreamManager) {
|
||||||
setTimeout(n.close.bind(n), 5000);
|
setTimeout(n.close.bind(n), 5000);
|
||||||
});
|
});
|
||||||
|
|
||||||
connection.on('mention', note => {
|
|
||||||
const _n = composeNotification('mention', note);
|
|
||||||
const n = new Notification(_n.title, {
|
|
||||||
body: _n.body,
|
|
||||||
icon: _n.icon
|
|
||||||
});
|
|
||||||
setTimeout(n.close.bind(n), 6000);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.on('reply', note => {
|
|
||||||
const _n = composeNotification('reply', note);
|
|
||||||
const n = new Notification(_n.title, {
|
|
||||||
body: _n.body,
|
|
||||||
icon: _n.icon
|
|
||||||
});
|
|
||||||
setTimeout(n.close.bind(n), 6000);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.on('quote', note => {
|
|
||||||
const _n = composeNotification('quote', note);
|
|
||||||
const n = new Notification(_n.title, {
|
|
||||||
body: _n.body,
|
|
||||||
icon: _n.icon
|
|
||||||
});
|
|
||||||
setTimeout(n.close.bind(n), 6000);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.on('unread_messaging_message', message => {
|
connection.on('unread_messaging_message', message => {
|
||||||
const _n = composeNotification('unread_messaging_message', message);
|
const _n = composeNotification('unread_messaging_message', message);
|
||||||
const n = new Notification(_n.title, {
|
const n = new Notification(_n.title, {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Mute from '../models/mute';
|
||||||
import { pack } from '../models/notification';
|
import { pack } from '../models/notification';
|
||||||
import stream from './stream';
|
import stream from './stream';
|
||||||
import User from '../models/user';
|
import User from '../models/user';
|
||||||
|
import pushSw from '../publishers/push-sw';
|
||||||
|
|
||||||
export default (
|
export default (
|
||||||
notifiee: mongo.ObjectID,
|
notifiee: mongo.ObjectID,
|
||||||
|
@ -26,9 +27,10 @@ export default (
|
||||||
|
|
||||||
resolve(notification);
|
resolve(notification);
|
||||||
|
|
||||||
|
const packed = await pack(notification);
|
||||||
|
|
||||||
// Publish notification event
|
// Publish notification event
|
||||||
stream(notifiee, 'notification',
|
stream(notifiee, 'notification', packed);
|
||||||
await pack(notification));
|
|
||||||
|
|
||||||
// Update flag
|
// Update flag
|
||||||
User.update({ _id: notifiee }, {
|
User.update({ _id: notifiee }, {
|
||||||
|
@ -52,7 +54,9 @@ export default (
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
stream(notifiee, 'unread_notification', await pack(notification));
|
stream(notifiee, 'unread_notification', packed);
|
||||||
|
|
||||||
|
pushSw(notifiee, 'notification', packed);
|
||||||
}
|
}
|
||||||
}, 3000);
|
}, 3000);
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,6 @@ import notify from '../../publishers/notify';
|
||||||
import NoteWatching from '../../models/note-watching';
|
import NoteWatching from '../../models/note-watching';
|
||||||
import watch from './watch';
|
import watch from './watch';
|
||||||
import Mute from '../../models/mute';
|
import Mute from '../../models/mute';
|
||||||
import pushSw from '../../publishers/push-sw';
|
|
||||||
import event from '../../publishers/stream';
|
import event from '../../publishers/stream';
|
||||||
import parse from '../../mfm/parse';
|
import parse from '../../mfm/parse';
|
||||||
import { IApp } from '../../models/app';
|
import { IApp } from '../../models/app';
|
||||||
|
@ -20,56 +19,56 @@ import UserList from '../../models/user-list';
|
||||||
import resolveUser from '../../remote/resolve-user';
|
import resolveUser from '../../remote/resolve-user';
|
||||||
import Meta from '../../models/meta';
|
import Meta from '../../models/meta';
|
||||||
|
|
||||||
type Reason = 'reply' | 'quote' | 'mention';
|
type Type = 'reply' | 'renote' | 'quote' | 'mention';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServiceWorkerへの通知を担当
|
* 通知を担当
|
||||||
*/
|
*/
|
||||||
class NotificationManager {
|
class NotificationManager {
|
||||||
private user: IUser;
|
private notifier: IUser;
|
||||||
private note: any;
|
private note: any;
|
||||||
private list: Array<{
|
private queue: Array<{
|
||||||
user: ILocalUser['_id'],
|
notifiee: ILocalUser['_id'],
|
||||||
reason: Reason;
|
type: Type;
|
||||||
}> = [];
|
}> = [];
|
||||||
|
|
||||||
constructor(user: IUser, note: any) {
|
constructor(notifier: IUser, note: any) {
|
||||||
this.user = user;
|
this.notifier = notifier;
|
||||||
this.note = note;
|
this.note = note;
|
||||||
}
|
}
|
||||||
|
|
||||||
public push(user: ILocalUser['_id'], reason: Reason) {
|
public push(notifiee: ILocalUser['_id'], type: Type) {
|
||||||
// 自分自身へは通知しない
|
// 自分自身へは通知しない
|
||||||
if (this.user._id.equals(user)) return;
|
if (this.notifier._id.equals(notifiee)) return;
|
||||||
|
|
||||||
const exist = this.list.find(x => x.user.equals(user));
|
const exist = this.queue.find(x => x.notifiee.equals(notifiee));
|
||||||
|
|
||||||
if (exist) {
|
if (exist) {
|
||||||
// 「メンションされているかつ返信されている」場合は、メンションとしての通知ではなく返信としての通知にする
|
// 「メンションされているかつ返信されている」場合は、メンションとしての通知ではなく返信としての通知にする
|
||||||
if (reason != 'mention') {
|
if (type != 'mention') {
|
||||||
exist.reason = reason;
|
exist.type = type;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.list.push({
|
this.queue.push({
|
||||||
user, reason
|
notifiee, type
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public deliver() {
|
public deliver() {
|
||||||
this.list.forEach(async x => {
|
this.queue.forEach(async x => {
|
||||||
const mentionee = x.user;
|
|
||||||
|
|
||||||
// ミュート情報を取得
|
// ミュート情報を取得
|
||||||
const mentioneeMutes = await Mute.find({
|
const mentioneeMutes = await Mute.find({
|
||||||
muterId: mentionee
|
muterId: x.notifiee
|
||||||
});
|
});
|
||||||
|
|
||||||
const mentioneesMutedUserIds = mentioneeMutes.map(m => m.muteeId.toString());
|
const mentioneesMutedUserIds = mentioneeMutes.map(m => m.muteeId.toString());
|
||||||
|
|
||||||
// 通知される側のユーザーが通知する側のユーザーをミュートしていない限りは通知する
|
// 通知される側のユーザーが通知する側のユーザーをミュートしていない限りは通知する
|
||||||
if (!mentioneesMutedUserIds.includes(this.user._id.toString())) {
|
if (!mentioneesMutedUserIds.includes(this.notifier._id.toString())) {
|
||||||
pushSw(mentionee, x.reason, this.note);
|
notify(x.notifiee, this.notifier._id, x.type, {
|
||||||
|
noteId: this.note._id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -264,10 +263,6 @@ export default async (user: IUser, data: {
|
||||||
if (data.renote && data.renote.userId.equals(u._id)) return;
|
if (data.renote && data.renote.userId.equals(u._id)) return;
|
||||||
|
|
||||||
// Create notification
|
// Create notification
|
||||||
notify(u._id, user._id, 'mention', {
|
|
||||||
noteId: note._id
|
|
||||||
});
|
|
||||||
|
|
||||||
nm.push(u._id, 'mention');
|
nm.push(u._id, 'mention');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -371,11 +366,6 @@ export default async (user: IUser, data: {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// (自分自身へのリプライでない限りは)通知を作成
|
|
||||||
notify(data.reply.userId, user._id, 'reply', {
|
|
||||||
noteId: note._id
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fetch watchers
|
// Fetch watchers
|
||||||
NoteWatching.find({
|
NoteWatching.find({
|
||||||
noteId: data.reply._id,
|
noteId: data.reply._id,
|
||||||
|
@ -388,9 +378,7 @@ export default async (user: IUser, data: {
|
||||||
}
|
}
|
||||||
}).then(watchers => {
|
}).then(watchers => {
|
||||||
watchers.forEach(watcher => {
|
watchers.forEach(watcher => {
|
||||||
notify(watcher.userId, user._id, 'reply', {
|
nm.push(watcher.userId, 'reply');
|
||||||
noteId: note._id
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -399,6 +387,7 @@ export default async (user: IUser, data: {
|
||||||
watch(user._id, data.reply);
|
watch(user._id, data.reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (自分自身へのリプライでない限りは)通知を作成
|
||||||
nm.push(data.reply.userId, 'reply');
|
nm.push(data.reply.userId, 'reply');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,9 +395,7 @@ export default async (user: IUser, data: {
|
||||||
if (data.renote) {
|
if (data.renote) {
|
||||||
// Notify
|
// Notify
|
||||||
const type = data.text ? 'quote' : 'renote';
|
const type = data.text ? 'quote' : 'renote';
|
||||||
notify(data.renote.userId, user._id, type, {
|
nm.push(data.renote.userId, type);
|
||||||
noteId: note._id
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fetch watchers
|
// Fetch watchers
|
||||||
NoteWatching.find({
|
NoteWatching.find({
|
||||||
|
@ -420,9 +407,7 @@ export default async (user: IUser, data: {
|
||||||
}
|
}
|
||||||
}).then(watchers => {
|
}).then(watchers => {
|
||||||
watchers.forEach(watcher => {
|
watchers.forEach(watcher => {
|
||||||
notify(watcher.userId, user._id, type, {
|
nm.push(watcher.userId, type);
|
||||||
noteId: note._id
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { IUser, pack as packUser, isLocalUser, isRemoteUser } from '../../../models/user';
|
import { IUser, isLocalUser, isRemoteUser } from '../../../models/user';
|
||||||
import Note, { INote, pack as packNote } from '../../../models/note';
|
import Note, { INote } from '../../../models/note';
|
||||||
import NoteReaction from '../../../models/note-reaction';
|
import NoteReaction from '../../../models/note-reaction';
|
||||||
import { publishNoteStream } from '../../../publishers/stream';
|
import { publishNoteStream } from '../../../publishers/stream';
|
||||||
import notify from '../../../publishers/notify';
|
import notify from '../../../publishers/notify';
|
||||||
import pushSw from '../../../publishers/push-sw';
|
|
||||||
import NoteWatching from '../../../models/note-watching';
|
import NoteWatching from '../../../models/note-watching';
|
||||||
import watch from '../watch';
|
import watch from '../watch';
|
||||||
import renderLike from '../../../remote/activitypub/renderer/like';
|
import renderLike from '../../../remote/activitypub/renderer/like';
|
||||||
|
@ -54,12 +53,6 @@ export default async (user: IUser, note: INote, reaction: string) => new Promise
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pushSw(note.userId, 'reaction', {
|
|
||||||
user: await packUser(user, note.userId),
|
|
||||||
note: await packNote(note, note.userId),
|
|
||||||
reaction: reaction
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fetch watchers
|
// Fetch watchers
|
||||||
NoteWatching
|
NoteWatching
|
||||||
.find({
|
.find({
|
||||||
|
|
Loading…
Reference in New Issue