import { publishMainStream } from "../stream.js"; import { NoteUnreads, Followings, ChannelFollowings } from "../../models/index.js"; import { Not, IsNull, In } from "typeorm"; import { readNotificationByQuery } from "../../server/api/common/read-notification.js"; /** * Mark notes as read */ export default async function(userId, notes, info) { const following = info?.following ? info.following : new Set((await Followings.find({ where: { followerId: userId }, select: [ "followeeId" ] })).map((x)=>x.followeeId)); const followingChannels = info?.followingChannels ? info.followingChannels : new Set((await ChannelFollowings.find({ where: { followerId: userId }, select: [ "followeeId" ] })).map((x)=>x.followeeId)); // const myAntennas = (await getAntennas()).filter((a) => a.userId === userId); const readMentions = []; const readSpecifiedNotes = []; const readChannelNotes = []; // const readAntennaNotes: (Note | Packed<"Note">)[] = []; for (const note of notes){ if (note.mentions?.includes(userId)) { readMentions.push(note); } else if (note.visibleUserIds?.includes(userId)) { readSpecifiedNotes.push(note); } if (note.channelId && followingChannels.has(note.channelId)) { readChannelNotes.push(note); } // if (note.user != null) { // // たぶんnullになることは無いはずだけど一応 // for (const antenna of myAntennas) { // if ( // await checkHitAntenna( // antenna, // note, // note.user, // undefined, // Array.from(following), // ) // ) { // readAntennaNotes.push(note); // } // } // } } if (readMentions.length > 0 || readSpecifiedNotes.length > 0 || readChannelNotes.length > 0) { // Remove the record await NoteUnreads.delete({ userId: userId, noteId: In([ ...readMentions.map((n)=>n.id), ...readSpecifiedNotes.map((n)=>n.id), ...readChannelNotes.map((n)=>n.id) ]) }); // TODO: ↓まとめてクエリしたい NoteUnreads.countBy({ userId: userId, isMentioned: true }).then((mentionsCount)=>{ if (mentionsCount === 0) { // 全て既読になったイベントを発行 publishMainStream(userId, "readAllUnreadMentions"); } }); NoteUnreads.countBy({ userId: userId, isSpecified: true }).then((specifiedCount)=>{ if (specifiedCount === 0) { // 全て既読になったイベントを発行 publishMainStream(userId, "readAllUnreadSpecifiedNotes"); } }); NoteUnreads.countBy({ userId: userId, noteChannelId: Not(IsNull()) }).then((channelNoteCount)=>{ if (channelNoteCount === 0) { // 全て既読になったイベントを発行 publishMainStream(userId, "readAllChannels"); } }); readNotificationByQuery(userId, { noteId: In([ ...readMentions.map((n)=>n.id), ...readSpecifiedNotes.map((n)=>n.id) ]) }); } // if (readAntennaNotes.length > 0) { // await AntennaNotes.update( // { // antennaId: In(myAntennas.map((a) => a.id)), // noteId: In(readAntennaNotes.map((n) => n.id)), // }, // { // read: true, // }, // ); // // TODO: まとめてクエリしたい // for (const antenna of myAntennas) { // const count = await AntennaNotes.countBy({ // antennaId: antenna.id, // read: false, // }); // if (count === 0) { // publishMainStream(userId, "readAntenna", antenna); // } // } // Users.getHasUnreadAntenna(userId).then((unread) => { // if (!unread) { // publishMainStream(userId, "readAllAntennas"); // } // }); // } }