From 7cd1d9ad93311cc3721c08b113133d15e0611689 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Sat, 10 May 2025 20:01:01 -0400 Subject: [PATCH 1/6] return actual muted word from check-word-mute.ts --- .../frontend/src/utility/check-word-mute.ts | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/packages/frontend/src/utility/check-word-mute.ts b/packages/frontend/src/utility/check-word-mute.ts index 26bf593f7b..2d8486760d 100644 --- a/packages/frontend/src/utility/check-word-mute.ts +++ b/packages/frontend/src/utility/check-word-mute.ts @@ -13,30 +13,37 @@ export function checkWordMute(note: string | Misskey.entities.Note, me: Misskey. if (text === '') return false; - const matched = mutedWords.filter(filter => { + const matched = mutedWords.reduce((matchedWords, filter) => { if (Array.isArray(filter)) { // Clean up const filteredFilter = filter.filter(keyword => keyword !== ''); - if (filteredFilter.length === 0) return false; - - return filteredFilter.every(keyword => text.includes(keyword)); + if (filteredFilter.length > 0 && filteredFilter.every(keyword => text.includes(keyword))) { + const fullFilter = filteredFilter.join(' '); + matchedWords.add(fullFilter); + } } else { // represents RegExp const regexp = filter.match(/^\/(.+)\/(.*)$/); // This should never happen due to input sanitisation. - if (!regexp) return false; - - try { - return new RegExp(regexp[1], regexp[2]).test(text); - } catch (err) { - // This should never happen due to input sanitisation. - return false; + if (regexp) { + try { + const flags = regexp[2].includes('g') ? regexp[2] : (regexp[2] + 'g'); + const matches = text.matchAll(new RegExp(regexp[1], flags)); + for (const match of matches) { + matchedWords.add(match[0]); + } + } catch { + // This should never happen due to input sanitisation. + } } } - }); - if (matched.length > 0) return matched; + return matchedWords; + }, new Set()); + + // Nested arrays are intentional, otherwise the note components will join with space (" ") and it's confusing. + if (matched.size > 0) return [[Array.from(matched).join(', ')]]; } return false; From 05e5be821885ea0a1d79f15b8aa7d26e542e9c2e Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Sat, 10 May 2025 20:01:26 -0400 Subject: [PATCH 2/6] show muted words in NoteDetailed / NoteSub components --- packages/frontend-shared/js/i18n.ts | 1 + .../src/components/MkNoteDetailed.vue | 51 ++++++++++++++++++- .../frontend/src/components/MkNoteSub.vue | 49 ++++++++++++++++-- .../src/components/SkNoteDetailed.vue | 51 ++++++++++++++++++- .../frontend/src/components/SkNoteSub.vue | 49 ++++++++++++++++-- 5 files changed, 191 insertions(+), 10 deletions(-) diff --git a/packages/frontend-shared/js/i18n.ts b/packages/frontend-shared/js/i18n.ts index 480cfcd642..d38bad45d9 100644 --- a/packages/frontend-shared/js/i18n.ts +++ b/packages/frontend-shared/js/i18n.ts @@ -59,6 +59,7 @@ export class I18n { if (typeof value === 'string') { const parameters = Array.from(value.matchAll(/\{(\w+)\}/g), ([, parameter]) => parameter); + // TODO add a flag to suppress this warning from uses of component if (parameters.length) { console.error(`Missing locale parameters: ${parameters.join(', ')} at ${String(p)}`); } diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 5bf1cde456..f702c7c422 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -230,11 +230,28 @@ SPDX-License-Identifier: AGPL-3.0-only
- + + + + + + + +
@@ -245,6 +262,7 @@ import * as Misskey from 'misskey-js'; import { isLink } from '@@/js/is-link.js'; import { host } from '@@/js/config.js'; import { computeMergedCw } from '@@/js/compute-merged-cw.js'; +import type { Ref } from 'vue'; import type { OpenOnRemoteOptions } from '@/utility/please-login.js'; import type { Paging } from '@/components/MkPagination.vue'; import type { Keymap } from '@/utility/hotkey.js'; @@ -340,7 +358,6 @@ const isMyRenote = $i && ($i.id === note.value.userId); const showContent = ref(prefer.s.uncollapseCW); const isDeleted = ref(false); const renoted = ref(false); -const muted = ref($i ? checkWordMute(appearNote.value, $i, $i.mutedWords) : false); const translation = ref(null); const translating = ref(false); const parsed = appearNote.value.text ? mfm.parse(appearNote.value.text) : null; @@ -358,6 +375,36 @@ const mergedCW = computed(() => computeMergedCw(appearNote.value)); const renoteTooltip = computeRenoteTooltip(renoted); +const inTimeline = inject('inTimeline', false); +const tl_withSensitive = inject>('tl_withSensitive', ref(true)); +const muted = ref(checkMute(appearNote.value, $i?.mutedWords)); +const showSoftWordMutedWord = computed(() => prefer.s.showSoftWordMutedWord); + +/* Overload FunctionにLintが対応していないのでコメントアウト +function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array | undefined | null, checkOnly: true): boolean; +function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array | undefined | null, checkOnly: false): Array | false | 'sensitiveMute'; +*/ +function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array | undefined | null, checkOnly = false): Array | false | 'sensitiveMute' { + if (mutedWords != null) { + const result = checkWordMute(noteToCheck, $i, mutedWords); + if (Array.isArray(result)) return result; + + const replyResult = noteToCheck.reply && checkWordMute(noteToCheck.reply, $i, mutedWords); + if (Array.isArray(replyResult)) return replyResult; + + const renoteResult = noteToCheck.renote && checkWordMute(noteToCheck.renote, $i, mutedWords); + if (Array.isArray(renoteResult)) return renoteResult; + } + + if (checkOnly) return false; + + if (inTimeline && tl_withSensitive.value === false && noteToCheck.files?.some((v) => v.isSensitive)) { + return 'sensitiveMute'; + } + + return false; +} + watch(() => props.expandAllCws, (expandAllCws) => { if (expandAllCws !== showContent.value) showContent.value = expandAllCws; }); diff --git a/packages/frontend/src/components/MkNoteSub.vue b/packages/frontend/src/components/MkNoteSub.vue index 9751dbbc5c..c017efa3f3 100644 --- a/packages/frontend/src/components/MkNoteSub.vue +++ b/packages/frontend/src/components/MkNoteSub.vue @@ -73,19 +73,33 @@ SPDX-License-Identifier: AGPL-3.0-only
- + + + + + + + +
diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index 878c81384c..ab8a3ec4a6 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -172,24 +172,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- - - - - - - - - - +