enhance(sensitive-flag):センシティブフラグの機能の強化 (MisskeyIO#936)

This commit is contained in:
まっちゃてぃー。 2025-03-18 03:22:08 +09:00 committed by GitHub
parent 7a94724098
commit abdaa18666
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 197 additions and 20 deletions

View file

@ -8,6 +8,14 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="$style.head">
<MkAvatar v-if="['pollEnded', 'note'].includes(notification.type) && notification.note" :class="$style.icon" :user="notification.note.user" link preview/>
<MkAvatar v-else-if="['roleAssigned', 'achievementEarned', 'noteScheduled', 'scheduledNotePosted', 'scheduledNoteError'].includes(notification.type)" :class="$style.icon" :user="$i" link preview/>
<div
v-else-if="notification.type === 'sensitiveFlagAssigned'"
:class="$style.iconFrame"
>
<div :class="[$style.iconInner]">
<img :class="$style.iconImg" src="/fluent-emoji/1f6a9.png">
</div>
</div>
<div v-else-if="notification.type === 'reaction:grouped' && notification.note.reactionAcceptance === 'likeOnly'" :class="[$style.icon, $style.icon_reactionGroupHeart]"><i class="ti ti-heart" style="line-height: 1;"></i></div>
<div v-else-if="notification.type === 'reaction:grouped'" :class="[$style.icon, $style.icon_reactionGroup]"><i class="ti ti-plus" style="line-height: 1;"></i></div>
<div v-else-if="notification.type === 'renote:grouped'" :class="[$style.icon, $style.icon_renoteGroup]"><i class="ti ti-repeat" style="line-height: 1;"></i></div>
@ -71,6 +79,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span v-else-if="notification.type === 'reaction:grouped'" :class="$style.headerName">{{ i18n.tsx._notification.reactedBySomeUsers({ n: getActualReactedUsersCount(notification) }) }}</span>
<span v-else-if="notification.type === 'renote:grouped'" :class="$style.headerName">{{ i18n.tsx._notification.renotedBySomeUsers({ n: notification.users.length }) }}</span>
<span v-else-if="notification.type === 'app'" :class="$style.headerName">{{ notification.header }}</span>
<MkA v-else-if="notification.type === 'sensitiveFlagAssigned'" :to="'/my/drive/file/'+notification.fileId" :class="$style.headerName">{{ i18n.ts._notification.sensitiveFlagAssigned }}</MkA>
<MkTime v-if="withTime" :time="notification.createdAt" :class="$style.headerTime"/>
</header>
<div>
@ -159,6 +168,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkAvatar :class="$style.reactionsItemAvatar" :user="user" link preview/>
</div>
</div>
<Mfm v-else-if="notification.type === 'sensitiveFlagAssigned'" :text="i18n.ts.sensitiveByModerator"/>
<span v-if="['sensitiveFlagAssigned'].includes(notification.type)" :class="$style.text" style="opacity: 0.6;">
{{ i18n.ts.thisInfoIsNotVisibleOtherUser }}
</span>
</div>
</div>
</div>
@ -341,6 +354,12 @@ function getActualReactedUsersCount(notification: Misskey.entities.Notification)
pointer-events: none;
}
.t_sensitiveFlagAssigned {
padding: 3px;
background: var(--eventOther);
pointer-events: none;
}
.tail {
flex: 1;
min-width: 0;
@ -430,6 +449,42 @@ function getActualReactedUsersCount(notification: Misskey.entities.Notification)
color: #fff;
}
.iconFrame {
position: relative;
width: 100%;
height: 100%;
padding: 4px;
border-radius: 100%;
box-sizing: border-box;
pointer-events: none;
user-select: none;
filter: drop-shadow(0px 2px 2px #00000044);
box-shadow: 0 1px 0px #ffffff88 inset;
overflow: clip;
background: linear-gradient(0deg, #703827, #d37566);
}
.iconImg {
width: calc(100% - 12px);
height: calc(100% - 12px);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
filter: drop-shadow(0px 1px 2px #000000aa);
}
.iconInner {
position: relative;
width: 100%;
height: 100%;
border-radius: 100%;
box-shadow: 0 1px 0px #ffffff88 inset;
background: linear-gradient(0deg, #d37566, #703827);
}
@container (max-width: 600px) {
.root {
padding: 16px;

View file

@ -70,6 +70,7 @@ export const notificationTypes = [
'noteScheduled',
'scheduledNotePosted',
'scheduledNoteError',
'sensitiveFlagAssigned',
'app',
] as const;
export const obsoleteNotificationTypes = ['pollVote', 'groupInvited'] as const;

View file

@ -6,6 +6,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div class="_gaps">
<MkInfo>{{ i18n.ts._fileViewer.thisPageCanBeSeenFromTheAuthor }}</MkInfo>
<MkInfo v-if="file && file.isSensitiveByModerator" :warn="true">
<Mfm :text="i18n.ts.sensitiveByModerator"/>
</MkInfo>
<MkLoading v-if="fetching"/>
<div v-else-if="file" class="_gaps">
<div :class="$style.filePreviewRoot">
@ -23,12 +26,14 @@ SPDX-License-Identifier: AGPL-3.0-only
<button v-if="isImage" v-tooltip="i18n.ts.cropImage" class="_button" :class="$style.fileQuickActionsOthersButton" @click="crop()">
<i class="ti ti-crop"></i>
</button>
<button v-if="file.isSensitive" v-tooltip="i18n.ts.unmarkAsSensitive" class="_button" :class="$style.fileQuickActionsOthersButton" @click="toggleSensitive()">
<i class="ti ti-eye"></i>
</button>
<button v-else v-tooltip="i18n.ts.markAsSensitive" class="_button" :class="$style.fileQuickActionsOthersButton" @click="toggleSensitive()">
<i class="ti ti-eye-exclamation"></i>
</button>
<span v-if="!file.isSensitiveByModerator">
<button v-if="file.isSensitive" v-tooltip="i18n.ts.unmarkAsSensitive" class="_button" :class="$style.fileQuickActionsOthersButton" @click="toggleSensitive()">
<i class="ti ti-eye"></i>
</button>
<button v-else v-tooltip="i18n.ts.markAsSensitive" class="_button" :class="$style.fileQuickActionsOthersButton" @click="toggleSensitive()">
<i class="ti ti-eye-exclamation"></i>
</button>
</span>
<a v-tooltip="i18n.ts.download" :href="file.url" :download="file.name" class="_button" :class="$style.fileQuickActionsOthersButton">
<i class="ti ti-download"></i>
</a>

View file

@ -21,6 +21,9 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<div class="_margin _gaps_s">
<MkRemoteCaution v-if="note.user.host != null" :href="note.url ?? note.uri"/>
<MkInfo v-if="hasSensitiveFiles" :warn="true">
<Mfm :text="i18n.ts.sensitiveByModerator"/>
</MkInfo>
<MkNoteDetailed :key="note.id" v-model:note="note" :initialTab="initialTab" :class="$style.note"/>
</div>
<div v-if="clips && clips.length > 0" class="_margin">
@ -61,6 +64,8 @@ import { i18n } from '@/i18n.js';
import { dateString } from '@/filters/date.js';
import MkClipPreview from '@/components/MkClipPreview.vue';
import { defaultStore } from '@/store.js';
import MkInfo from '@/components/MkInfo.vue';
import { $i } from '@/account.js';
const props = defineProps<{
noteId: string;
@ -69,6 +74,7 @@ const props = defineProps<{
const note = ref<null | Misskey.entities.Note>();
const clips = ref<Misskey.entities.Clip[]>();
const hasSensitiveFiles = ref(false);
const showPrev = ref<'user' | 'channel' | false>(false);
const showNext = ref<'user' | 'channel' | false>(false);
const error = ref();
@ -119,6 +125,15 @@ function fetchNote() {
noteId: props.noteId,
}).then(res => {
note.value = res;
if (note.value.userId === $i?.id && note.value.fileIds) {
Promise.all(note.value.fileIds.map(fileId =>
misskeyApi('drive/files/show', { fileId: fileId }),
)).then(files => {
hasSensitiveFiles.value = files.some(file => file.isSensitiveByModerator);
});
}
// 2023-10-01notes/clips
if (note.value.clippedCount > 0 || new Date(note.value.createdAt).getTime() < new Date('2023-10-01').getTime()) {
misskeyApi('notes/clips', {