[Frontend] Incoming media that isnt marked as sensitive but is from a cwed post is now sensitve #74

Open
leah wants to merge 3 commits from feature/mark-incoming-cwed-post-media-as-sensitive into main
12 changed files with 32 additions and 5 deletions

View file

@ -765,6 +765,7 @@ lockedAccountInfo: "Unless you set your note visiblity to \"Followers only\", yo
alwaysMarkSensitive: "Mark as sensitive by default" alwaysMarkSensitive: "Mark as sensitive by default"
loadRawImages: "Load original images instead of showing thumbnails" loadRawImages: "Load original images instead of showing thumbnails"
disableCatSpeak: "Disable cat speak" disableCatSpeak: "Disable cat speak"
markIncomingMediaInCwedPostAsSensitive: "Mark incoming media in cwed posts as sensitive"
disableShowingAnimatedImages: "Don't play animated images" disableShowingAnimatedImages: "Don't play animated images"
highlightSensitiveMedia: "Highlight sensitive media" highlightSensitiveMedia: "Highlight sensitive media"
verificationEmailSent: "A verification email has been sent. Please follow the included link to complete verification." verificationEmailSent: "A verification email has been sent. Please follow the included link to complete verification."

4
locales/index.d.ts vendored
View file

@ -3076,6 +3076,10 @@ export interface Locale extends ILocale {
* *
*/ */
"disableCatSpeak": string; "disableCatSpeak": string;
/**
* cwed投稿の受信メディアを機密扱いとしてマークする
*/
"markIncomingMediaInCwedPostAsSensitive": string;
/** /**
* *
*/ */

View file

@ -765,6 +765,7 @@ lockedAccountInfo: "フォローを承認制にしても、ノートの公開範
alwaysMarkSensitive: "デフォルトでメディアをセンシティブ設定にする" alwaysMarkSensitive: "デフォルトでメディアをセンシティブ設定にする"
loadRawImages: "添付画像のサムネイルをオリジナル画質にする" loadRawImages: "添付画像のサムネイルをオリジナル画質にする"
disableCatSpeak: "猫の話し方を無効にする" disableCatSpeak: "猫の話し方を無効にする"
markIncomingMediaInCwedPostAsSensitive: "cwed投稿の受信メディアを機密扱いとしてマークする"
disableShowingAnimatedImages: "アニメーション画像を再生しない" disableShowingAnimatedImages: "アニメーション画像を再生しない"
highlightSensitiveMedia: "メディアがセンシティブであることを分かりやすく表示" highlightSensitiveMedia: "メディアがセンシティブであることを分かりやすく表示"
verificationEmailSent: "確認のメールを送信しました。メールに記載されたリンクにアクセスして、設定を完了してください。" verificationEmailSent: "確認のメールを送信しました。メールに記載されたリンクにアクセスして、設定を完了してください。"

View file

@ -39,11 +39,13 @@ import XVideo from '@/components/MkMediaVideo.vue';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { FILE_TYPE_BROWSERSAFE } from '@/const.js'; import { FILE_TYPE_BROWSERSAFE } from '@/const.js';
import { defaultStore } from '@/store.js'; import { defaultStore } from '@/store.js';
import { $i } from "@/account";
const props = defineProps<{ const props = defineProps<{
mediaList: Misskey.entities.DriveFile[]; mediaList: Misskey.entities.DriveFile[];
user?: Misskey.entities.UserLite; user?: Misskey.entities.UserLite;
raw?: boolean; raw?: boolean;
isNoteSensitive?: boolean;
}>(); }>();
const gallery = shallowRef<HTMLDivElement>(); const gallery = shallowRef<HTMLDivElement>();
@ -90,6 +92,12 @@ async function calcAspectRatio() {
} }
onMounted(() => { onMounted(() => {
if (($i ? defaultStore.state.markIncomingMediaInCwedPostAsSensitive : true)) {
props.mediaList.forEach(media => {
media.isSensitive = props.isNoteSensitive;
});
}
calcAspectRatio(); calcAspectRatio();
lightbox = new PhotoSwipeLightbox({ lightbox = new PhotoSwipeLightbox({

View file

@ -79,7 +79,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</div> </div>
<div v-if="appearNote.files && appearNote.files.length > 0"> <div v-if="appearNote.files && appearNote.files.length > 0">
<MkMediaList :mediaList="appearNote.files" :user="appearNote.user"/> <MkMediaList :mediaList="appearNote.files" :user="appearNote.user" :isNoteSensitive="note.cw"/>
</div> </div>
<MkPoll v-if="appearNote.poll" :noteId="appearNote.id" :poll="appearNote.poll" :class="$style.poll"/> <MkPoll v-if="appearNote.poll" :noteId="appearNote.id" :poll="appearNote.poll" :class="$style.poll"/>
<div v-if="isEnabledUrlPreview"> <div v-if="isEnabledUrlPreview">

View file

@ -92,7 +92,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</div> </div>
<div v-if="appearNote.files && appearNote.files.length > 0"> <div v-if="appearNote.files && appearNote.files.length > 0">
<MkMediaList :mediaList="appearNote.files" :user="appearNote.user"/> <MkMediaList :mediaList="appearNote.files" :user="appearNote.user" :isNoteSensitive="note.cw"/>
</div> </div>
<MkPoll v-if="appearNote.poll" ref="pollViewer" :noteId="appearNote.id" :poll="appearNote.poll" :class="$style.poll"/> <MkPoll v-if="appearNote.poll" ref="pollViewer" :noteId="appearNote.id" :poll="appearNote.poll" :class="$style.poll"/>
<div v-if="isEnabledUrlPreview"> <div v-if="isEnabledUrlPreview">

View file

@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
<details v-if="note.files && note.files.length > 0"> <details v-if="note.files && note.files.length > 0">
<summary>({{ i18n.tsx.withNFiles({ n: note.files.length }) }})</summary> <summary>({{ i18n.tsx.withNFiles({ n: note.files.length }) }})</summary>
<MkMediaList :mediaList="note.files" :user="note.user"/> <MkMediaList :mediaList="note.files" :user="note.user" :isNoteSensitive="note.cw"/>
</details> </details>
<details v-if="note.poll"> <details v-if="note.poll">
<summary>{{ i18n.ts.poll }}</summary> <summary>{{ i18n.ts.poll }}</summary>

View file

@ -64,6 +64,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="showGapBetweenNotesInTimeline">{{ i18n.ts.showGapBetweenNotesInTimeline }}</MkSwitch> <MkSwitch v-model="showGapBetweenNotesInTimeline">{{ i18n.ts.showGapBetweenNotesInTimeline }}</MkSwitch>
<MkSwitch v-model="loadRawImages">{{ i18n.ts.loadRawImages }}</MkSwitch> <MkSwitch v-model="loadRawImages">{{ i18n.ts.loadRawImages }}</MkSwitch>
<MkSwitch v-model="disableCatSpeak">{{ i18n.ts.disableCatSpeak }}</MkSwitch> <MkSwitch v-model="disableCatSpeak">{{ i18n.ts.disableCatSpeak }}</MkSwitch>
<MkSwitch v-model="markIncomingMediaInCwedPostAsSensitive">{{ i18n.ts.markIncomingMediaInCwedPostAsSensitive }}</MkSwitch>
<MkRadios v-model="reactionsDisplaySize"> <MkRadios v-model="reactionsDisplaySize">
<template #label>{{ i18n.ts.reactionsDisplaySize }}</template> <template #label>{{ i18n.ts.reactionsDisplaySize }}</template>
<option value="small">{{ i18n.ts.small }}</option> <option value="small">{{ i18n.ts.small }}</option>
@ -301,6 +302,7 @@ const disableShowingAnimatedImages = computed(defaultStore.makeGetterSetter('dis
const forceShowAds = computed(defaultStore.makeGetterSetter('forceShowAds')); const forceShowAds = computed(defaultStore.makeGetterSetter('forceShowAds'));
const loadRawImages = computed(defaultStore.makeGetterSetter('loadRawImages')); const loadRawImages = computed(defaultStore.makeGetterSetter('loadRawImages'));
const disableCatSpeak = computed(defaultStore.makeGetterSetter('disableCatSpeak')); const disableCatSpeak = computed(defaultStore.makeGetterSetter('disableCatSpeak'));
const markIncomingMediaInCwedPostAsSensitive = computed(defaultStore.makeGetterSetter('markIncomingMediaInCwedPostAsSensitive'));
const highlightSensitiveMedia = computed(defaultStore.makeGetterSetter('highlightSensitiveMedia')); const highlightSensitiveMedia = computed(defaultStore.makeGetterSetter('highlightSensitiveMedia'));
const imageNewTab = computed(defaultStore.makeGetterSetter('imageNewTab')); const imageNewTab = computed(defaultStore.makeGetterSetter('imageNewTab'));
const warnMissingAltText = computed(defaultStore.makeGetterSetter('warnMissingAltText')); const warnMissingAltText = computed(defaultStore.makeGetterSetter('warnMissingAltText'));

View file

@ -79,6 +79,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
'imageNewTab', 'imageNewTab',
'dataSaver', 'dataSaver',
'disableCatSpeak', 'disableCatSpeak',
'markIncomingMediaInCwedPostAsSensitive',
'disableShowingAnimatedImages', 'disableShowingAnimatedImages',
'emojiStyle', 'emojiStyle',
'disableDrawer', 'disableDrawer',

View file

@ -33,6 +33,8 @@ import XVideo from '@/components/MkMediaVideo.vue';
import XImage from '@/components/MkMediaImage.vue'; import XImage from '@/components/MkMediaImage.vue';
import XBanner from '@/components/MkMediaBanner.vue'; import XBanner from '@/components/MkMediaBanner.vue';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { $i } from "@/account";
import { defaultStore } from "@/store";
const props = defineProps<{ const props = defineProps<{
user: Misskey.entities.UserDetailed; user: Misskey.entities.UserDetailed;
@ -51,7 +53,11 @@ onMounted(() => {
limit: 15, limit: 15,
}).then(notes => { }).then(notes => {
for (const note of notes) { for (const note of notes) {
for (const file of note.files) { for (let file of note.files) {
if (($i ? defaultStore.state.markIncomingMediaInCwedPostAsSensitive : true)) {
file.isSensitive = note.cw !== null;
}
medias.value.push({ medias.value.push({
note, note,
file, file,

View file

@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkA v-if="note.renoteId" class="rp" :to="`/notes/${note.renoteId}`">RN: ...</MkA> <MkA v-if="note.renoteId" class="rp" :to="`/notes/${note.renoteId}`">RN: ...</MkA>
</div> </div>
<div v-if="note.files.length > 0" :class="$style.richcontent"> <div v-if="note.files.length > 0" :class="$style.richcontent">
<MkMediaList :mediaList="note.files" :user="note.user"/> <MkMediaList :mediaList="note.files" :user="note.user" :isNoteSensitive="note.cw"/>
</div> </div>
<div v-if="note.poll"> <div v-if="note.poll">
<MkPoll :noteId="note.id" :poll="note.poll" :readOnly="true"/> <MkPoll :noteId="note.id" :poll="note.poll" :readOnly="true"/>

View file

@ -263,6 +263,10 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'account', where: 'account',
default: false, default: false,
}, },
markIncomingMediaInCwedPostAsSensitive: {
where: 'account',
default: true,
},
emojiStyle: { emojiStyle: {
where: 'device', where: 'device',
default: 'twemoji', // twemoji / fluentEmoji / native default: 'twemoji', // twemoji / fluentEmoji / native