Skip to content

Commit

Permalink
enhance: 通知がミュートを考慮するようにする
Browse files Browse the repository at this point in the history
  • Loading branch information
tai-cha committed Feb 19, 2024
1 parent 034f472 commit 35609b4
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { Brackets, In } from 'typeorm';
import * as Redis from 'ioredis';
import { Inject, Injectable } from '@nestjs/common';
import type { NotesRepository } from '@/models/_.js';
import type { NotesRepository, UsersRepository } from '@/models/_.js';
import { obsoleteNotificationTypes, notificationTypes, FilterUnionByProperty } from '@/types.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { NoteReadService } from '@/core/NoteReadService.js';
Expand All @@ -15,6 +15,7 @@ import { NotificationService } from '@/core/NotificationService.js';
import { DI } from '@/di-symbols.js';
import { IdService } from '@/core/IdService.js';
import { MiGroupedNotification, MiNotification } from '@/models/Notification.js';
import { CacheService } from '@/core/CacheService.js';

export const meta = {
tags: ['account', 'notifications'],
Expand Down Expand Up @@ -66,10 +67,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,

@Inject(DI.usersRepository)
private usersRepository: UsersRepository,

private idService: IdService,
private notificationEntityService: NotificationEntityService,
private notificationService: NotificationService,
private noteReadService: NoteReadService,
private cacheService: CacheService,
) {
super(meta, paramDef, async (ps, me) => {
const EXTRA_LIMIT = 100;
Expand Down Expand Up @@ -105,6 +110,29 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
notifications = notifications.filter(notification => !excludeTypes.includes(notification.type));
}

//#region Check muting

const [
userIdsWhoMeMuting,
userMutedInstances,
] = await Promise.all([
this.cacheService.userMutingsCache.fetch(me.id),
this.cacheService.userProfileCache.fetch(me.id).then(p => new Set(p.mutedInstances)),
]);

notifications = (await Promise.all(notifications.map(async (notification): Promise<MiNotification|null> => {
if (!('notifierId' in notification)) return null;
if (userIdsWhoMeMuting.has(notification.notifierId)) return null;

const notifier = await this.usersRepository.findOneBy({ id: notification.notifierId });
if (notifier === null) return null;
if (notifier.host && userMutedInstances.has(notifier.host)) return null;

return notification;
}))).filter((notification): notification is MiNotification => notification !== null);

//#endregion Check muting

if (notifications.length === 0) {
return [];
}
Expand Down
30 changes: 29 additions & 1 deletion packages/backend/src/server/api/endpoints/i/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { Brackets, In } from 'typeorm';
import * as Redis from 'ioredis';
import { Inject, Injectable } from '@nestjs/common';
import type { NotesRepository } from '@/models/_.js';
import type { NotesRepository, UsersRepository } from '@/models/_.js';
import { obsoleteNotificationTypes, notificationTypes, FilterUnionByProperty } from '@/types.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { NoteReadService } from '@/core/NoteReadService.js';
Expand All @@ -15,6 +15,7 @@ import { NotificationService } from '@/core/NotificationService.js';
import { DI } from '@/di-symbols.js';
import { IdService } from '@/core/IdService.js';
import { MiNotification } from '@/models/Notification.js';
import { CacheService } from '@/core/CacheService.js';

export const meta = {
tags: ['account', 'notifications'],
Expand Down Expand Up @@ -66,10 +67,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,

@Inject(DI.usersRepository)
private usersRepository: UsersRepository,

private idService: IdService,
private notificationEntityService: NotificationEntityService,
private notificationService: NotificationService,
private noteReadService: NoteReadService,
private cacheService: CacheService,
) {
super(meta, paramDef, async (ps, me) => {
// includeTypes が空の場合はクエリしない
Expand Down Expand Up @@ -103,6 +108,29 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
notifications = notifications.filter(notification => !excludeTypes.includes(notification.type));
}

//#region Check muting

const [
userIdsWhoMeMuting,
userMutedInstances,
] = await Promise.all([
this.cacheService.userMutingsCache.fetch(me.id),
this.cacheService.userProfileCache.fetch(me.id).then(p => new Set(p.mutedInstances)),
]);

notifications = (await Promise.all(notifications.map(async (notification): Promise<MiNotification|null> => {
if (!('notifierId' in notification)) return null;
if (userIdsWhoMeMuting.has(notification.notifierId)) return null;

const notifier = await this.usersRepository.findOneBy({ id: notification.notifierId });
if (notifier === null) return null;
if (notifier.host && userMutedInstances.has(notifier.host)) return null;

return notification;
}))).filter((notification): notification is MiNotification => notification !== null);

//#endregion Check muting

if (notifications.length === 0) {
return [];
}
Expand Down

0 comments on commit 35609b4

Please sign in to comment.