summaryrefslogtreecommitdiff
path: root/packages/backend/src/services/note/unread.ts
blob: d9ed711e03f370ad63c0871e9ccb1e5c02984a0e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { Note } from '@/models/entities/note.js';
import { publishMainStream } from '@/services/stream.js';
import { User } from '@/models/entities/user.js';
import { Mutings, NoteThreadMutings, NoteUnreads } from '@/models/index.js';
import { genId } from '@/misc/gen-id.js';

export async function insertNoteUnread(userId: User['id'], note: Note, params: {
	// NOTE: isSpecifiedがtrueならisMentionedは必ずfalse
	isSpecified: boolean;
	isMentioned: boolean;
}) {
	//#region ミュートしているなら無視
	// TODO: 現在の仕様ではChannelにミュートは適用されないのでよしなにケアする
	const mute = await Mutings.findBy({
		muterId: userId,
	});
	if (mute.map(m => m.muteeId).includes(note.userId)) return;
	//#endregion

	// スレッドミュート
	const threadMute = await NoteThreadMutings.findOneBy({
		userId: userId,
		threadId: note.threadId || note.id,
	});
	if (threadMute) return;

	const unread = {
		id: genId(),
		noteId: note.id,
		userId: userId,
		isSpecified: params.isSpecified,
		isMentioned: params.isMentioned,
		noteChannelId: note.channelId,
		noteUserId: note.userId,
	};

	await NoteUnreads.insert(unread);

	// 2秒経っても既読にならなかったら「未読の投稿がありますよ」イベントを発行する
	setTimeout(async () => {
		const exist = await NoteUnreads.findOneBy({ id: unread.id });

		if (exist == null) return;

		if (params.isMentioned) {
			publishMainStream(userId, 'unreadMention', note.id);
		}
		if (params.isSpecified) {
			publishMainStream(userId, 'unreadSpecifiedNote', note.id);
		}
		if (note.channelId) {
			publishMainStream(userId, 'unreadChannel', note.id);
		}
	}, 2000);
}