noteのread処理
This commit is contained in:
@ -33,6 +33,7 @@ import { countSameRenotes } from '../../misc/count-same-renotes';
|
||||
import { deliverToRelays } from '../relay';
|
||||
import { Channel } from '../../models/entities/channel';
|
||||
import { normalizeForSearch } from '../../misc/normalize-for-search';
|
||||
import { getAntennas } from '../../misc/antenna-cache';
|
||||
|
||||
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
|
||||
|
||||
@ -241,6 +242,7 @@ export default async (user: User, data: Option, silent = false) => new Promise<N
|
||||
incNotesCountOfUser(user);
|
||||
|
||||
// Word mute
|
||||
// TODO: cache
|
||||
UserProfiles.find({
|
||||
enableWordMute: true
|
||||
}).then(us => {
|
||||
@ -262,17 +264,15 @@ export default async (user: User, data: Option, silent = false) => new Promise<N
|
||||
Followings.createQueryBuilder('following')
|
||||
.andWhere(`following.followeeId = :userId`, { userId: note.userId })
|
||||
.getMany()
|
||||
.then(followings => {
|
||||
.then(async followings => {
|
||||
const followers = followings.map(f => f.followerId);
|
||||
Antennas.find().then(async antennas => {
|
||||
for (const antenna of antennas) {
|
||||
checkHitAntenna(antenna, note, user, followers).then(hit => {
|
||||
if (hit) {
|
||||
addNoteToAntenna(antenna, note, user);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
for (const antenna of (await getAntennas())) {
|
||||
checkHitAntenna(antenna, note, user, followers).then(hit => {
|
||||
if (hit) {
|
||||
addNoteToAntenna(antenna, note, user);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Channel
|
||||
|
@ -1,23 +1,59 @@
|
||||
import { publishMainStream } from '../stream';
|
||||
import { Note } from '../../models/entities/note';
|
||||
import { User } from '../../models/entities/user';
|
||||
import { NoteUnreads, Antennas, AntennaNotes, Users } from '../../models';
|
||||
import { NoteUnreads, AntennaNotes, Users } from '../../models';
|
||||
import { Not, IsNull, In } from 'typeorm';
|
||||
import { Channel } from '../../models/entities/channel';
|
||||
import { checkHitAntenna } from '../../misc/check-hit-antenna';
|
||||
import { getAntennas } from '../../misc/antenna-cache';
|
||||
import { PackedNote } from '../../models/repositories/note';
|
||||
|
||||
/**
|
||||
* Mark notes as read
|
||||
*/
|
||||
export default async function(
|
||||
userId: User['id'],
|
||||
noteIds: Note['id'][]
|
||||
notes: (Note | PackedNote)[],
|
||||
info: {
|
||||
following: Set<Channel['id']>;
|
||||
followingChannels: Set<Channel['id']>;
|
||||
}
|
||||
) {
|
||||
async function careNoteUnreads() {
|
||||
const myAntennas = (await getAntennas()).filter(a => a.userId === userId);
|
||||
const readMentions: (Note | PackedNote)[] = [];
|
||||
const readSpecifiedNotes: (Note | PackedNote)[] = [];
|
||||
const readChannelNotes: (Note | PackedNote)[] = [];
|
||||
const readAntennaNotes: (Note | PackedNote)[] = [];
|
||||
|
||||
for (const note of notes) {
|
||||
if (note.mentions && note.mentions.includes(userId)) {
|
||||
readMentions.push(note);
|
||||
} else if (note.visibleUserIds && note.visibleUserIds.includes(userId)) {
|
||||
readSpecifiedNotes.push(note);
|
||||
}
|
||||
|
||||
if (note.channelId && info.followingChannels.has(note.channelId)) {
|
||||
readChannelNotes.push(note);
|
||||
}
|
||||
|
||||
if (note.user != null) { // たぶんnullになることは無いはずだけど一応
|
||||
for (const antenna of myAntennas) {
|
||||
if (checkHitAntenna(antenna, note, note.user as any, undefined, Array.from(info.following))) {
|
||||
readAntennaNotes.push(note);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((readMentions.length > 0) || (readSpecifiedNotes.length > 0) || (readChannelNotes.length > 0)) {
|
||||
// Remove the record
|
||||
await NoteUnreads.delete({
|
||||
userId: userId,
|
||||
noteId: In(noteIds),
|
||||
noteId: In([...readMentions.map(n => n.id), ...readSpecifiedNotes.map(n => n.id), ...readChannelNotes.map(n => n.id)]),
|
||||
});
|
||||
|
||||
// TODO: ↓まとめてクエリしたい
|
||||
|
||||
NoteUnreads.count({
|
||||
userId: userId,
|
||||
isMentioned: true
|
||||
@ -49,33 +85,25 @@ export default async function(
|
||||
});
|
||||
}
|
||||
|
||||
async function careAntenna() {
|
||||
const antennas = await Antennas.find({ userId });
|
||||
if (readAntennaNotes.length > 0) {
|
||||
await AntennaNotes.update({
|
||||
antennaId: In(myAntennas.map(a => a.id)),
|
||||
noteId: In(readAntennaNotes.map(n => n.id))
|
||||
}, {
|
||||
read: true
|
||||
});
|
||||
|
||||
await Promise.all(antennas.map(async antenna => {
|
||||
const countBefore = await AntennaNotes.count({
|
||||
// TODO: まとめてクエリしたい
|
||||
for (const antenna of myAntennas) {
|
||||
const count = await AntennaNotes.count({
|
||||
antennaId: antenna.id,
|
||||
read: false
|
||||
});
|
||||
|
||||
if (countBefore === 0) return;
|
||||
|
||||
await AntennaNotes.update({
|
||||
antennaId: antenna.id,
|
||||
noteId: In(noteIds)
|
||||
}, {
|
||||
read: true
|
||||
});
|
||||
|
||||
const countAfter = await AntennaNotes.count({
|
||||
antennaId: antenna.id,
|
||||
read: false
|
||||
});
|
||||
|
||||
if (countAfter === 0) {
|
||||
if (count === 0) {
|
||||
publishMainStream(userId, 'readAntenna', antenna);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
Users.getHasUnreadAntenna(userId).then(unread => {
|
||||
if (!unread) {
|
||||
@ -83,7 +111,4 @@ export default async function(
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
careNoteUnreads();
|
||||
careAntenna();
|
||||
}
|
||||
|
@ -20,6 +20,10 @@ class Publisher {
|
||||
}));
|
||||
}
|
||||
|
||||
public publishInternalEvent = (type: string, value?: any): void => {
|
||||
this.publish('internal', type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
public publishUserEvent = (userId: User['id'], type: string, value?: any): void => {
|
||||
this.publish(`user:${userId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
@ -88,6 +92,7 @@ const publisher = new Publisher();
|
||||
|
||||
export default publisher;
|
||||
|
||||
export const publishInternalEvent = publisher.publishInternalEvent;
|
||||
export const publishUserEvent = publisher.publishUserEvent;
|
||||
export const publishBroadcastStream = publisher.publishBroadcastStream;
|
||||
export const publishMainStream = publisher.publishMainStream;
|
||||
|
Reference in New Issue
Block a user