parent
38d0b62167
commit
30d6992684
29 changed files with 185 additions and 613 deletions
|
@ -1,7 +1,8 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
import { In } from 'typeorm';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { AccessTokensRepository, NoteReactionsRepository, NotificationsRepository, User } from '@/models/index.js';
|
||||
import type { AccessTokensRepository, NoteReactionsRepository, NotesRepository, User, UsersRepository } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Notification } from '@/models/entities/Notification.js';
|
||||
import type { Note } from '@/models/entities/Note.js';
|
||||
|
@ -25,8 +26,11 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
constructor(
|
||||
private moduleRef: ModuleRef,
|
||||
|
||||
@Inject(DI.notificationsRepository)
|
||||
private notificationsRepository: NotificationsRepository,
|
||||
@Inject(DI.notesRepository)
|
||||
private notesRepository: NotesRepository,
|
||||
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
@Inject(DI.noteReactionsRepository)
|
||||
private noteReactionsRepository: NoteReactionsRepository,
|
||||
|
@ -48,30 +52,39 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
|
||||
@bindThis
|
||||
public async pack(
|
||||
src: Notification['id'] | Notification,
|
||||
src: Notification,
|
||||
meId: User['id'],
|
||||
options: {
|
||||
_hint_?: {
|
||||
packedNotes: Map<Note['id'], Packed<'Note'>>;
|
||||
};
|
||||
|
||||
},
|
||||
hint?: {
|
||||
packedNotes: Map<Note['id'], Packed<'Note'>>;
|
||||
packedUsers: Map<User['id'], Packed<'User'>>;
|
||||
},
|
||||
): Promise<Packed<'Notification'>> {
|
||||
const notification = typeof src === 'object' ? src : await this.notificationsRepository.findOneByOrFail({ id: src });
|
||||
const notification = src;
|
||||
const token = notification.appAccessTokenId ? await this.accessTokensRepository.findOneByOrFail({ id: notification.appAccessTokenId }) : null;
|
||||
const noteIfNeed = NOTE_REQUIRED_NOTIFICATION_TYPES.has(notification.type) && notification.noteId != null ? (
|
||||
options._hint_?.packedNotes != null
|
||||
? options._hint_.packedNotes.get(notification.noteId)
|
||||
: this.noteEntityService.pack(notification.note ?? notification.noteId!, { id: notification.notifieeId }, {
|
||||
hint?.packedNotes != null
|
||||
? hint.packedNotes.get(notification.noteId)
|
||||
: this.noteEntityService.pack(notification.noteId!, { id: meId }, {
|
||||
detail: true,
|
||||
})
|
||||
) : undefined;
|
||||
const userIfNeed = notification.notifierId != null ? (
|
||||
hint?.packedUsers != null
|
||||
? hint.packedUsers.get(notification.notifierId)
|
||||
: this.userEntityService.pack(notification.notifierId!, { id: meId }, {
|
||||
detail: false,
|
||||
})
|
||||
) : undefined;
|
||||
|
||||
return await awaitAll({
|
||||
id: notification.id,
|
||||
createdAt: notification.createdAt.toISOString(),
|
||||
createdAt: new Date(notification.createdAt).toISOString(),
|
||||
type: notification.type,
|
||||
isRead: notification.isRead,
|
||||
userId: notification.notifierId,
|
||||
user: notification.notifierId ? this.userEntityService.pack(notification.notifier ?? notification.notifierId) : null,
|
||||
...(userIfNeed != null ? { user: userIfNeed } : {}),
|
||||
...(noteIfNeed != null ? { note: noteIfNeed } : {}),
|
||||
...(notification.type === 'reaction' ? {
|
||||
reaction: notification.reaction,
|
||||
|
@ -87,33 +100,36 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param notifications you should join "note" property when fetch from DB, and all notifieeId should be same as meId
|
||||
*/
|
||||
@bindThis
|
||||
public async packMany(
|
||||
notifications: Notification[],
|
||||
meId: User['id'],
|
||||
) {
|
||||
if (notifications.length === 0) return [];
|
||||
|
||||
for (const notification of notifications) {
|
||||
if (meId !== notification.notifieeId) {
|
||||
// because we call note packMany with meId, all notifieeId should be same as meId
|
||||
throw new Error('TRY_TO_PACK_ANOTHER_USER_NOTIFICATION');
|
||||
}
|
||||
}
|
||||
|
||||
const notes = notifications.map(x => x.note).filter(isNotNull);
|
||||
const noteIds = notifications.map(x => x.noteId).filter(isNotNull);
|
||||
const notes = noteIds.length > 0 ? await this.notesRepository.find({
|
||||
where: { id: In(noteIds) },
|
||||
relations: ['user', 'user.avatar', 'user.banner', 'reply', 'reply.user', 'reply.user.avatar', 'reply.user.banner', 'renote', 'renote.user', 'renote.user.avatar', 'renote.user.banner'],
|
||||
}) : [];
|
||||
const packedNotesArray = await this.noteEntityService.packMany(notes, { id: meId }, {
|
||||
detail: true,
|
||||
});
|
||||
const packedNotes = new Map(packedNotesArray.map(p => [p.id, p]));
|
||||
|
||||
return await Promise.all(notifications.map(x => this.pack(x, {
|
||||
_hint_: {
|
||||
packedNotes,
|
||||
},
|
||||
const userIds = notifications.map(x => x.notifierId).filter(isNotNull);
|
||||
const users = userIds.length > 0 ? await this.usersRepository.find({
|
||||
where: { id: In(userIds) },
|
||||
relations: ['avatar', 'banner'],
|
||||
}) : [];
|
||||
const packedUsersArray = await this.userEntityService.packMany(users, { id: meId }, {
|
||||
detail: false,
|
||||
});
|
||||
const packedUsers = new Map(packedUsersArray.map(p => [p.id, p]));
|
||||
|
||||
return await Promise.all(notifications.map(x => this.pack(x, meId, {}, {
|
||||
packedNotes,
|
||||
packedUsers,
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue