Files
2026-07-26 18:25:37 +09:00

127 lines
4.0 KiB
JavaScript

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");
// }
// });
// }
}