From 4c2f7c64cc2b70bd7b686e9ece1ebbc30eeab511 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 8 Mar 2023 08:56:09 +0900 Subject: feat: Per-user renote mute (#10249) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: per-user renote muting From FoundKey/c414f24a2c https://akkoma.dev/FoundKeyGang/FoundKey * Update ja-JP.yml * Delete renote-muting.ts * rename * fix ids * lint * fix * Update CHANGELOG.md * リノートをミュートしたユーザー一覧を見れるように * :art: * add test * fix test --------- Co-authored-by: Hélène --- packages/backend/src/server/api/stream/channel.ts | 4 ++++ .../backend/src/server/api/stream/channels/antenna.ts | 2 ++ .../backend/src/server/api/stream/channels/channel.ts | 2 ++ .../src/server/api/stream/channels/global-timeline.ts | 2 ++ .../backend/src/server/api/stream/channels/hashtag.ts | 2 ++ .../src/server/api/stream/channels/home-timeline.ts | 2 ++ .../src/server/api/stream/channels/hybrid-timeline.ts | 2 ++ .../src/server/api/stream/channels/local-timeline.ts | 2 ++ .../src/server/api/stream/channels/user-list.ts | 2 ++ packages/backend/src/server/api/stream/index.ts | 18 +++++++++++++++++- 10 files changed, 37 insertions(+), 1 deletion(-) (limited to 'packages/backend/src/server/api/stream') diff --git a/packages/backend/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts index 3e67880b45..32935325aa 100644 --- a/packages/backend/src/server/api/stream/channel.ts +++ b/packages/backend/src/server/api/stream/channel.ts @@ -27,6 +27,10 @@ export default abstract class Channel { return this.connection.muting; } + protected get renoteMuting() { + return this.connection.renoteMuting; + } + protected get blocking() { return this.connection.blocking; } diff --git a/packages/backend/src/server/api/stream/channels/antenna.ts b/packages/backend/src/server/api/stream/channels/antenna.ts index 18604d94f0..e2a42fbfe9 100644 --- a/packages/backend/src/server/api/stream/channels/antenna.ts +++ b/packages/backend/src/server/api/stream/channels/antenna.ts @@ -39,6 +39,8 @@ class AntennaChannel extends Channel { // 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する if (isUserRelated(note, this.blocking)) return; + if (note.renote && !note.text && isUserRelated(note, this.renoteMuting)) return; + this.connection.cacheNote(note); this.send('note', note); diff --git a/packages/backend/src/server/api/stream/channels/channel.ts b/packages/backend/src/server/api/stream/channels/channel.ts index f5ef1d1102..1234738ce8 100644 --- a/packages/backend/src/server/api/stream/channels/channel.ts +++ b/packages/backend/src/server/api/stream/channels/channel.ts @@ -51,6 +51,8 @@ class ChannelChannel extends Channel { // 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する if (isUserRelated(note, this.blocking)) return; + if (note.renote && !note.text && isUserRelated(note, this.renoteMuting)) return; + this.connection.cacheNote(note); this.send('note', note); diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts index b8c0076ed9..ab439a1717 100644 --- a/packages/backend/src/server/api/stream/channels/global-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts @@ -68,6 +68,8 @@ class GlobalTimelineChannel extends Channel { // 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する if (isUserRelated(note, this.blocking)) return; + if (note.renote && !note.text && isUserRelated(note, this.renoteMuting)) return; + // 流れてきたNoteがミュートすべきNoteだったら無視する // TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある) // 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、 diff --git a/packages/backend/src/server/api/stream/channels/hashtag.ts b/packages/backend/src/server/api/stream/channels/hashtag.ts index 00f8d8ecd2..63a2dd5b3a 100644 --- a/packages/backend/src/server/api/stream/channels/hashtag.ts +++ b/packages/backend/src/server/api/stream/channels/hashtag.ts @@ -49,6 +49,8 @@ class HashtagChannel extends Channel { if (isUserRelated(note, this.muting)) return; // 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する if (isUserRelated(note, this.blocking)) return; + + if (note.renote && !note.text && isUserRelated(note, this.renoteMuting)) return; this.connection.cacheNote(note); diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts index 04a9f29686..678fbe12d6 100644 --- a/packages/backend/src/server/api/stream/channels/home-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts @@ -75,6 +75,8 @@ class HomeTimelineChannel extends Channel { // 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する if (isUserRelated(note, this.blocking)) return; + if (note.renote && !note.text && isUserRelated(note, this.renoteMuting)) return; + // 流れてきたNoteがミュートすべきNoteだったら無視する // TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある) // 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、 diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts index ab52aabb30..e33a280499 100644 --- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts @@ -86,6 +86,8 @@ class HybridTimelineChannel extends Channel { // 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する if (isUserRelated(note, this.blocking)) return; + if (note.renote && !note.text && isUserRelated(note, this.renoteMuting)) return; + // 流れてきたNoteがミュートすべきNoteだったら無視する // TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある) // 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、 diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts index d8532c477b..341c4e32ce 100644 --- a/packages/backend/src/server/api/stream/channels/local-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts @@ -65,6 +65,8 @@ class LocalTimelineChannel extends Channel { // 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する if (isUserRelated(note, this.blocking)) return; + if (note.renote && !note.text && isUserRelated(note, this.renoteMuting)) return; + // 流れてきたNoteがミュートすべきNoteだったら無視する // TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある) // 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、 diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts index 7254d0a6d4..e7899245b6 100644 --- a/packages/backend/src/server/api/stream/channels/user-list.ts +++ b/packages/backend/src/server/api/stream/channels/user-list.ts @@ -93,6 +93,8 @@ class UserListChannel extends Channel { // 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する if (isUserRelated(note, this.blocking)) return; + if (note.renote && !note.text && isUserRelated(note, this.renoteMuting)) return; + this.send('note', note); } diff --git a/packages/backend/src/server/api/stream/index.ts b/packages/backend/src/server/api/stream/index.ts index d3056aca57..0a4fd8393a 100644 --- a/packages/backend/src/server/api/stream/index.ts +++ b/packages/backend/src/server/api/stream/index.ts @@ -1,6 +1,6 @@ import type { User } from '@/models/entities/User.js'; import type { Channel as ChannelModel } from '@/models/entities/Channel.js'; -import type { FollowingsRepository, MutingsRepository, UserProfilesRepository, ChannelFollowingsRepository, BlockingsRepository } from '@/models/index.js'; +import type { FollowingsRepository, MutingsRepository, RenoteMutingsRepository, UserProfilesRepository, ChannelFollowingsRepository, BlockingsRepository } from '@/models/index.js'; import type { AccessToken } from '@/models/entities/AccessToken.js'; import type { UserProfile } from '@/models/entities/UserProfile.js'; import type { Packed } from '@/misc/schema.js'; @@ -22,6 +22,7 @@ export default class Connection { public userProfile?: UserProfile | null; public following: Set = new Set(); public muting: Set = new Set(); + public renoteMuting: Set = new Set(); public blocking: Set = new Set(); // "被"blocking public followingChannels: Set = new Set(); public token?: AccessToken; @@ -34,6 +35,7 @@ export default class Connection { constructor( private followingsRepository: FollowingsRepository, private mutingsRepository: MutingsRepository, + private renoteMutingsRepository: RenoteMutingsRepository, private blockingsRepository: BlockingsRepository, private channelFollowingsRepository: ChannelFollowingsRepository, private userProfilesRepository: UserProfilesRepository, @@ -66,6 +68,7 @@ export default class Connection { if (this.user) { this.updateFollowing(); this.updateMuting(); + this.updateRenoteMuting(); this.updateBlocking(); this.updateFollowingChannels(); this.updateUserProfile(); @@ -93,6 +96,7 @@ export default class Connection { this.muting.delete(data.body.id); break; + // TODO: renote mute events // TODO: block events case 'followChannel': @@ -342,6 +346,18 @@ export default class Connection { this.muting = new Set(mutings.map(x => x.muteeId)); } + @bindThis + private async updateRenoteMuting() { + const renoteMutings = await this.renoteMutingsRepository.find({ + where: { + muterId: this.user!.id, + }, + select: ['muteeId'], + }); + + this.renoteMuting = new Set(renoteMutings.map(x => x.muteeId)); + } + @bindThis private async updateBlocking() { // ここでいうBlockingは被Blockingの意 const blockings = await this.blockingsRepository.find({ -- cgit v1.2.3-freya