From f1fc8bc35734dfa010161bdfa63c751ab0baede5 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Wed, 13 Aug 2025 11:54:17 -0400 Subject: [PATCH] add bypassSilence property at note level to fix silenced users' self-boosts showing a warning even when the user is followed --- packages/backend/src/core/entities/NoteEntityService.ts | 9 +++++++++ packages/backend/src/models/json-schema/note.ts | 4 ++++ packages/frontend/src/utility/check-word-mute.ts | 9 +++++---- packages/misskey-js/src/autogen/types.ts | 1 + 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts index 1f5496aa93..d0d7b0e9cf 100644 --- a/packages/backend/src/core/entities/NoteEntityService.ts +++ b/packages/backend/src/core/entities/NoteEntityService.ts @@ -600,6 +600,7 @@ export class NoteEntityService implements OnModuleInit { detail?: boolean; skipHide?: boolean; withReactionAndUserPairCache?: boolean; + bypassSilence?: boolean; _hint_?: { bufferedReactions: Map; pairs: ([MiUser['id'], string])[] }> | null; myReactions: Map; @@ -721,6 +722,7 @@ export class NoteEntityService implements OnModuleInit { isMutingNote: mutedNotes.has(note.id), isFavorited, isRenoted, + bypassSilence: opts.bypassSilence ?? false, ...(meId && Object.keys(reactions).length > 0 ? { myReaction: this.populateMyReaction({ @@ -739,6 +741,9 @@ export class NoteEntityService implements OnModuleInit { skipHide: opts.skipHide, withReactionAndUserPairCache: opts.withReactionAndUserPairCache, _hint_: options?._hint_, + + // Don't silence target of self-renote, since the outer note will already be silenced. + bypassSilence: options?.bypassSilence || note.userId === note.replyUserId, }) : undefined, renote: note.renoteId ? this.pack(note.renote ?? opts._hint_?.notes.get(note.renoteId) ?? note.renoteId, me, { @@ -746,6 +751,9 @@ export class NoteEntityService implements OnModuleInit { skipHide: opts.skipHide, withReactionAndUserPairCache: opts.withReactionAndUserPairCache, _hint_: options?._hint_, + + // Don't silence target of self-reply, since the outer note will already be silenced. + bypassSilence: options?.bypassSilence || note.userId === note.renoteUserId, }) : undefined, } : {}), }); @@ -771,6 +779,7 @@ export class NoteEntityService implements OnModuleInit { options?: { detail?: boolean; skipHide?: boolean; + bypassSilence?: boolean; }, ) { if (notes.length === 0) return []; diff --git a/packages/backend/src/models/json-schema/note.ts b/packages/backend/src/models/json-schema/note.ts index 79b36ba0da..960865facd 100644 --- a/packages/backend/src/models/json-schema/note.ts +++ b/packages/backend/src/models/json-schema/note.ts @@ -197,6 +197,10 @@ export const packedNoteSchema = { type: 'boolean', optional: false, nullable: false, }, + bypassSilence: { + type: 'boolean', + optional: false, nullable: false, + }, emojis: { type: 'object', optional: true, nullable: false, diff --git a/packages/frontend/src/utility/check-word-mute.ts b/packages/frontend/src/utility/check-word-mute.ts index 70d2491dc5..a92104a403 100644 --- a/packages/frontend/src/utility/check-word-mute.ts +++ b/packages/frontend/src/utility/check-word-mute.ts @@ -107,12 +107,13 @@ function getMutes(note: Misskey.entities.Note, withHardMute: boolean, overrides: ) : {}; const isMe = $i != null && $i.id === note.userId; + const bypassSilence = note.bypassSilence || note.user.bypassSilence; const hardMuted = override.hardMuted ?? (!isMe && withHardMute && isHardMuted(note)); const softMutedWords = override.softMutedWords ?? (isMe ? [] : isSoftMuted(note)); const sensitiveMuted = override.sensitiveMuted ?? isSensitiveMuted(note); - const userSilenced = override.userSilenced ?? (note.user.isSilenced && !note.user.bypassSilence); - const instanceSilenced = override.instanceSilenced ?? (note.user.instance?.isSilenced && !note.user.bypassSilence) ?? false; + const userSilenced = override.userSilenced ?? (note.user.isSilenced && !bypassSilence); + const instanceSilenced = override.instanceSilenced ?? (note.user.instance?.isSilenced && !bypassSilence) ?? false; const threadMuted = override.threadMuted ?? (!isMe && note.isMutingThread); const noteMuted = override.noteMuted ?? (!isMe && note.isMutingNote); const noteMandatoryCW = override.noteMandatoryCW !== undefined @@ -120,13 +121,13 @@ function getMutes(note: Misskey.entities.Note, withHardMute: boolean, overrides: : (isMe ? null : note.mandatoryCW); const userMandatoryCW = override.userMandatoryCW !== undefined ? override.userMandatoryCW - : !note.user.bypassSilence + : !bypassSilence ? note.user.mandatoryCW : null; const instanceMandatoryCW = override.instanceMandatoryCW !== undefined ? override.instanceMandatoryCW - : (!note.user.bypassSilence && note.user.instance) + : (!bypassSilence && note.user.instance) ? note.user.instance.mandatoryCW : null; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 71c30d66e5..fa86d3447d 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -4732,6 +4732,7 @@ export type components = { isMutingNote: boolean; isFavorited: boolean; isRenoted: boolean; + bypassSilence: boolean; emojis?: { [key: string]: string; };