feat: require double click for sensitive images

This commit is contained in:
オスカー、 2024-07-20 22:21:57 +09:00
parent 8bd86ce456
commit 7d4383c449
Signed by: SWREI
GPG Key ID: 139D6573F92DA9F7
6 changed files with 83 additions and 10 deletions

View File

@ -616,7 +616,7 @@ addedRelays: "추가된 릴레이"
serviceworkerInfo: "푸시 알림을 수행하려면 활성화해야 합니다."
deletedNote: "삭제된 노트"
invisibleNote: "비공개 노트"
enableInfiniteScroll: "자동으로 더 보기"
enableInfiniteScroll: "스크롤해서 더 보기"
visibility: "공개 범위"
poll: "투표"
useCw: "내용 숨기기"
@ -1227,7 +1227,7 @@ overwriteContentConfirm: "현재 내용을 덮어쓰기 합니다. 계속 진행
seasonalScreenEffect: "계절에 따른 효과 보이기"
decorate: "장식하기"
addMfmFunction: "장식 추가하기"
enableQuickAddMfmFunction: "상급자용 MFM 선택기 표시하기"
enableQuickAddMfmFunction: "상급자용 MFM 선택기 표시"
bubbleGame: "버블 게임"
sfx: "효과음"
soundWillBePlayed: "소리가 재생됩니다"
@ -1242,7 +1242,7 @@ backToTitle: "타이틀로 가기"
hemisphere: "거주 지역"
withSensitive: "민감한 파일이 포함된 노트 보기"
userSaysSomethingSensitive: "{name} 같은 민감한 파일이 포함된 글"
enableHorizontalSwipe: "스와이프하여 탭 전환"
enableHorizontalSwipe: "밀어서 탭 간 전환하기"
loading: "불러오는 중"
surrender: "그만두기"
gameRetry: "다시 시도"
@ -1252,6 +1252,8 @@ useBackupCode: "백업 코드 사용"
launchApp: "앱 실행"
useNativeUIForVideoAudioPlayer: "브라우저 UI에서 미디어 재생"
here: "여기"
hideMutedNotes: "단어 뮤트된 노트를 완전히 숨기기"
alwaysConfirmFollow: "팔로우할 때 항상 확인하기"
credits: "엔딩 크레딧"
timeWillCome: "언젠가 이 칸에 당신의 이름이 쓰여지는 날이 올까요?"
thankYou: "오스카는 당신과 함께 서핑할 것입니다. 언제까지고."

View File

@ -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="showHiddenContent">
<div v-else-if="media.isSensitive && hide" :class="$style.sensitive" @click="showHiddenContent" @dblclick="showHiddenContentDouble">
<span style="font-size: 1.6em;"><i class="ti ti-alert-triangle"></i></span>
<b>{{ i18n.ts.sensitive }}</b>
<span>{{ i18n.ts.clickToShow }}</span>
@ -30,6 +30,7 @@ import { i18n } from '@/i18n.js';
import MkMediaAudio from '@/components/MkMediaAudio.vue';
import { pleaseLogin } from '@/scripts/please-login.js';
import { $i } from '@/account.js';
import { defaultStore } from '@/store.js';
const props = withDefaults(defineProps<{
media: Misskey.entities.DriveFile;
@ -40,6 +41,25 @@ const audioEl = shallowRef<HTMLAudioElement>();
const hide = ref(true);
function showHiddenContent(ev: MouseEvent) {
if (defaultStore.state.sensitiveDoubleClickRequired) {
return;
}
if (props.media.isSensitive && !$i) {
ev.preventDefault();
ev.stopPropagation();
pleaseLogin();
return;
}
if (hide.value) {
ev.preventDefault();
ev.stopPropagation();
hide.value = false;
}
}
function showHiddenContentDouble(ev: MouseEvent) {
if (props.media.isSensitive && !$i) {
ev.preventDefault();
ev.stopPropagation();

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div :class="[hide ? $style.hidden : $style.visible, (image.isSensitive && defaultStore.state.highlightSensitiveMedia) && $style.sensitive]" :style="darkMode ? '--c: rgb(255 255 255 / 2%);' : '--c: rgb(0 0 0 / 2%);'" @click="showHiddenContent">
<div :class="[hide ? $style.hidden : $style.visible, (image.isSensitive && defaultStore.state.highlightSensitiveMedia) && $style.sensitive]" :style="darkMode ? '--c: rgb(255 255 255 / 2%);' : '--c: rgb(0 0 0 / 2%);'" @click="showHiddenContent" @dblclick="showHiddenContentDouble">
<component
:is="(image.isSensitive && !$i) || disableImageLink ? 'div' : 'a'"
v-bind="(image.isSensitive && !$i) || disableImageLink ? {
@ -135,6 +135,29 @@ function showHiddenContent(ev: MouseEvent) {
return;
}
if (defaultStore.state.sensitiveDoubleClickRequired) {
return;
}
if (props.image.isSensitive && !$i) {
ev.preventDefault();
ev.stopPropagation();
pleaseLogin();
return;
}
if (hide.value) {
ev.preventDefault();
ev.stopPropagation();
hide.value = false;
}
}
function showHiddenContentDouble(ev: MouseEvent) {
if (!props.controls) {
return;
}
if (props.image.isSensitive && !$i) {
ev.preventDefault();
ev.stopPropagation();

View File

@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@contextmenu.stop
@keydown.stop
>
<button v-if="hide" :class="$style.hidden" @click="showHiddenContent">
<button v-if="hide" :class="$style.hidden" @click="showHiddenContent" @dblclick="showHiddenContentDouble">
<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>
@ -255,6 +255,25 @@ function showMenu(ev: MouseEvent) {
}
function showHiddenContent(ev: MouseEvent) {
if (defaultStore.state.sensitiveDoubleClickRequired) {
return;
}
if (props.video.isSensitive && !$i) {
ev.preventDefault();
ev.stopPropagation();
pleaseLogin();
return;
}
if (hide.value) {
ev.preventDefault();
ev.stopPropagation();
hide.value = false;
}
}
function showHiddenContentDouble(ev: MouseEvent) {
if (props.video.isSensitive && !$i) {
ev.preventDefault();
ev.stopPropagation();

View File

@ -170,6 +170,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="disableStreamingTimeline">{{ i18n.ts.disableStreamingTimeline }}</MkSwitch>
<MkSwitch v-model="enableHorizontalSwipe">{{ i18n.ts.enableHorizontalSwipe }}</MkSwitch>
<MkSwitch v-model="alwaysConfirmFollow">{{ i18n.ts.alwaysConfirmFollow }}</MkSwitch>
<MkSwitch v-model="sensitiveDoubleClickRequired">{{ i18n.ts.sensitiveDoubleClickRequired }}</MkSwitch>
</div>
<MkSelect v-model="serverDisconnectedBehavior">
<template #label>{{ i18n.ts.whenServerDisconnected }}</template>

View File

@ -80,10 +80,6 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'account',
default: true,
},
hideDirectMessages: {
where: 'deviceAccount',
default: false,
},
showFullAcct: {
where: 'account',
default: false,
@ -160,6 +156,14 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'deviceAccount',
default: false,
},
hideSensitiveInformation: {
where: 'device',
default: false,
},
hideDirectMessages: {
where: 'device',
default: false,
},
showPreview: {
where: 'device',
default: false,
@ -218,6 +222,10 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'device',
default: true,
},
sensitiveDoubleClickRequired: {
where: 'device',
default: false,
},
animation: {
where: 'device',
default: !window.matchMedia('(prefers-reduced-motion)').matches,