diff options
Diffstat (limited to 'packages/frontend/src/components')
| -rw-r--r-- | packages/frontend/src/components/MkMediaAudio.vue | 14 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkMediaBanner.vue | 26 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkMediaImage.vue | 12 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkMediaList.vue | 8 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkMediaVideo.vue | 14 |
5 files changed, 57 insertions, 17 deletions
diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index 582cf238c0..a080550ddf 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only @contextmenu.stop @keydown.stop > - <button v-if="hide" :class="$style.hidden" @click="hide = false"> + <button v-if="hide" :class="$style.hidden" @click="show"> <div :class="$style.hiddenTextWrapper"> <b v-if="audio.isSensitive" style="display: block;"><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}{{ defaultStore.state.dataSaver.media ? ` (${i18n.ts.audio}${audio.size ? ' ' + bytes(audio.size) : ''})` : '' }}</b> <b v-else style="display: block;"><i class="ti ti-music"></i> {{ defaultStore.state.dataSaver.media && audio.size ? bytes(audio.size) : i18n.ts.audio }}</b> @@ -156,6 +156,18 @@ const audioEl = shallowRef<HTMLAudioElement>(); // eslint-disable-next-line vue/no-setup-props-reactivity-loss const hide = ref((defaultStore.state.nsfw === 'force' || defaultStore.state.dataSaver.media) ? true : (props.audio.isSensitive && defaultStore.state.nsfw !== 'ignore')); +async function show() { + if (props.audio.isSensitive && defaultStore.state.confirmWhenRevealingSensitiveMedia) { + const { canceled } = await os.confirm({ + type: 'question', + text: i18n.ts.sensitiveMediaRevealConfirm, + }); + if (canceled) return; + } + + hide.value = false; +} + // Menu const menuShowing = ref(false); diff --git a/packages/frontend/src/components/MkMediaBanner.vue b/packages/frontend/src/components/MkMediaBanner.vue index a219848b7f..11995e1f3b 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="hide = false"> + <div v-else-if="media.isSensitive && hide" :class="$style.sensitive" @click="show"> <span style="font-size: 1.6em;"><i class="ti ti-alert-triangle"></i></span> <b>{{ i18n.ts.sensitive }}</b> <span>{{ i18n.ts.clickToShow }}</span> @@ -24,24 +24,30 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { shallowRef, watch, ref } from 'vue'; +import { ref } from 'vue'; import * as Misskey from 'misskey-js'; import { i18n } from '@/i18n.js'; +import { defaultStore } from '@/store.js'; +import * as os from '@/os.js'; import MkMediaAudio from '@/components/MkMediaAudio.vue'; -const props = withDefaults(defineProps<{ +const props = defineProps<{ media: Misskey.entities.DriveFile; -}>(), { -}); +}>(); -const audioEl = shallowRef<HTMLAudioElement>(); const hide = ref(true); -watch(audioEl, () => { - if (audioEl.value) { - audioEl.value.volume = 0.3; +async function show() { + if (props.media.isSensitive && defaultStore.state.confirmWhenRevealingSensitiveMedia) { + const { canceled } = await os.confirm({ + type: 'question', + text: i18n.ts.sensitiveMediaRevealConfirm, + }); + if (canceled) return; } -}); + + hide.value = false; +} </script> <style lang="scss" module> diff --git a/packages/frontend/src/components/MkMediaImage.vue b/packages/frontend/src/components/MkMediaImage.vue index 82f36fe5c4..0d1409e2c8 100644 --- a/packages/frontend/src/components/MkMediaImage.vue +++ b/packages/frontend/src/components/MkMediaImage.vue @@ -83,11 +83,21 @@ const url = computed(() => (props.raw || defaultStore.state.loadRawImages) : props.image.thumbnailUrl, ); -function onclick() { +async function onclick(ev: MouseEvent) { if (!props.controls) { return; } + if (hide.value) { + ev.stopPropagation(); + if (props.image.isSensitive && defaultStore.state.confirmWhenRevealingSensitiveMedia) { + const { canceled } = await os.confirm({ + type: 'question', + text: i18n.ts.sensitiveMediaRevealConfirm, + }); + if (canceled) return; + } + hide.value = false; } } diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue index 24b177d255..2300802dcf 100644 --- a/packages/frontend/src/components/MkMediaList.vue +++ b/packages/frontend/src/components/MkMediaList.vue @@ -138,15 +138,13 @@ onMounted(() => { pswpModule: PhotoSwipe, }); - lightbox.on('itemData', (ev) => { - const { itemData } = ev; - + lightbox.addFilter('itemData', (itemData) => { // element is children const { element } = itemData; const id = element?.dataset.id; const file = props.mediaList.find(media => media.id === id); - if (!file) return; + if (!file) return itemData; itemData.src = file.url; itemData.w = Number(file.properties.width); @@ -158,6 +156,8 @@ onMounted(() => { itemData.alt = file.comment ?? file.name; itemData.comment = file.comment ?? file.name; itemData.thumbCropped = true; + + return itemData; }); lightbox.on('uiRegister', () => { diff --git a/packages/frontend/src/components/MkMediaVideo.vue b/packages/frontend/src/components/MkMediaVideo.vue index 0ec0039df4..7c5a365148 100644 --- a/packages/frontend/src/components/MkMediaVideo.vue +++ b/packages/frontend/src/components/MkMediaVideo.vue @@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only @contextmenu.stop @keydown.stop > - <button v-if="hide" :class="$style.hidden" @click="hide = false"> + <button v-if="hide" :class="$style.hidden" @click="show"> <div :class="$style.hiddenTextWrapper"> <b v-if="video.isSensitive" style="display: block;"><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}{{ defaultStore.state.dataSaver.media ? ` (${i18n.ts.video}${video.size ? ' ' + bytes(video.size) : ''})` : '' }}</b> <b v-else style="display: block;"><i class="ti ti-movie"></i> {{ defaultStore.state.dataSaver.media && video.size ? bytes(video.size) : i18n.ts.video }}</b> @@ -176,6 +176,18 @@ function hasFocus() { // eslint-disable-next-line vue/no-setup-props-reactivity-loss const hide = ref((defaultStore.state.nsfw === 'force' || defaultStore.state.dataSaver.media) ? true : (props.video.isSensitive && defaultStore.state.nsfw !== 'ignore')); +async function show() { + if (props.video.isSensitive && defaultStore.state.confirmWhenRevealingSensitiveMedia) { + const { canceled } = await os.confirm({ + type: 'question', + text: i18n.ts.sensitiveMediaRevealConfirm, + }); + if (canceled) return; + } + + hide.value = false; +} + // Menu const menuShowing = ref(false); |