diff options
| author | Hazelnoot <acomputerdog@gmail.com> | 2025-05-12 23:28:55 -0400 |
|---|---|---|
| committer | Hazelnoot <acomputerdog@gmail.com> | 2025-05-12 23:28:55 -0400 |
| commit | b52db71e1894e25cebfafc782d2cec86705e2cbb (patch) | |
| tree | c3444a49a9507403a5e6cbd0a7f1a8fd4a0e10d9 /packages/frontend | |
| parent | simplify access to showSoftWordMutedWord (diff) | |
| download | sharkey-b52db71e1894e25cebfafc782d2cec86705e2cbb.tar.gz sharkey-b52db71e1894e25cebfafc782d2cec86705e2cbb.tar.bz2 sharkey-b52db71e1894e25cebfafc782d2cec86705e2cbb.zip | |
factor out shared word mute logic
Diffstat (limited to 'packages/frontend')
| -rw-r--r-- | packages/frontend/src/components/MkNote.vue | 52 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkNoteDetailed.vue | 56 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkNoteSub.vue | 54 | ||||
| -rw-r--r-- | packages/frontend/src/components/SkMutedNote.vue | 46 | ||||
| -rw-r--r-- | packages/frontend/src/components/SkNote.vue | 52 | ||||
| -rw-r--r-- | packages/frontend/src/components/SkNoteDetailed.vue | 56 | ||||
| -rw-r--r-- | packages/frontend/src/components/SkNoteSub.vue | 52 | ||||
| -rw-r--r-- | packages/frontend/src/utility/check-word-mute.ts | 36 |
8 files changed, 107 insertions, 297 deletions
diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 4ceefe300b..b4977b73bc 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -171,24 +171,7 @@ SPDX-License-Identifier: AGPL-3.0-only </article> </div> <div v-else-if="!hardMuted" :class="$style.muted" @click="muted = false"> - <I18n v-if="muted === 'sensitiveMute'" :src="i18n.ts.userSaysSomethingSensitive" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - </I18n> - <I18n v-else-if="prefer.s.showSoftWordMutedWord" :src="i18n.ts.userSaysSomething" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - </I18n> - <I18n v-else :src="i18n.ts.userSaysSomethingAbout" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - <template #word> - {{ Array.isArray(muted) ? muted.map(words => Array.isArray(words) ? words.join() : words).slice(0, 3).join(' ') : muted }} - </template> - </I18n> + <SkMutedNote :muted="muted" :note="appearNote"></SkMutedNote> </div> <div v-else> <!-- @@ -224,7 +207,7 @@ import MkUrlPreview from '@/components/MkUrlPreview.vue'; import MkInstanceTicker from '@/components/MkInstanceTicker.vue'; import MkButton from '@/components/MkButton.vue'; import { pleaseLogin } from '@/utility/please-login.js'; -import { checkWordMute } from '@/utility/check-word-mute.js'; +import { checkMutes } from '@/utility/check-word-mute.js'; import { notePage } from '@/filters/note.js'; import { userPage } from '@/filters/user.js'; import number from '@/filters/number.js'; @@ -253,6 +236,7 @@ import { prefer } from '@/preferences.js'; import { getPluginHandlers } from '@/plugin.js'; import { DI } from '@/di.js'; import { useRouter } from '@/router.js'; +import SkMutedNote from '@/components/SkMutedNote.vue'; const props = withDefaults(defineProps<{ note: Misskey.entities.Note; @@ -272,8 +256,6 @@ const emit = defineEmits<{ const router = useRouter(); -const inTimeline = inject<boolean>('inTimeline', false); -const tl_withSensitive = inject<Ref<boolean>>('tl_withSensitive', ref(true)); const inChannel = inject('inChannel', null); const currentClip = inject<Ref<Misskey.entities.Clip> | null>('currentClip', null); @@ -327,8 +309,7 @@ const isLong = shouldCollapsed(appearNote.value, urls.value ?? []); const collapsed = ref(prefer.s.expandLongNote && appearNote.value.cw == null && isLong ? false : appearNote.value.cw == null && isLong); const isDeleted = ref(false); const renoted = ref(false); -const muted = ref(checkMute(appearNote.value, $i?.mutedWords)); -const hardMuted = ref(props.withHardMute && checkMute(appearNote.value, $i?.hardMutedWords, true)); +const { muted, hardMuted } = checkMutes(appearNote.value, props.withHardMute); const translation = ref<Misskey.entities.NotesTranslateResponse | null>(null); const translating = ref(false); const showTicker = (prefer.s.instanceTicker === 'always') || (prefer.s.instanceTicker === 'remote' && appearNote.value.user.instance); @@ -353,31 +334,6 @@ const mergedCW = computed(() => computeMergedCw(appearNote.value)); const renoteTooltip = computeRenoteTooltip(renoted); -/* Overload FunctionにLintが対応していないのでコメントアウト -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: true): boolean; -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: false): Array<string | string[]> | false | 'sensitiveMute'; -*/ -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly = false): Array<string | string[]> | 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; -} - let renoting = false; const keymap = { diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 0b3e5966dc..4a51cb3641 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -230,28 +230,7 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </div> <div v-else class="_panel" :class="$style.muted" @click="muted = false"> - <I18n v-if="muted === 'sensitiveMute'" :src="i18n.ts.userSaysSomethingSensitive" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - </I18n> - <I18n v-else-if="prefer.s.showSoftWordMutedWord" :src="i18n.ts.userSaysSomething" tag="small"> - <template #name> - <MkA v-user-preview="appearNote.userId" :to="userPage(appearNote.user)"> - <MkUserName :user="appearNote.user"/> - </MkA> - </template> - </I18n> - <I18n v-else :src="i18n.ts.userSaysSomethingAbout" tag="small"> - <template #name> - <MkA v-user-preview="appearNote.userId" :to="userPage(appearNote.user)"> - <MkUserName :user="appearNote.user"/> - </MkA> - </template> - <template #word> - {{ Array.isArray(muted) ? muted.map(words => Array.isArray(words) ? words.join() : words).slice(0, 3).join(' ') : muted }} - </template> - </I18n> + <SkMutedNote :muted="muted" :note="appearNote"></SkMutedNote> </div> </template> @@ -262,7 +241,6 @@ 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'; @@ -278,7 +256,7 @@ import MkUsersTooltip from '@/components/MkUsersTooltip.vue'; import MkUrlPreview from '@/components/MkUrlPreview.vue'; import MkInstanceTicker from '@/components/MkInstanceTicker.vue'; import { pleaseLogin } from '@/utility/please-login.js'; -import { checkWordMute } from '@/utility/check-word-mute.js'; +import { checkMutes } from '@/utility/check-word-mute.js'; import { userPage } from '@/filters/user.js'; import { notePage } from '@/filters/note.js'; import number from '@/filters/number.js'; @@ -308,6 +286,7 @@ import { getAppearNote } from '@/utility/get-appear-note.js'; import { prefer } from '@/preferences.js'; import { getPluginHandlers } from '@/plugin.js'; import { DI } from '@/di.js'; +import SkMutedNote from '@/components/SkMutedNote.vue'; const props = withDefaults(defineProps<{ note: Misskey.entities.Note; @@ -375,34 +354,7 @@ const mergedCW = computed(() => computeMergedCw(appearNote.value)); const renoteTooltip = computeRenoteTooltip(renoted); -const inTimeline = inject<boolean>('inTimeline', false); -const tl_withSensitive = inject<Ref<boolean>>('tl_withSensitive', ref(true)); -const muted = ref(checkMute(appearNote.value, $i?.mutedWords)); - -/* Overload FunctionにLintが対応していないのでコメントアウト -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: true): boolean; -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: false): Array<string | string[]> | false | 'sensitiveMute'; -*/ -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly = false): Array<string | string[]> | 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; -} +const { muted } = checkMutes(appearNote.value); 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 b975de85e1..7661bebfe7 100644 --- a/packages/frontend/src/components/MkNoteSub.vue +++ b/packages/frontend/src/components/MkNoteSub.vue @@ -73,33 +73,15 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </div> <div v-else :class="$style.muted" @click="muted = false"> - <I18n v-if="muted === 'sensitiveMute'" :src="i18n.ts.userSaysSomethingSensitive" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - </I18n> - <I18n v-else-if="prefer.s.showSoftWordMutedWord" :src="i18n.ts.userSaysSomething" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - </I18n> - <I18n v-else :src="i18n.ts.userSaysSomethingAbout" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - <template #word> - {{ Array.isArray(muted) ? muted.map(words => Array.isArray(words) ? words.join() : words).slice(0, 3).join(' ') : muted }} - </template> - </I18n> + <SkMutedNote :muted="muted" :note="appearNote"></SkMutedNote> </div> </template> <script lang="ts" setup> -import { computed, inject, ref, shallowRef, watch } from 'vue'; +import { computed, ref, shallowRef, watch } from 'vue'; import * as Misskey from 'misskey-js'; import { computeMergedCw } from '@@/js/compute-merged-cw.js'; import { host } from '@@/js/config.js'; -import type { Ref } from 'vue'; import type { Visibility } from '@/utility/boost-quote.js'; import type { OpenOnRemoteOptions } from '@/utility/please-login.js'; import MkNoteHeader from '@/components/MkNoteHeader.vue'; @@ -113,7 +95,7 @@ import { misskeyApi } from '@/utility/misskey-api.js'; import { i18n } from '@/i18n.js'; import { $i } from '@/i.js'; import { userPage } from '@/filters/user.js'; -import { checkWordMute } from '@/utility/check-word-mute.js'; +import { checkMutes } from '@/utility/check-word-mute.js'; import { pleaseLogin } from '@/utility/please-login.js'; import { showMovedDialog } from '@/utility/show-moved-dialog.js'; import MkRippleEffect from '@/components/MkRippleEffect.vue'; @@ -123,6 +105,7 @@ import { getNoteMenu } from '@/utility/get-note-menu.js'; import { boostMenuItems, computeRenoteTooltip } from '@/utility/boost-quote.js'; import { prefer } from '@/preferences.js'; import { useNoteCapture } from '@/use/use-note-capture.js'; +import SkMutedNote from '@/components/SkMutedNote.vue'; const props = withDefaults(defineProps<{ note: Misskey.entities.Note; @@ -183,34 +166,7 @@ async function removeReply(id: Misskey.entities.Note['id']) { } } -const inTimeline = inject<boolean>('inTimeline', false); -const tl_withSensitive = inject<Ref<boolean>>('tl_withSensitive', ref(true)); -const muted = ref(checkMute(appearNote.value, $i?.mutedWords)); - -/* Overload FunctionにLintが対応していないのでコメントアウト -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: true): boolean; -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: false): Array<string | string[]> | false | 'sensitiveMute'; -*/ -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly = false): Array<string | string[]> | 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; -} +const { muted } = checkMutes(appearNote.value); useNoteCapture({ rootEl: el, diff --git a/packages/frontend/src/components/SkMutedNote.vue b/packages/frontend/src/components/SkMutedNote.vue new file mode 100644 index 0000000000..4336a3abdc --- /dev/null +++ b/packages/frontend/src/components/SkMutedNote.vue @@ -0,0 +1,46 @@ +<!-- +SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors +SPDX-License-Identifier: AGPL-3.0-only +--> + +<template> +<I18n v-if="muted === 'sensitiveMute'" :src="i18n.ts.userSaysSomethingSensitive" tag="small"> + <template #name> + <MkUserName :user="note.user"/> + </template> +</I18n> +<I18n v-else-if="prefer.s.showSoftWordMutedWord" :src="i18n.ts.userSaysSomething" tag="small"> + <template #name> + <MkUserName :user="note.user"/> + </template> +</I18n> +<I18n v-else :src="i18n.ts.userSaysSomethingAbout" tag="small"> + <template #name> + <MkUserName :user="note.user"/> + </template> + <template #word> + {{ mutedWords }} + </template> +</I18n> +</template> + +<script setup lang="ts"> +import * as Misskey from 'misskey-js'; +import { computed } from 'vue'; +import { i18n } from '@/i18n.js'; +import { prefer } from '@/preferences.js'; + +const props = defineProps<{ + muted: false | 'sensitiveMute' | (string | string[])[]; + note: Misskey.entities.Note; + +}>(); + +const mutedWords = computed(() => Array.isArray(props.muted) + ? props.muted.map(words => Array.isArray(words) ? words.join() : words).join(' ') + : props.muted); +</script> + +<style module lang="scss"> + +</style> 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 </article> </div> <div v-else-if="!hardMuted" :class="$style.muted" @click="muted = false"> - <I18n v-if="muted === 'sensitiveMute'" :src="i18n.ts.userSaysSomethingSensitive" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - </I18n> - <I18n v-else-if="prefer.s.showSoftWordMutedWord" :src="i18n.ts.userSaysSomething" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - </I18n> - <I18n v-else :src="i18n.ts.userSaysSomethingAbout" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - <template #word> - {{ Array.isArray(muted) ? muted.map(words => Array.isArray(words) ? words.join() : words).slice(0, 3).join(' ') : muted }} - </template> - </I18n> + <SkMutedNote :muted="muted" :note="appearNote"></SkMutedNote> </div> <div v-else> <!-- @@ -224,7 +207,7 @@ import MkUsersTooltip from '@/components/MkUsersTooltip.vue'; import MkUrlPreview from '@/components/MkUrlPreview.vue'; import MkButton from '@/components/MkButton.vue'; import { pleaseLogin } from '@/utility/please-login.js'; -import { checkWordMute } from '@/utility/check-word-mute.js'; +import { checkMutes } from '@/utility/check-word-mute.js'; import { notePage } from '@/filters/note.js'; import { userPage } from '@/filters/user.js'; import number from '@/filters/number.js'; @@ -253,6 +236,7 @@ import { prefer } from '@/preferences.js'; import { getPluginHandlers } from '@/plugin.js'; import { DI } from '@/di.js'; import { useRouter } from '@/router.js'; +import SkMutedNote from '@/components/SkMutedNote.vue'; const props = withDefaults(defineProps<{ note: Misskey.entities.Note; @@ -272,8 +256,6 @@ const emit = defineEmits<{ const router = useRouter(); -const inTimeline = inject<boolean>('inTimeline', false); -const tl_withSensitive = inject<Ref<boolean>>('tl_withSensitive', ref(true)); const inChannel = inject('inChannel', null); const currentClip = inject<Ref<Misskey.entities.Clip> | null>('currentClip', null); @@ -327,8 +309,7 @@ const isLong = shouldCollapsed(appearNote.value, urls.value ?? []); const collapsed = ref(prefer.s.expandLongNote && appearNote.value.cw == null && isLong ? false : appearNote.value.cw == null && isLong); const isDeleted = ref(false); const renoted = ref(false); -const muted = ref(checkMute(appearNote.value, $i?.mutedWords)); -const hardMuted = ref(props.withHardMute && checkMute(appearNote.value, $i?.hardMutedWords, true)); +const { muted, hardMuted } = checkMutes(appearNote.value, props.withHardMute); const translation = ref<Misskey.entities.NotesTranslateResponse | null>(null); const translating = ref(false); const showTicker = (prefer.s.instanceTicker === 'always') || (prefer.s.instanceTicker === 'remote' && appearNote.value.user.instance); @@ -353,31 +334,6 @@ const mergedCW = computed(() => computeMergedCw(appearNote.value)); const renoteTooltip = computeRenoteTooltip(renoted); -/* Overload FunctionにLintが対応していないのでコメントアウト -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: true): boolean; -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: false): Array<string | string[]> | false | 'sensitiveMute'; -*/ -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly = false): Array<string | string[]> | 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; -} - let renoting = false; const keymap = { diff --git a/packages/frontend/src/components/SkNoteDetailed.vue b/packages/frontend/src/components/SkNoteDetailed.vue index 29886244ce..c499855a80 100644 --- a/packages/frontend/src/components/SkNoteDetailed.vue +++ b/packages/frontend/src/components/SkNoteDetailed.vue @@ -235,28 +235,7 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </div> <div v-else class="_panel" :class="$style.muted" @click="muted = false"> - <I18n v-if="muted === 'sensitiveMute'" :src="i18n.ts.userSaysSomethingSensitive" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - </I18n> - <I18n v-else-if="prefer.s.showSoftWordMutedWord" :src="i18n.ts.userSaysSomething" tag="small"> - <template #name> - <MkA v-user-preview="appearNote.userId" :to="userPage(appearNote.user)"> - <MkUserName :user="appearNote.user"/> - </MkA> - </template> - </I18n> - <I18n v-else :src="i18n.ts.userSaysSomethingAbout" tag="small"> - <template #name> - <MkA v-user-preview="appearNote.userId" :to="userPage(appearNote.user)"> - <MkUserName :user="appearNote.user"/> - </MkA> - </template> - <template #word> - {{ Array.isArray(muted) ? muted.map(words => Array.isArray(words) ? words.join() : words).slice(0, 3).join(' ') : muted }} - </template> - </I18n> + <SkMutedNote :muted="muted" :note="appearNote"></SkMutedNote> </div> </template> @@ -267,7 +246,6 @@ 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'; @@ -283,7 +261,7 @@ import MkUsersTooltip from '@/components/MkUsersTooltip.vue'; import MkUrlPreview from '@/components/MkUrlPreview.vue'; import SkInstanceTicker from '@/components/SkInstanceTicker.vue'; import { pleaseLogin } from '@/utility/please-login.js'; -import { checkWordMute } from '@/utility/check-word-mute.js'; +import { checkMutes } from '@/utility/check-word-mute.js'; import { userPage } from '@/filters/user.js'; import { notePage } from '@/filters/note.js'; import number from '@/filters/number.js'; @@ -313,6 +291,7 @@ import { getAppearNote } from '@/utility/get-appear-note.js'; import { prefer } from '@/preferences.js'; import { getPluginHandlers } from '@/plugin.js'; import { DI } from '@/di.js'; +import SkMutedNote from '@/components/SkMutedNote.vue'; const props = withDefaults(defineProps<{ note: Misskey.entities.Note; @@ -381,34 +360,7 @@ const mergedCW = computed(() => computeMergedCw(appearNote.value)); const renoteTooltip = computeRenoteTooltip(renoted); -const inTimeline = inject<boolean>('inTimeline', false); -const tl_withSensitive = inject<Ref<boolean>>('tl_withSensitive', ref(true)); -const muted = ref(checkMute(appearNote.value, $i?.mutedWords)); - -/* Overload FunctionにLintが対応していないのでコメントアウト -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: true): boolean; -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: false): Array<string | string[]> | false | 'sensitiveMute'; -*/ -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly = false): Array<string | string[]> | 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; -} +const { muted } = checkMutes(appearNote.value); watch(() => props.expandAllCws, (expandAllCws) => { if (expandAllCws !== showContent.value) showContent.value = expandAllCws; diff --git a/packages/frontend/src/components/SkNoteSub.vue b/packages/frontend/src/components/SkNoteSub.vue index 36bbf9b826..4c4fca2450 100644 --- a/packages/frontend/src/components/SkNoteSub.vue +++ b/packages/frontend/src/components/SkNoteSub.vue @@ -81,24 +81,7 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </div> <div v-else :class="$style.muted" @click="muted = false"> - <I18n v-if="muted === 'sensitiveMute'" :src="i18n.ts.userSaysSomethingSensitive" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - </I18n> - <I18n v-else-if="prefer.s.showSoftWordMutedWord" :src="i18n.ts.userSaysSomething" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - </I18n> - <I18n v-else :src="i18n.ts.userSaysSomethingAbout" tag="small"> - <template #name> - <MkUserName :user="appearNote.user"/> - </template> - <template #word> - {{ Array.isArray(muted) ? muted.map(words => Array.isArray(words) ? words.join() : words).slice(0, 3).join(' ') : muted }} - </template> - </I18n> + <SkMutedNote :muted="muted" :note="appearNote"></SkMutedNote> </div> </template> @@ -107,7 +90,6 @@ import { computed, inject, ref, shallowRef, watch } from 'vue'; import * as Misskey from 'misskey-js'; import { computeMergedCw } from '@@/js/compute-merged-cw.js'; import { host } from '@@/js/config.js'; -import type { Ref } from 'vue'; import type { Visibility } from '@/utility/boost-quote.js'; import type { OpenOnRemoteOptions } from '@/utility/please-login.js'; import SkNoteHeader from '@/components/SkNoteHeader.vue'; @@ -121,7 +103,7 @@ import { misskeyApi } from '@/utility/misskey-api.js'; import { i18n } from '@/i18n.js'; import { $i } from '@/i.js'; import { userPage } from '@/filters/user.js'; -import { checkWordMute } from '@/utility/check-word-mute.js'; +import { checkMutes } from '@/utility/check-word-mute.js'; import { pleaseLogin } from '@/utility/please-login.js'; import { showMovedDialog } from '@/utility/show-moved-dialog.js'; import MkRippleEffect from '@/components/MkRippleEffect.vue'; @@ -131,6 +113,7 @@ import { getNoteMenu } from '@/utility/get-note-menu.js'; import { boostMenuItems, computeRenoteTooltip } from '@/utility/boost-quote.js'; import { prefer } from '@/preferences.js'; import { useNoteCapture } from '@/use/use-note-capture.js'; +import SkMutedNote from '@/components/SkMutedNote.vue'; const props = withDefaults(defineProps<{ note: Misskey.entities.Note; @@ -197,34 +180,7 @@ async function removeReply(id: Misskey.entities.Note['id']) { } } -const inTimeline = inject<boolean>('inTimeline', false); -const tl_withSensitive = inject<Ref<boolean>>('tl_withSensitive', ref(true)); -const muted = ref(checkMute(appearNote.value, $i?.mutedWords)); - -/* Overload FunctionにLintが対応していないのでコメントアウト -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: true): boolean; -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: false): Array<string | string[]> | false | 'sensitiveMute'; -*/ -function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly = false): Array<string | string[]> | 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; -} +const { muted } = checkMutes(appearNote.value); useNoteCapture({ rootEl: el, diff --git a/packages/frontend/src/utility/check-word-mute.ts b/packages/frontend/src/utility/check-word-mute.ts index 2d8486760d..dc36ea1906 100644 --- a/packages/frontend/src/utility/check-word-mute.ts +++ b/packages/frontend/src/utility/check-word-mute.ts @@ -3,6 +3,42 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import * as Misskey from 'misskey-js'; +import { inject, ref } from 'vue'; +import type { Ref } from 'vue'; +import { $i } from '@/i'; + +export function checkMutes(noteToCheck: Misskey.entities.Note, withHardMute = false) { + const muted = ref(checkMute(noteToCheck, $i?.mutedWords)); + const hardMuted = ref(withHardMute && checkMute(noteToCheck, $i?.hardMutedWords, true)); + return { muted, hardMuted }; +} + +/* Overload FunctionにLintが対応していないのでコメントアウト +function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: true): boolean; +function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: false): Array<string | string[]> | false | 'sensitiveMute'; +*/ +export function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly = false): Array<string | string[]> | 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; + + const inTimeline = inject<boolean>('inTimeline', false); + const tl_withSensitive = inject<Ref<boolean> | null>('tl_withSensitive', null); + if (inTimeline && tl_withSensitive?.value === false && noteToCheck.files?.some((v) => v.isSensitive)) { + return 'sensitiveMute'; + } + + return false; +} export function checkWordMute(note: string | Misskey.entities.Note, me: Misskey.entities.UserLite | null | undefined, mutedWords: Array<string | string[]>): Array<string | string[]> | false { // 自分自身 |