diff options
| author | かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> | 2026-01-02 21:41:32 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-02 21:41:32 +0900 |
| commit | 9c225384541192bbd83da94ac2f6c09ade3a25e8 (patch) | |
| tree | b93b31accb31ce101a565b944f0c47e1c3f41261 | |
| parent | fix(frontend): ログインダイアログが表示されたあとの処理... (diff) | |
| download | misskey-9c225384541192bbd83da94ac2f6c09ade3a25e8.tar.gz misskey-9c225384541192bbd83da94ac2f6c09ade3a25e8.tar.bz2 misskey-9c225384541192bbd83da94ac2f6c09ade3a25e8.zip | |
fix(frontend): ファイルタブのセンシティブメディアを開く際に確認ダイアログを出す設定が適用されない問題を修正 (#17019)
* fix(frontend): ファイルタブのセンシティブメディアを開く際に確認ダイアログを出す設定が適用されない問題を修正
* Update Changelog
* refactor
* Update Changelog
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkMediaAudio.vue | 12 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkMediaBanner.vue | 15 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkMediaImage.vue | 13 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkMediaVideo.vue | 11 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkNoteMediaGrid.vue | 28 | ||||
| -rw-r--r-- | packages/frontend/src/utility/sensitive-file.ts | 33 |
7 files changed, 73 insertions, 40 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index e22dfba72a..669e6778ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Fix: ドライブクリーナーでファイルを削除しても画面に反映されない問題を修正 #16061 - Fix: 非ログイン時にログインを求めるダイアログが表示された後にダイアログのぼかしが解除されず操作不能になることがある問題を修正 - Fix: ドライブのソートが「登録日(昇順)」の場合に正しく動作しない問題を修正 +- Fix: ファイルタブのセンシティブメディアを開く際に確認ダイアログを出す設定が適用されない問題を修正 ### Server - Enhance: OAuthのクライアント情報取得(Client Information Discovery)において、IndieWeb Living Standard 11 July 2024で定義されているJSONドキュメント形式に対応しました diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index e3bb39549f..efcbf26a29 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -100,6 +100,7 @@ import { hms } from '@/filters/hms.js'; import MkMediaRange from '@/components/MkMediaRange.vue'; import { $i, iAmModerator } from '@/i.js'; import { prefer } from '@/preferences.js'; +import { canRevealFile, shouldHideFileByDefault } from '@/utility/sensitive-file.js'; const props = defineProps<{ audio: Misskey.entities.DriveFile; @@ -154,16 +155,11 @@ function hasFocus() { const playerEl = useTemplateRef('playerEl'); const audioEl = useTemplateRef('audioEl'); -// eslint-disable-next-line vue/no-setup-props-reactivity-loss -const hide = ref((prefer.s.nsfw === 'force' || prefer.s.dataSaver.media) ? true : (props.audio.isSensitive && prefer.s.nsfw !== 'ignore')); +const hide = ref(shouldHideFileByDefault(props.audio)); async function reveal() { - if (props.audio.isSensitive && prefer.s.confirmWhenRevealingSensitiveMedia) { - const { canceled } = await os.confirm({ - type: 'question', - text: i18n.ts.sensitiveMediaRevealConfirm, - }); - if (canceled) return; + if (!(await canRevealFile(props.audio))) { + return; } hide.value = false; diff --git a/packages/frontend/src/components/MkMediaBanner.vue b/packages/frontend/src/components/MkMediaBanner.vue index 7730e01a9f..fd86b61b87 100644 --- a/packages/frontend/src/components/MkMediaBanner.vue +++ b/packages/frontend/src/components/MkMediaBanner.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <div :class="$style.root"> <MkMediaAudio v-if="media.type.startsWith('audio') && media.type !== 'audio/midi'" :audio="media"/> - <div v-else-if="media.isSensitive && hide" :class="$style.sensitive" @click="reveal"> + <div v-else-if="hide" :class="$style.sensitive" @click="reveal"> <span style="font-size: 1.6em;"><i class="ti ti-alert-triangle"></i></span> <b>{{ i18n.ts.sensitive }}</b> <span>{{ i18n.ts.clickToShow }}</span> @@ -27,23 +27,18 @@ SPDX-License-Identifier: AGPL-3.0-only import { ref } from 'vue'; import * as Misskey from 'misskey-js'; import { i18n } from '@/i18n.js'; -import * as os from '@/os.js'; import MkMediaAudio from '@/components/MkMediaAudio.vue'; -import { prefer } from '@/preferences.js'; +import { shouldHideFileByDefault, canRevealFile } from '@/utility/sensitive-file.js'; const props = defineProps<{ media: Misskey.entities.DriveFile; }>(); -const hide = ref(true); +const hide = ref(shouldHideFileByDefault(props.media)); async function reveal() { - if (props.media.isSensitive && prefer.s.confirmWhenRevealingSensitiveMedia) { - const { canceled } = await os.confirm({ - type: 'question', - text: i18n.ts.sensitiveMediaRevealConfirm, - }); - if (canceled) return; + if (!(await canRevealFile(props.media))) { + return; } hide.value = false; diff --git a/packages/frontend/src/components/MkMediaImage.vue b/packages/frontend/src/components/MkMediaImage.vue index f59d15d9a2..345c261776 100644 --- a/packages/frontend/src/components/MkMediaImage.vue +++ b/packages/frontend/src/components/MkMediaImage.vue @@ -77,6 +77,7 @@ import { i18n } from '@/i18n.js'; import * as os from '@/os.js'; import { $i, iAmModerator } from '@/i.js'; import { prefer } from '@/preferences.js'; +import { shouldHideFileByDefault, canRevealFile } from '@/utility/sensitive-file.js'; const props = withDefaults(defineProps<{ image: Misskey.entities.DriveFile; @@ -106,12 +107,8 @@ async function reveal(ev: MouseEvent) { if (hide.value) { ev.stopPropagation(); - if (props.image.isSensitive && prefer.s.confirmWhenRevealingSensitiveMedia) { - const { canceled } = await os.confirm({ - type: 'question', - text: i18n.ts.sensitiveMediaRevealConfirm, - }); - if (canceled) return; + if (!(await canRevealFile(props.image))) { + return; } hide.value = false; @@ -119,8 +116,8 @@ async function reveal(ev: MouseEvent) { } // Plugin:register_note_view_interruptor を使って書き換えられる可能性があるためwatchする -watch(() => props.image, () => { - hide.value = (prefer.s.nsfw === 'force' || prefer.s.dataSaver.media) ? true : (props.image.isSensitive && prefer.s.nsfw !== 'ignore'); +watch(() => props.image, (newImage) => { + hide.value = shouldHideFileByDefault(newImage); }, { deep: true, immediate: true, diff --git a/packages/frontend/src/components/MkMediaVideo.vue b/packages/frontend/src/components/MkMediaVideo.vue index b0f7a909d3..63db3c3ab5 100644 --- a/packages/frontend/src/components/MkMediaVideo.vue +++ b/packages/frontend/src/components/MkMediaVideo.vue @@ -124,6 +124,7 @@ import hasAudio from '@/utility/media-has-audio.js'; import MkMediaRange from '@/components/MkMediaRange.vue'; import { $i, iAmModerator } from '@/i.js'; import { prefer } from '@/preferences.js'; +import { shouldHideFileByDefault, canRevealFile } from '@/utility/sensitive-file.js'; const props = defineProps<{ video: Misskey.entities.DriveFile; @@ -176,15 +177,11 @@ function hasFocus() { } // eslint-disable-next-line vue/no-setup-props-reactivity-loss -const hide = ref((prefer.s.nsfw === 'force' || prefer.s.dataSaver.media) ? true : (props.video.isSensitive && prefer.s.nsfw !== 'ignore')); +const hide = ref(shouldHideFileByDefault(props.video)); async function reveal() { - if (props.video.isSensitive && prefer.s.confirmWhenRevealingSensitiveMedia) { - const { canceled } = await os.confirm({ - type: 'question', - text: i18n.ts.sensitiveMediaRevealConfirm, - }); - if (canceled) return; + if (!(await canRevealFile(props.video))) { + return; } hide.value = false; diff --git a/packages/frontend/src/components/MkNoteMediaGrid.vue b/packages/frontend/src/components/MkNoteMediaGrid.vue index 7e900b28fa..e46456d614 100644 --- a/packages/frontend/src/components/MkNoteMediaGrid.vue +++ b/packages/frontend/src/components/MkNoteMediaGrid.vue @@ -6,14 +6,9 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <template v-for="file in note.files"> <div - v-if="((( - (prefer.s.nsfw === 'force' || file.isSensitive) && - prefer.s.nsfw !== 'ignore' - ) || (prefer.s.dataSaver.media && file.type.startsWith('image/'))) && - !showingFiles.has(file.id) - )" + v-if="isHiding(file)" :class="[$style.filePreview, { [$style.square]: square }]" - @click="showingFiles.add(file.id)" + @click="reveal(file)" > <MkDriveFileThumbnail :file="file" @@ -49,6 +44,7 @@ import * as Misskey from 'misskey-js'; import { notePage } from '@/filters/note.js'; import { i18n } from '@/i18n.js'; import { prefer } from '@/preferences.js'; +import { shouldHideFileByDefault, canRevealFile } from '@/utility/sensitive-file.js'; import bytes from '@/filters/bytes.js'; import MkDriveFileThumbnail from '@/components/MkDriveFileThumbnail.vue'; @@ -59,6 +55,24 @@ defineProps<{ }>(); const showingFiles = ref<Set<string>>(new Set()); + +function isHiding(file: Misskey.entities.DriveFile) { + if (shouldHideFileByDefault(file) && !showingFiles.value.has(file.id)) { + if (!file.isSensitive && !file.type.startsWith('image/')) { + return false; + } + return true; + } + return false; +} + +async function reveal(file: Misskey.entities.DriveFile) { + if (!(await canRevealFile(file))) { + return; + } + + showingFiles.value.add(file.id); +} </script> <style lang="scss" module> diff --git a/packages/frontend/src/utility/sensitive-file.ts b/packages/frontend/src/utility/sensitive-file.ts new file mode 100644 index 0000000000..f1fc909e4a --- /dev/null +++ b/packages/frontend/src/utility/sensitive-file.ts @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import * as Misskey from 'misskey-js'; +import * as os from '@/os.js'; +import { prefer } from '@/preferences.js'; +import { i18n } from '@/i18n.js'; + +export function shouldHideFileByDefault(file: Misskey.entities.DriveFile): boolean { + if (prefer.s.nsfw === 'force' || prefer.s.dataSaver.media) { + return true; + } + + if (file.isSensitive && prefer.s.nsfw !== 'ignore') { + return true; + } + + return false; +} + +export async function canRevealFile(file: Misskey.entities.DriveFile): Promise<boolean> { + if (file.isSensitive && prefer.s.confirmWhenRevealingSensitiveMedia) { + const { canceled } = await os.confirm({ + type: 'question', + text: i18n.ts.sensitiveMediaRevealConfirm, + }); + if (canceled) return false; + } + + return true; +} |