feat(privacy): private mode

This commit is contained in:
オスカー、 2024-07-20 23:58:32 +09:00
parent de023d8c99
commit 73f1a1ba86
Signed by: SWREI
GPG Key ID: 139D6573F92DA9F7
7 changed files with 80 additions and 47 deletions

44
locales/index.d.ts vendored
View File

@ -5104,13 +5104,21 @@ export interface Locale extends ILocale {
*/
"thankYou": string;
/**
*
*
*/
"privateMode": string;
/**
*
*/
"hideSensitiveInformation": string;
/**
*
*
*/
"youAreHidingSensitiveInformation": string;
/**
*
*/
"temporarilySeeThis": string;
"_bubbleGame": {
/**
*
@ -10395,67 +10403,67 @@ export interface Locale extends ILocale {
};
"_hideSensitiveInformation": {
/**
*
*
*/
"use": string;
/**
*
* Misskeyを利用する際にプライバシー保護に役立ちます
*/
"about": string;
/**
*
*
*/
"itsHidden": string;
/**
*
*
*/
"itsNotHidden": string;
/**
*
* 稿
*/
"directMessages": string;
/**
*
* 稿
*/
"directMessagesUse": string;
/**
*
* 稿
*/
"directMessagesDescription": string;
/**
*
*
*/
"drive": string;
/**
*
*
*/
"driveUse": string;
/**
*
*
*/
"driveDescription": string;
/**
*
*
*/
"moderationLog": string;
/**
*
*
*/
"moderationLogUse": string;
/**
*
*
*/
"moderationLogDescription": string;
/**
*
*
*/
"roles": string;
/**
*
*
*/
"rolesUse": string;
/**
*
*
*/
"rolesDescription": string;
};

View File

@ -1271,8 +1271,10 @@ here: "こちら"
credits: "スタッフロール"
timeWillCome: "いつかこの欄にあなたの名前が書かれる日が来るのでしょうか?"
thankYou: "オスカーはあなたと一緒にサーフィンします。 いつまでも。"
hideSensitiveInformation: ""
youAreHidingSensitiveInformation: ""
privateMode: "プライベートモード"
hideSensitiveInformation: "個人情報の非表示"
youAreHidingSensitiveInformation: "「プライベートモード」で非表示になっています。"
temporarilySeeThis: "無視して表示する"
_bubbleGame:
howToPlay: "遊び方"
@ -2766,19 +2768,19 @@ _skebStatus:
nRequests: "取引実績 {n}件"
_hideSensitiveInformation:
use: ""
about: ""
itsHidden: ""
itsNotHidden: ""
directMessages: ""
directMessagesUse: ""
directMessagesDescription: ""
drive: ""
driveUse: ""
driveDescription: ""
moderationLog: ""
moderationLogUse: ""
moderationLogDescription: ""
roles: ""
rolesUse: ""
rolesDescription: ""
use: "「プライベートモード」を有効にする"
about: "この機能を有効にすると、他の人が自分の画面を見たり、公共の場所などでMisskeyを利用する際にプライバシー保護に役立ちます。"
itsHidden: "非表示"
itsNotHidden: "表示"
directMessages: "ダイレクト投稿"
directMessagesUse: "ダイレクト投稿を非表示にする"
directMessagesDescription: "このオプションを有効にすると、ダイレクト投稿の内容が基本的に表示されなくなります。"
drive: "ドライブ"
driveUse: "ファイルリストを非表示にする"
driveDescription: "このオプションを有効にすると、ドライブのファイルリストが表示されなくなります(ドライブ内のファイルの添付が難しくなります)。"
moderationLog: "モデレーションノート"
moderationLogUse: "モデレーションノートを非表示にする"
moderationLogDescription: "このオプションを有効にすると、ユーザープロフィールにモデレーターが作成したモデレーションノートが表示されなくなります。"
roles: "ロール"
rolesUse: "割り当てられたロールを非表示にする"
rolesDescription: "このオプションを有効にすると、ユーザープロファイルにすべてのロールリストが表示されなくなります。"

View File

@ -1257,8 +1257,10 @@ alwaysConfirmFollow: "팔로우할 때 항상 확인하기"
credits: "엔딩 크레딧"
timeWillCome: "언젠가 이 칸에 당신의 이름이 쓰여지는 날이 올까요?"
thankYou: "오스카는 당신과 함께 서핑할 것입니다. 언제까지고."
privateMode: "프라이빗 모드"
hideSensitiveInformation: "민감한 정보 숨기기"
youAreHidingSensitiveInformation: "'프라이빗 모드'에 의해 숨겨졌습니다."
temporarilySeeThis: "무시하고 표시하기"
_bubbleGame:
howToPlay: "설명"
hold: "홀드"
@ -2666,4 +2668,4 @@ _hideSensitiveInformation:
moderationLogDescription: "이 옵션을 활성화하면 유저 프로필에서 중재자가 작성한 중재 기록이 표시되지 않게 됩니다."
roles: "역할"
rolesUse: "할당된 역할 숨기기"
rolesDescription: "이 옵션을 활성화하면 유저 프로필에서 '공개'로 설정되지 않은 역할이 표시되지 않게 됩니다."
rolesDescription: "이 옵션을 활성화하면 유저 프로필에서 모든 역할 목록이 표시되지 않게 됩니다."

View File

@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@drop.prevent.stop="onDrop"
@contextmenu.stop="onContextmenu"
>
<div ref="contents">
<div ref="contents" v-if="!hideDriveFileList">
<div v-show="folders.length > 0" ref="foldersContainer" :class="$style.folders">
<XFolder
v-for="(f, i) in folders"
@ -87,6 +87,16 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-if="!draghover && folder != null">{{ i18n.ts.emptyFolder }}</div>
</div>
</div>
<div ref="contents" :class="$style.privateMode" v-else>
<div v-if="!fetching" :class="$style.empty">
<div>
<strong>{{ i18n.ts.privateMode }}</strong>
<br/>
{{ i18n.ts.youAreHidingSensitiveInformation }}
</div>
</div>
<MkButton small inline @click="hideDriveFileList = false">{{ i18n.ts.temporarilySeeThis }}</MkButton>
</div>
<MkLoading v-if="fetching"/>
</div>
<div v-if="draghover" :class="$style.dropzone"></div>
@ -142,6 +152,7 @@ const selectedFolders = ref<Misskey.entities.DriveFolder[]>([]);
const uploadings = uploads;
const connection = useStream().useChannel('drive');
const keepOriginal = ref<boolean>(defaultStore.state.keepOriginalUploading); // $ref使
const hideDriveFileList = ref<boolean>(defaultStore.state.hideSensitiveInformation && defaultStore.state.hideDriveFileList);
//
const draghover = ref(false);
@ -768,6 +779,11 @@ onBeforeUnmount(() => {
}
}
.privateMode {
text-align: center;
align-items: center;
}
.folders,
.files {
display: flex;

View File

@ -154,7 +154,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
</I18n>
</div>
<div v-else :class="$style.muted" :style="hideMutedNotes ? 'display: none' : undefined" @click="isRedacted = false; muted = false">
<div v-else :class="$style.muted" @click="isRedacted = false; muted = false">
<I18n :src="i18n.ts.youAreHidingSensitiveInformation" tag="small"/>
</div>
</template>
@ -250,11 +250,6 @@ const isRenote = (
note.value.fileIds && note.value.fileIds.length === 0 &&
note.value.poll == null
);
const isRedacted = (
defaultStore.state.hideDirectMessages &&
defaultStore.state.hideSensitiveInformation &&
note.value.visibility === 'specified'
);
const rootEl = shallowRef<HTMLElement>();
const menuButton = shallowRef<HTMLElement>();
@ -272,6 +267,11 @@ const isLong = shouldCollapsed(appearNote.value, urls.value ?? []);
const collapsed = ref(appearNote.value.cw == null && isLong);
const isDeleted = ref(false);
const muted = ref(checkMute(appearNote.value, $i?.mutedWords ?? []));
const isRedacted = ref<boolean>(
defaultStore.state.hideDirectMessages &&
defaultStore.state.hideSensitiveInformation &&
note.value.visibility === 'specified'
);
const translation = ref<Misskey.entities.NotesTranslateResponse | null>(null);
const translating = ref(false);
const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance);

View File

@ -64,8 +64,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="defaultNoteLocalOnly">{{ i18n.ts._visibility.disableFederation }}</MkSwitch>
</div>
</MkFolder>
</div>
<MkSwitch v-model="keepCw">{{ i18n.ts.keepCw }}</MkSwitch>
</div>
</FormSection>
<FormSection>

View File

@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span v-if="user.isBot" :title="i18n.ts.isBot"><i class="ti ti-robot"></i></span>
</div>
</div>
<div v-if="user.roles.length > 0" class="roles">
<div v-if="user.roles.length > 0 && !hideRoleList" class="roles">
<span v-for="role in user.roles" :key="role.id" v-tooltip="role.description" class="role" :style="{ '--color': role.color }">
<MkA v-adaptive-bg :to="`/roles/${role.id}`">
<img v-if="role.iconUrl" style="height: 1.3em; vertical-align: -22%;" :src="role.iconUrl"/>
@ -55,7 +55,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkA>
</span>
</div>
<div v-if="iAmModerator" class="moderationNote">
<div v-if="!hideModerationNote" class="moderationNote">
<MkTextarea v-if="editModerationNote || (moderationNote != null && moderationNote !== '')" v-model="moderationNote" manualSave>
<template #label>{{ i18n.ts.moderationNote }}</template>
</MkTextarea>
@ -212,6 +212,7 @@ import { confetti } from '@/scripts/confetti.js';
import { misskeyApi, misskeyApiGet } from '@/scripts/misskey-api.js';
import { isFollowingVisibleForMe, isFollowersVisibleForMe } from '@/scripts/isFfVisibleForMe.js';
import { useRouter } from '@/router/supplier.js';
import { defaultStore } from '@/store.js';
function calcAge(birthdate: string): number {
const date = new Date(birthdate);
@ -254,6 +255,9 @@ const isEditingMemo = ref(false);
const moderationNote = ref(props.user.moderationNote);
const editModerationNote = ref(false);
const hideModerationNote = !iAmModerator || (defaultStore.state.hideSensitiveInformation && defaultStore.state.hideModerationLog);
const hideRoleList = defaultStore.state.hideSensitiveInformation && defaultStore.state.hideRoleList;
watch(moderationNote, async () => {
await misskeyApi('admin/update-user-note', { userId: props.user.id, text: moderationNote.value });
});
@ -266,6 +270,7 @@ const style = computed(() => {
});
const age = computed(() => {
if (props.user.birthday == null) return 0;
return calcAge(props.user.birthday);
});