iceshrimp-legacy/packages/backend/src/services/note/unread.ts

60 lines
1.7 KiB
TypeScript

import type { Note } from "@/models/entities/note.js";
import { publishMainStream } from "@/services/stream.js";
import type { 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.exist({ where: { id: unread.id } });
if (!exist) 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);
}