From 09a228051379723b4d3b9a97a7c6ab7a8054d7c4 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Fri, 27 Jun 2025 18:51:32 -0400 Subject: [PATCH 001/110] fix missing import for MkOmit in home.vue --- packages/frontend/src/pages/user/home.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue index 930baca05e..156eab004f 100644 --- a/packages/frontend/src/pages/user/home.vue +++ b/packages/frontend/src/pages/user/home.vue @@ -222,6 +222,7 @@ import { getStaticImageUrl } from '@/utility/media-proxy.js'; import MkSparkle from '@/components/MkSparkle.vue'; import { prefer } from '@/preferences.js'; import DynamicNote from '@/components/DynamicNote.vue'; +import MkOmit from '@/components/MkOmit.vue'; function calcAge(birthdate: string): number { const date = new Date(birthdate); From 54ad6438af52b2a0094a8cf478d7bc3cc2442d7c Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Fri, 27 Jun 2025 18:52:08 -0400 Subject: [PATCH 002/110] refactor note mutes and render mandatoryCW as a mute --- locales/index.d.ts | 4 + packages/frontend/src/components/MkNote.vue | 47 +--- .../src/components/MkNoteDetailed.vue | 40 +-- .../frontend/src/components/MkNoteSimple.vue | 8 +- .../frontend/src/components/MkNoteSub.vue | 29 +-- .../src/components/SkFollowingFeedEntry.vue | 27 +- .../frontend/src/components/SkMutedNote.vue | 119 ++++++--- packages/frontend/src/components/SkNote.vue | 45 +--- .../src/components/SkNoteDetailed.vue | 39 +-- .../frontend/src/components/SkNoteSimple.vue | 8 +- .../frontend/src/components/SkNoteSub.vue | 26 +- .../frontend/src/utility/check-word-mute.ts | 240 +++++++++++------- sharkey-locales/en-US.yml | 1 + 13 files changed, 304 insertions(+), 329 deletions(-) diff --git a/locales/index.d.ts b/locales/index.d.ts index 7f20c6803f..bb953a4a5e 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -12084,6 +12084,10 @@ export interface Locale extends ILocale { * {name} said something in a muted thread */ "userSaysSomethingInMutedThread": ParameterizedString<"name">; + /** + * {name} is flagged: "{cw}" + */ + "userIsFlaggedAs": ParameterizedString<"name" | "cw">; /** * Mark all media from user as NSFW */ diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index cd36bc2b89..fd752eb3f8 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -4,11 +4,12 @@ SPDX-License-Identifier: AGPL-3.0-only --> diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index 08098f89a5..8cfdcec62b 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -6,11 +6,12 @@ Displays a note in the Sharkey style. Used to show the "main" note in a given co --> diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index fd752eb3f8..9feed0acc6 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -12,6 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only :withHardMute="withHardMute" :class="[$style.root, { [$style.showActionsOnlyHover]: prefer.s.showNoteActionsOnlyHover, [$style.skipRender]: prefer.s.skipNoteRender }]" :tabindex="isDeleted ? '-1' : '0'" + @expand="n => emit('expandCW', n)" >
@@ -244,6 +245,7 @@ provide(DI.mock, props.mock); const emit = defineEmits<{ (ev: 'reaction', emoji: string): void; (ev: 'removeReaction', emoji: string): void; + (ev: 'expandCW', note: Misskey.entities.Note): void; }>(); const router = useRouter(); diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index 8cfdcec62b..d2b31e3df7 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -14,6 +14,7 @@ Displays a note in the Sharkey style. Used to show the "main" note in a given co :withHardMute="withHardMute" :class="[$style.root, { [$style.showActionsOnlyHover]: prefer.s.showNoteActionsOnlyHover, [$style.skipRender]: prefer.s.skipNoteRender }]" :tabindex="isDeleted ? '-1' : '0'" + @expand="n => emit('expandCW', n)" >
@@ -245,6 +246,7 @@ provide(DI.mock, props.mock); const emit = defineEmits<{ (ev: 'reaction', emoji: string): void; (ev: 'removeReaction', emoji: string): void; + (ev: 'expandCW', note: Misskey.entities.Note): void; }>(); const router = useRouter(); diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue index 156eab004f..0df9b425ed 100644 --- a/packages/frontend/src/pages/user/home.vue +++ b/packages/frontend/src/pages/user/home.vue @@ -176,10 +176,10 @@ SPDX-License-Identifier: AGPL-3.0-only
- +
- + @@ -198,6 +198,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { defineAsyncComponent, computed, onMounted, onUnmounted, nextTick, watch, ref } from 'vue'; import * as Misskey from 'misskey-js'; import { getScrollPosition } from '@@/js/scroll.js'; +import { patchMuteOverrides } from '@/utility/check-word-mute.js'; import MkTab from '@/components/MkTab.vue'; import MkNotes from '@/components/MkNotes.vue'; import MkFollowButton from '@/components/MkFollowButton.vue'; @@ -255,6 +256,14 @@ const emit = defineEmits<{ (ev: 'unfoldFiles'): void; }>(); +const cwOverrides = patchMuteOverrides(); + +function onExpandCW() { + // This kills the user-level and instance-level CWs for all notes below this point + cwOverrides.userMandatoryCW = null; + cwOverrides.instanceMandatoryCW = null; +} + const router = useRouter(); const user = ref(props.user); diff --git a/packages/frontend/src/utility/check-word-mute.ts b/packages/frontend/src/utility/check-word-mute.ts index fb61ad74ad..6b054852f5 100644 --- a/packages/frontend/src/utility/check-word-mute.ts +++ b/packages/frontend/src/utility/check-word-mute.ts @@ -19,7 +19,6 @@ export interface Mute { noteMuted?: boolean; noteMandatoryCW?: string | null; - // TODO show this as a single block on user timelines userMandatoryCW?: string | null; instanceMandatoryCW?: string | null; } From 4847257011b49ab37ede121d5fa843aba9b74c8c Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Sat, 28 Jun 2025 18:38:43 -0400 Subject: [PATCH 012/110] fix bulk expand mute --- .../frontend/src/components/DynamicNote.vue | 4 +- .../src/components/DynamicNoteDetailed.vue | 41 +++++- packages/frontend/src/components/MkNote.vue | 4 +- .../src/components/MkNoteDetailed.vue | 5 + packages/frontend/src/components/MkNotes.vue | 6 +- .../frontend/src/components/SkMutedNote.vue | 9 +- packages/frontend/src/components/SkNote.vue | 4 +- .../src/components/SkNoteDetailed.vue | 5 + packages/frontend/src/pages/user/home.vue | 25 ++-- .../frontend/src/utility/check-word-mute.ts | 135 +++++++++++------- packages/frontend/src/utility/merge.ts | 36 +++++ 11 files changed, 201 insertions(+), 73 deletions(-) diff --git a/packages/frontend/src/components/DynamicNote.vue b/packages/frontend/src/components/DynamicNote.vue index 115aeecfb3..5d01d3e255 100644 --- a/packages/frontend/src/components/DynamicNote.vue +++ b/packages/frontend/src/components/DynamicNote.vue @@ -14,7 +14,7 @@ Displays a note with either Misskey or Sharkey style, based on user preference. :withHardMute="withHardMute" @reaction="emoji => emit('reaction', emoji)" @removeReaction="emoji => emit('removeReaction', emoji)" - @expandCW="n => emit('expandCW', n)" + @expandMute="n => emit('expandMute', n)" /> @@ -45,6 +45,6 @@ defineProps<{ const emit = defineEmits<{ (ev: 'reaction', emoji: string): void; (ev: 'removeReaction', emoji: string): void; - (ev: 'expandCW', note: Misskey.entities.Note): void; + (ev: 'expandMute', note: Misskey.entities.Note): void; }>(); diff --git a/packages/frontend/src/components/DynamicNoteDetailed.vue b/packages/frontend/src/components/DynamicNoteDetailed.vue index f47536d47a..959cba3e4d 100644 --- a/packages/frontend/src/components/DynamicNoteDetailed.vue +++ b/packages/frontend/src/components/DynamicNoteDetailed.vue @@ -11,30 +11,61 @@ Displays a note in the detailed view with either Misskey or Sharkey style, based :note="note" :initialTab="initialTab" :expandAllCws="expandAllCws" + @expandMute="n => onExpandNote(n)" /> diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 9feed0acc6..30a9a1ad00 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only :withHardMute="withHardMute" :class="[$style.root, { [$style.showActionsOnlyHover]: prefer.s.showNoteActionsOnlyHover, [$style.skipRender]: prefer.s.skipNoteRender }]" :tabindex="isDeleted ? '-1' : '0'" - @expand="n => emit('expandCW', n)" + @expandMute="n => emit('expandMute', n)" >
@@ -245,7 +245,7 @@ provide(DI.mock, props.mock); const emit = defineEmits<{ (ev: 'reaction', emoji: string): void; (ev: 'removeReaction', emoji: string): void; - (ev: 'expandCW', note: Misskey.entities.Note): void; + (ev: 'expandMute', note: Misskey.entities.Note): void; }>(); const router = useRouter(); diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 98582c56fc..f63e18f42a 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -11,6 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only :note="appearNote" :class="$style.root" :tabindex="isDeleted ? '-1' : '0'" + @expandMute="n => emit('expandMute', n)" >
@@ -292,6 +293,10 @@ const props = withDefaults(defineProps<{ initialTab: 'replies', }); +const emit = defineEmits<{ + (ev: 'expandMute', note: Misskey.entities.Note): void; +}>(); + const inChannel = inject('inChannel', null); const note = ref(deepClone(props.note)); diff --git a/packages/frontend/src/components/MkNotes.vue b/packages/frontend/src/components/MkNotes.vue index e31b56eee7..7108a5721b 100644 --- a/packages/frontend/src/components/MkNotes.vue +++ b/packages/frontend/src/components/MkNotes.vue @@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only