From 9760f3d7c9113f5436732bf6d6e454b253061b1d Mon Sep 17 00:00:00 2001 From: taichan <40626578+tai-cha@users.noreply.github.com> Date: Tue, 14 Jan 2025 22:49:59 +0900 Subject: [PATCH] =?UTF-8?q?enhance(frontend):=20=E3=83=AF=E3=83=BC?= =?UTF-8?q?=E3=83=89=E3=83=9F=E3=83=A5=E3=83=BC=E3=83=88=E3=81=A7=E5=BC=95?= =?UTF-8?q?=E3=81=A3=E3=81=8B=E3=81=8B=E3=81=A3=E3=81=9F=E3=83=AF=E3=83=BC?= =?UTF-8?q?=E3=83=89=E3=82=92=E8=A1=A8=E7=A4=BA=E5=8F=AF=E8=83=BD=E3=81=AB?= =?UTF-8?q?=E3=81=99=E3=82=8B=20(#15195)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(frontend): ソフトミュートã§å¼•ã£ã‹ã‹ã£ãŸã‚‚ã®ã‚’表示ã§ãるよã†ã« * ソフトワードミュートã®ãƒŸãƒ¥ãƒ¼ãƒˆæ–‡å—列表示を切り替ãˆå¯èƒ½ã« * Chore(docs): Update CHANGELOG * Fix: language file * Fixed by review * Fix by review * Fix: reloadAskãªãŠã—ãã‚Œã¦ã„ãªã‹ã£ãŸ * perf: filter -> findã«å¤‰æ›´ã—ã¦æœ€åˆã®ä¸€å€‹ã®ã¿ã‚’表示ã™ã‚‹ã‚ˆã†ã«å¤‰æ›´ * Revert "perf: filter -> findã«å¤‰æ›´ã—ã¦æœ€åˆã®ä¸€å€‹ã®ã¿ã‚’表示ã™ã‚‹ã‚ˆã†ã«å¤‰æ›´" This reverts commit 72ef92f0d62828754702cd00e26ad873adb4652f. --- CHANGELOG.md | 1 + locales/index.d.ts | 8 +++++ locales/ja-JP.yml | 2 ++ packages/frontend/src/components/MkNote.vue | 32 ++++++++++++++----- .../src/pages/settings/mute-block.vue | 14 +++++++- .../frontend/src/scripts/check-word-mute.ts | 6 ++-- packages/frontend/src/store.ts | 6 +++- 7 files changed, 56 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9380f23cfb..0319cb8c30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Enhance: PCç”»é¢ã§ãƒãƒ£ãƒ³ãƒãƒ«ãŒè¤‡æ•°åˆ—ã§è¡¨ç¤ºã•ã‚Œã‚‹ã‚ˆã†ã« (Cherry-picked from https://github.com/Otaku-Social/maniakey/pull/13) - Enhance: 照会ã«å¤±æ•—ã—ãŸå ´åˆã€ãã®ç†ç”±ã‚’表示ã™ã‚‹ã‚ˆã†ã« +- Enhance: ワードミュートã§æ¤œçŸ¥ã•ã‚ŒãŸãƒ¯ãƒ¼ãƒ‰ã‚’表示ã§ãるよã†ã« - Enhance: リモートã®ãƒŽãƒ¼ãƒˆã®ãƒªãƒ³ã‚¯ã‚’コピーã§ãるよã†ã« - Enhance: 連åˆãŒãƒ›ãƒ¯ã‚¤ãƒˆãƒªã‚¹ãƒˆåŒ–・無効化ã•ã‚Œã¦ã„るサーãƒãƒ¼å‘ã‘ã®ãƒ‡ã‚¶ã‚¤ãƒ³ä¿®æ£ - Enhance: AiScriptã®ã‚»ãƒ¼ãƒ–データを明示的ã«å‰Šé™¤ã™ã‚‹é–¢æ•°`Mk:remove`ã‚’è¿½åŠ diff --git a/locales/index.d.ts b/locales/index.d.ts index 453d40feea..001dca29aa 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -2762,6 +2762,10 @@ export interface Locale extends ILocale { * ãƒãƒ¼ãƒ‰ãƒ¯ãƒ¼ãƒ‰ãƒŸãƒ¥ãƒ¼ãƒˆ */ "hardWordMute": string; + /** + * ミュートã•ã‚ŒãŸãƒ¯ãƒ¼ãƒ‰ã‚’表示 + */ + "showMutedWord": string; /** * 指定ã—ãŸèªžå¥ã‚’å«ã‚€ãƒŽãƒ¼ãƒˆã‚’éš ã—ã¾ã™ã€‚ワードミュートã¨ã¯ç•°ãªã‚Šã€ãƒŽãƒ¼ãƒˆã¯å®Œå…¨ã«è¡¨ç¤ºã•ã‚Œãªããªã‚Šã¾ã™ã€‚ */ @@ -2782,6 +2786,10 @@ export interface Locale extends ILocale { * {name}ãŒä½•ã‹ã‚’言ã„ã¾ã—㟠*/ "userSaysSomething": ParameterizedString<"name">; + /** + * {name}ãŒã€Œ{word}ã€ã«ã¤ã„ã¦ä½•ã‹ã‚’言ã„ã¾ã—㟠+ */ + "userSaysSomethingAbout": ParameterizedString<"name" | "word">; /** * アクティブã«ã™ã‚‹ */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index ad9d9bea4b..2a8fd94522 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -687,11 +687,13 @@ testEmail: "é…信テスト" wordMute: "ワードミュート" wordMuteDescription: "指定ã—ãŸèªžå¥ã‚’å«ã‚€ãƒŽãƒ¼ãƒˆã‚’最å°åŒ–ã—ã¾ã™ã€‚最å°åŒ–ã•ã‚ŒãŸãƒŽãƒ¼ãƒˆã‚’クリックã™ã‚‹ã“ã¨ã§è¡¨ç¤ºã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" hardWordMute: "ãƒãƒ¼ãƒ‰ãƒ¯ãƒ¼ãƒ‰ãƒŸãƒ¥ãƒ¼ãƒˆ" +showMutedWord: "ミュートã•ã‚ŒãŸãƒ¯ãƒ¼ãƒ‰ã‚’表示" hardWordMuteDescription: "指定ã—ãŸèªžå¥ã‚’å«ã‚€ãƒŽãƒ¼ãƒˆã‚’éš ã—ã¾ã™ã€‚ワードミュートã¨ã¯ç•°ãªã‚Šã€ãƒŽãƒ¼ãƒˆã¯å®Œå…¨ã«è¡¨ç¤ºã•ã‚Œãªããªã‚Šã¾ã™ã€‚" regexpError: "æ£è¦è¡¨ç¾ã‚¨ãƒ©ãƒ¼" regexpErrorDescription: "{tab}ワードミュートã®{line}行目ã®æ£è¦è¡¨ç¾ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ:" instanceMute: "サーãƒãƒ¼ãƒŸãƒ¥ãƒ¼ãƒˆ" userSaysSomething: "{name}ãŒä½•ã‹ã‚’言ã„ã¾ã—ãŸ" +userSaysSomethingAbout: "{name}ãŒã€Œ{word}ã€ã«ã¤ã„ã¦ä½•ã‹ã‚’言ã„ã¾ã—ãŸ" makeActive: "アクティブã«ã™ã‚‹" display: "表示" copy: "コピー" diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 1a8814b7cb..4c26444b35 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -150,13 +150,23 @@ SPDX-License-Identifier: AGPL-3.0-only </MkA> </template> </I18n> - <I18n v-else :src="i18n.ts.userSaysSomething" tag="small"> + <I18n v-else-if="showSoftWordMutedWord !== true" :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> </div> <div v-else> <!-- @@ -272,6 +282,7 @@ const collapsed = ref(appearNote.value.cw == null && isLong); const isDeleted = ref(false); const muted = ref(checkMute(appearNote.value, $i?.mutedWords)); const hardMuted = ref(props.withHardMute && checkMute(appearNote.value, $i?.hardMutedWords, true)); +const showSoftWordMutedWord = computed(() => defaultStore.state.showSoftWordMutedWord); const translation = ref<Misskey.entities.NotesTranslateResponse | null>(null); const translating = ref(false); const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance); @@ -290,14 +301,19 @@ const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({ /* 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): boolean | 'sensitiveMute'; +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): boolean | 'sensitiveMute' { - if (mutedWords != null) { - if (checkWordMute(noteToCheck, $i, mutedWords)) return true; - if (noteToCheck.reply && checkWordMute(noteToCheck.reply, $i, mutedWords)) return true; - if (noteToCheck.renote && checkWordMute(noteToCheck.renote, $i, mutedWords)) return true; - } +function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly = false): Array<string | string[]> | false | 'sensitiveMute' { + if (mutedWords == null) return false; + + 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; diff --git a/packages/frontend/src/pages/settings/mute-block.vue b/packages/frontend/src/pages/settings/mute-block.vue index d32d4842bd..4caa556b15 100644 --- a/packages/frontend/src/pages/settings/mute-block.vue +++ b/packages/frontend/src/pages/settings/mute-block.vue @@ -11,6 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div class="_gaps_m"> <MkInfo>{{ i18n.ts.wordMuteDescription }}</MkInfo> + <MkSwitch v-model="showSoftWordMutedWord">{{ i18n.ts.showMutedWord }}</MkSwitch> <XWordMute :muted="$i.mutedWords" @save="saveMutedWords"/> </div> </MkFolder> @@ -132,7 +133,7 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { ref, computed } from 'vue'; +import { ref, computed, watch } from 'vue'; import XInstanceMute from './mute-block.instance-mute.vue'; import XWordMute from './mute-block.word-mute.vue'; import MkPagination from '@/components/MkPagination.vue'; @@ -146,6 +147,9 @@ import { instance, infoImageUrl } from '@/instance.js'; import { signinRequired } from '@/account.js'; import MkInfo from '@/components/MkInfo.vue'; import MkFolder from '@/components/MkFolder.vue'; +import MkSwitch from '@/components/MkSwitch.vue'; +import { defaultStore } from '@/store'; +import { reloadAsk } from '@/scripts/reload-ask.js'; const $i = signinRequired(); @@ -168,6 +172,14 @@ const expandedRenoteMuteItems = ref([]); const expandedMuteItems = ref([]); const expandedBlockItems = ref([]); +const showSoftWordMutedWord = computed(defaultStore.makeGetterSetter('showSoftWordMutedWord')); + +watch([ + showSoftWordMutedWord, +], async () => { + await reloadAsk({ reason: i18n.ts.reloadToApplySetting, unison: true }); +}); + async function unrenoteMute(user, ev) { os.popupMenu([{ text: i18n.ts.renoteUnmute, diff --git a/packages/frontend/src/scripts/check-word-mute.ts b/packages/frontend/src/scripts/check-word-mute.ts index 0a37a08bf0..98fea1bced 100644 --- a/packages/frontend/src/scripts/check-word-mute.ts +++ b/packages/frontend/src/scripts/check-word-mute.ts @@ -4,7 +4,7 @@ */ import * as Misskey from 'misskey-js'; -export function checkWordMute(note: Misskey.entities.Note, me: Misskey.entities.UserLite | null | undefined, mutedWords: Array<string | string[]>): boolean { +export function checkWordMute(note: Misskey.entities.Note, me: Misskey.entities.UserLite | null | undefined, mutedWords: Array<string | string[]>): Array<string | string[]> | false { // 自分自身 if (me && (note.userId === me.id)) return false; @@ -13,7 +13,7 @@ export function checkWordMute(note: Misskey.entities.Note, me: Misskey.entities. if (text === '') return false; - const matched = mutedWords.some(filter => { + const matched = mutedWords.filter(filter => { if (Array.isArray(filter)) { // Clean up const filteredFilter = filter.filter(keyword => keyword !== ''); @@ -36,7 +36,7 @@ export function checkWordMute(note: Misskey.entities.Note, me: Misskey.entities. } }); - if (matched) return true; + if (matched.length > 0) return matched; } return false; diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index 1d981e897b..dbe90dba86 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -9,10 +9,10 @@ import { hemisphere } from '@@/js/intl-const.js'; import lightTheme from '@@/themes/l-light.json5'; import darkTheme from '@@/themes/d-green-lime.json5'; import type { SoundType } from '@/scripts/sound.js'; +import type { Ast } from '@syuilo/aiscript'; import { DEFAULT_DEVICE_KIND, type DeviceKind } from '@/scripts/device-kind.js'; import { miLocalStorage } from '@/local-storage.js'; import { Storage } from '@/pizzax.js'; -import type { Ast } from '@syuilo/aiscript'; interface PostFormAction { title: string, @@ -474,6 +474,10 @@ export const defaultStore = markRaw(new Storage('base', { where: 'device', default: true, }, + showSoftWordMutedWord: { + where: 'device', + default: false, + }, sound_masterVolume: { where: 'device', -- GitLab