Improve ServiceWorker notification
This commit is contained in:
		
							parent
							
								
									b0408d1d6e
								
							
						
					
					
						commit
						87fc6522fb
					
				
					 5 changed files with 77 additions and 107 deletions
				
			
		| 
						 | 
					@ -20,6 +20,22 @@ export default function(type, data): Notification {
 | 
				
			||||||
				icon: data.url + '?thumbnail&size=64'
 | 
									icon: data.url + '?thumbnail&size=64'
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 'unread_messaging_message':
 | 
				
			||||||
 | 
								return {
 | 
				
			||||||
 | 
									title: `${getUserName(data.user)}さんからメッセージ:`,
 | 
				
			||||||
 | 
									body: data.text, // TODO: getMessagingMessageSummary(data),
 | 
				
			||||||
 | 
									icon: data.user.avatarUrl + '?thumbnail&size=64'
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 'reversi_invited':
 | 
				
			||||||
 | 
								return {
 | 
				
			||||||
 | 
									title: '対局への招待があります',
 | 
				
			||||||
 | 
									body: `${getUserName(data.parent)}さんから`,
 | 
				
			||||||
 | 
									icon: data.parent.avatarUrl + '?thumbnail&size=64'
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 'notification':
 | 
				
			||||||
 | 
								switch (data.type) {
 | 
				
			||||||
				case 'mention':
 | 
									case 'mention':
 | 
				
			||||||
					return {
 | 
										return {
 | 
				
			||||||
						title: `${getUserName(data.user)}さんから:`,
 | 
											title: `${getUserName(data.user)}さんから:`,
 | 
				
			||||||
| 
						 | 
					@ -48,19 +64,9 @@ export default function(type, data): Notification {
 | 
				
			||||||
						icon: data.user.avatarUrl + '?thumbnail&size=64'
 | 
											icon: data.user.avatarUrl + '?thumbnail&size=64'
 | 
				
			||||||
					};
 | 
										};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case 'unread_messaging_message':
 | 
									default:
 | 
				
			||||||
			return {
 | 
										return null;
 | 
				
			||||||
				title: `${getUserName(data.user)}さんからメッセージ:`,
 | 
								}
 | 
				
			||||||
				body: data.text, // TODO: getMessagingMessageSummary(data),
 | 
					 | 
				
			||||||
				icon: data.user.avatarUrl + '?thumbnail&size=64'
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case 'reversi_invited':
 | 
					 | 
				
			||||||
			return {
 | 
					 | 
				
			||||||
				title: '対局への招待があります',
 | 
					 | 
				
			||||||
				body: `${getUserName(data.parent)}さんから`,
 | 
					 | 
				
			||||||
				icon: data.parent.avatarUrl + '?thumbnail&size=64'
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		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…
	
	Add table
		Add a link
		
	
		Reference in a new issue