summaryrefslogtreecommitdiff
path: root/packages/frontend/src
diff options
context:
space:
mode:
authorHazelnoot <acomputerdog@gmail.com>2025-05-12 23:28:55 -0400
committerHazelnoot <acomputerdog@gmail.com>2025-05-12 23:28:55 -0400
commitb52db71e1894e25cebfafc782d2cec86705e2cbb (patch)
treec3444a49a9507403a5e6cbd0a7f1a8fd4a0e10d9 /packages/frontend/src
parentsimplify access to showSoftWordMutedWord (diff)
downloadsharkey-b52db71e1894e25cebfafc782d2cec86705e2cbb.tar.gz
sharkey-b52db71e1894e25cebfafc782d2cec86705e2cbb.tar.bz2
sharkey-b52db71e1894e25cebfafc782d2cec86705e2cbb.zip
factor out shared word mute logic
Diffstat (limited to 'packages/frontend/src')
-rw-r--r--packages/frontend/src/components/MkNote.vue52
-rw-r--r--packages/frontend/src/components/MkNoteDetailed.vue56
-rw-r--r--packages/frontend/src/components/MkNoteSub.vue54
-rw-r--r--packages/frontend/src/components/SkMutedNote.vue46
-rw-r--r--packages/frontend/src/components/SkNote.vue52
-rw-r--r--packages/frontend/src/components/SkNoteDetailed.vue56
-rw-r--r--packages/frontend/src/components/SkNoteSub.vue52
-rw-r--r--packages/frontend/src/utility/check-word-mute.ts36
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 {
// 自分自身