feat(privacy): private mode
This commit is contained in:
parent
de023d8c99
commit
73f1a1ba86
44
locales/index.d.ts
vendored
44
locales/index.d.ts
vendored
@ -5104,13 +5104,21 @@ export interface Locale extends ILocale {
|
|||||||
*/
|
*/
|
||||||
"thankYou": string;
|
"thankYou": string;
|
||||||
/**
|
/**
|
||||||
*
|
* プライベートモード
|
||||||
|
*/
|
||||||
|
"privateMode": string;
|
||||||
|
/**
|
||||||
|
* 個人情報の非表示
|
||||||
*/
|
*/
|
||||||
"hideSensitiveInformation": string;
|
"hideSensitiveInformation": string;
|
||||||
/**
|
/**
|
||||||
*
|
* 「プライベートモード」で非表示になっています。
|
||||||
*/
|
*/
|
||||||
"youAreHidingSensitiveInformation": string;
|
"youAreHidingSensitiveInformation": string;
|
||||||
|
/**
|
||||||
|
* 無視して表示する
|
||||||
|
*/
|
||||||
|
"temporarilySeeThis": string;
|
||||||
"_bubbleGame": {
|
"_bubbleGame": {
|
||||||
/**
|
/**
|
||||||
* 遊び方
|
* 遊び方
|
||||||
@ -10395,67 +10403,67 @@ export interface Locale extends ILocale {
|
|||||||
};
|
};
|
||||||
"_hideSensitiveInformation": {
|
"_hideSensitiveInformation": {
|
||||||
/**
|
/**
|
||||||
*
|
* 「プライベートモード」を有効にする
|
||||||
*/
|
*/
|
||||||
"use": string;
|
"use": string;
|
||||||
/**
|
/**
|
||||||
*
|
* この機能を有効にすると、他の人が自分の画面を見たり、公共の場所などでMisskeyを利用する際にプライバシー保護に役立ちます。
|
||||||
*/
|
*/
|
||||||
"about": string;
|
"about": string;
|
||||||
/**
|
/**
|
||||||
*
|
* 非表示
|
||||||
*/
|
*/
|
||||||
"itsHidden": string;
|
"itsHidden": string;
|
||||||
/**
|
/**
|
||||||
*
|
* 表示
|
||||||
*/
|
*/
|
||||||
"itsNotHidden": string;
|
"itsNotHidden": string;
|
||||||
/**
|
/**
|
||||||
*
|
* ダイレクト投稿
|
||||||
*/
|
*/
|
||||||
"directMessages": string;
|
"directMessages": string;
|
||||||
/**
|
/**
|
||||||
*
|
* ダイレクト投稿を非表示にする
|
||||||
*/
|
*/
|
||||||
"directMessagesUse": string;
|
"directMessagesUse": string;
|
||||||
/**
|
/**
|
||||||
*
|
* このオプションを有効にすると、ダイレクト投稿の内容が基本的に表示されなくなります。
|
||||||
*/
|
*/
|
||||||
"directMessagesDescription": string;
|
"directMessagesDescription": string;
|
||||||
/**
|
/**
|
||||||
*
|
* ドライブ
|
||||||
*/
|
*/
|
||||||
"drive": string;
|
"drive": string;
|
||||||
/**
|
/**
|
||||||
*
|
* ファイルリストを非表示にする
|
||||||
*/
|
*/
|
||||||
"driveUse": string;
|
"driveUse": string;
|
||||||
/**
|
/**
|
||||||
*
|
* このオプションを有効にすると、ドライブのファイルリストが表示されなくなります(ドライブ内のファイルの添付が難しくなります)。
|
||||||
*/
|
*/
|
||||||
"driveDescription": string;
|
"driveDescription": string;
|
||||||
/**
|
/**
|
||||||
*
|
* モデレーションノート
|
||||||
*/
|
*/
|
||||||
"moderationLog": string;
|
"moderationLog": string;
|
||||||
/**
|
/**
|
||||||
*
|
* モデレーションノートを非表示にする
|
||||||
*/
|
*/
|
||||||
"moderationLogUse": string;
|
"moderationLogUse": string;
|
||||||
/**
|
/**
|
||||||
*
|
* このオプションを有効にすると、ユーザープロフィールにモデレーターが作成したモデレーションノートが表示されなくなります。
|
||||||
*/
|
*/
|
||||||
"moderationLogDescription": string;
|
"moderationLogDescription": string;
|
||||||
/**
|
/**
|
||||||
*
|
* ロール
|
||||||
*/
|
*/
|
||||||
"roles": string;
|
"roles": string;
|
||||||
/**
|
/**
|
||||||
*
|
* 割り当てられたロールを非表示にする
|
||||||
*/
|
*/
|
||||||
"rolesUse": string;
|
"rolesUse": string;
|
||||||
/**
|
/**
|
||||||
*
|
* このオプションを有効にすると、ユーザープロファイルにすべてのロールリストが表示されなくなります。
|
||||||
*/
|
*/
|
||||||
"rolesDescription": string;
|
"rolesDescription": string;
|
||||||
};
|
};
|
||||||
|
@ -1271,8 +1271,10 @@ here: "こちら"
|
|||||||
credits: "スタッフロール"
|
credits: "スタッフロール"
|
||||||
timeWillCome: "いつかこの欄にあなたの名前が書かれる日が来るのでしょうか?"
|
timeWillCome: "いつかこの欄にあなたの名前が書かれる日が来るのでしょうか?"
|
||||||
thankYou: "オスカーはあなたと一緒にサーフィンします。 いつまでも。"
|
thankYou: "オスカーはあなたと一緒にサーフィンします。 いつまでも。"
|
||||||
hideSensitiveInformation: ""
|
privateMode: "プライベートモード"
|
||||||
youAreHidingSensitiveInformation: ""
|
hideSensitiveInformation: "個人情報の非表示"
|
||||||
|
youAreHidingSensitiveInformation: "「プライベートモード」で非表示になっています。"
|
||||||
|
temporarilySeeThis: "無視して表示する"
|
||||||
|
|
||||||
_bubbleGame:
|
_bubbleGame:
|
||||||
howToPlay: "遊び方"
|
howToPlay: "遊び方"
|
||||||
@ -2766,19 +2768,19 @@ _skebStatus:
|
|||||||
nRequests: "取引実績 {n}件"
|
nRequests: "取引実績 {n}件"
|
||||||
|
|
||||||
_hideSensitiveInformation:
|
_hideSensitiveInformation:
|
||||||
use: ""
|
use: "「プライベートモード」を有効にする"
|
||||||
about: ""
|
about: "この機能を有効にすると、他の人が自分の画面を見たり、公共の場所などでMisskeyを利用する際にプライバシー保護に役立ちます。"
|
||||||
itsHidden: ""
|
itsHidden: "非表示"
|
||||||
itsNotHidden: ""
|
itsNotHidden: "表示"
|
||||||
directMessages: ""
|
directMessages: "ダイレクト投稿"
|
||||||
directMessagesUse: ""
|
directMessagesUse: "ダイレクト投稿を非表示にする"
|
||||||
directMessagesDescription: ""
|
directMessagesDescription: "このオプションを有効にすると、ダイレクト投稿の内容が基本的に表示されなくなります。"
|
||||||
drive: ""
|
drive: "ドライブ"
|
||||||
driveUse: ""
|
driveUse: "ファイルリストを非表示にする"
|
||||||
driveDescription: ""
|
driveDescription: "このオプションを有効にすると、ドライブのファイルリストが表示されなくなります(ドライブ内のファイルの添付が難しくなります)。"
|
||||||
moderationLog: ""
|
moderationLog: "モデレーションノート"
|
||||||
moderationLogUse: ""
|
moderationLogUse: "モデレーションノートを非表示にする"
|
||||||
moderationLogDescription: ""
|
moderationLogDescription: "このオプションを有効にすると、ユーザープロフィールにモデレーターが作成したモデレーションノートが表示されなくなります。"
|
||||||
roles: ""
|
roles: "ロール"
|
||||||
rolesUse: ""
|
rolesUse: "割り当てられたロールを非表示にする"
|
||||||
rolesDescription: ""
|
rolesDescription: "このオプションを有効にすると、ユーザープロファイルにすべてのロールリストが表示されなくなります。"
|
||||||
|
@ -1257,8 +1257,10 @@ alwaysConfirmFollow: "팔로우할 때 항상 확인하기"
|
|||||||
credits: "엔딩 크레딧"
|
credits: "엔딩 크레딧"
|
||||||
timeWillCome: "언젠가 이 칸에 당신의 이름이 쓰여지는 날이 올까요?"
|
timeWillCome: "언젠가 이 칸에 당신의 이름이 쓰여지는 날이 올까요?"
|
||||||
thankYou: "오스카는 당신과 함께 서핑할 것입니다. 언제까지고."
|
thankYou: "오스카는 당신과 함께 서핑할 것입니다. 언제까지고."
|
||||||
|
privateMode: "프라이빗 모드"
|
||||||
hideSensitiveInformation: "민감한 정보 숨기기"
|
hideSensitiveInformation: "민감한 정보 숨기기"
|
||||||
youAreHidingSensitiveInformation: "'프라이빗 모드'에 의해 숨겨졌습니다."
|
youAreHidingSensitiveInformation: "'프라이빗 모드'에 의해 숨겨졌습니다."
|
||||||
|
temporarilySeeThis: "무시하고 표시하기"
|
||||||
_bubbleGame:
|
_bubbleGame:
|
||||||
howToPlay: "설명"
|
howToPlay: "설명"
|
||||||
hold: "홀드"
|
hold: "홀드"
|
||||||
@ -2666,4 +2668,4 @@ _hideSensitiveInformation:
|
|||||||
moderationLogDescription: "이 옵션을 활성화하면 유저 프로필에서 중재자가 작성한 중재 기록이 표시되지 않게 됩니다."
|
moderationLogDescription: "이 옵션을 활성화하면 유저 프로필에서 중재자가 작성한 중재 기록이 표시되지 않게 됩니다."
|
||||||
roles: "역할"
|
roles: "역할"
|
||||||
rolesUse: "할당된 역할 숨기기"
|
rolesUse: "할당된 역할 숨기기"
|
||||||
rolesDescription: "이 옵션을 활성화하면 유저 프로필에서 '공개'로 설정되지 않은 역할이 표시되지 않게 됩니다."
|
rolesDescription: "이 옵션을 활성화하면 유저 프로필에서 모든 역할 목록이 표시되지 않게 됩니다."
|
||||||
|
@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
@drop.prevent.stop="onDrop"
|
@drop.prevent.stop="onDrop"
|
||||||
@contextmenu.stop="onContextmenu"
|
@contextmenu.stop="onContextmenu"
|
||||||
>
|
>
|
||||||
<div ref="contents">
|
<div ref="contents" v-if="!hideDriveFileList">
|
||||||
<div v-show="folders.length > 0" ref="foldersContainer" :class="$style.folders">
|
<div v-show="folders.length > 0" ref="foldersContainer" :class="$style.folders">
|
||||||
<XFolder
|
<XFolder
|
||||||
v-for="(f, i) in folders"
|
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 v-if="!draghover && folder != null">{{ i18n.ts.emptyFolder }}</div>
|
||||||
</div>
|
</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"/>
|
<MkLoading v-if="fetching"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="draghover" :class="$style.dropzone"></div>
|
<div v-if="draghover" :class="$style.dropzone"></div>
|
||||||
@ -142,6 +152,7 @@ const selectedFolders = ref<Misskey.entities.DriveFolder[]>([]);
|
|||||||
const uploadings = uploads;
|
const uploadings = uploads;
|
||||||
const connection = useStream().useChannel('drive');
|
const connection = useStream().useChannel('drive');
|
||||||
const keepOriginal = ref<boolean>(defaultStore.state.keepOriginalUploading); // 外部渡しが多いので$refは使わないほうがよい
|
const keepOriginal = ref<boolean>(defaultStore.state.keepOriginalUploading); // 外部渡しが多いので$refは使わないほうがよい
|
||||||
|
const hideDriveFileList = ref<boolean>(defaultStore.state.hideSensitiveInformation && defaultStore.state.hideDriveFileList);
|
||||||
|
|
||||||
// ドロップされようとしているか
|
// ドロップされようとしているか
|
||||||
const draghover = ref(false);
|
const draghover = ref(false);
|
||||||
@ -768,6 +779,11 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.privateMode {
|
||||||
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.folders,
|
.folders,
|
||||||
.files {
|
.files {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -154,7 +154,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</template>
|
</template>
|
||||||
</I18n>
|
</I18n>
|
||||||
</div>
|
</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"/>
|
<I18n :src="i18n.ts.youAreHidingSensitiveInformation" tag="small"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -250,11 +250,6 @@ const isRenote = (
|
|||||||
note.value.fileIds && note.value.fileIds.length === 0 &&
|
note.value.fileIds && note.value.fileIds.length === 0 &&
|
||||||
note.value.poll == null
|
note.value.poll == null
|
||||||
);
|
);
|
||||||
const isRedacted = (
|
|
||||||
defaultStore.state.hideDirectMessages &&
|
|
||||||
defaultStore.state.hideSensitiveInformation &&
|
|
||||||
note.value.visibility === 'specified'
|
|
||||||
);
|
|
||||||
|
|
||||||
const rootEl = shallowRef<HTMLElement>();
|
const rootEl = shallowRef<HTMLElement>();
|
||||||
const menuButton = 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 collapsed = ref(appearNote.value.cw == null && isLong);
|
||||||
const isDeleted = ref(false);
|
const isDeleted = ref(false);
|
||||||
const muted = ref(checkMute(appearNote.value, $i?.mutedWords ?? []));
|
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 translation = ref<Misskey.entities.NotesTranslateResponse | null>(null);
|
||||||
const translating = ref(false);
|
const translating = ref(false);
|
||||||
const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance);
|
const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance);
|
||||||
|
@ -64,8 +64,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<MkSwitch v-model="defaultNoteLocalOnly">{{ i18n.ts._visibility.disableFederation }}</MkSwitch>
|
<MkSwitch v-model="defaultNoteLocalOnly">{{ i18n.ts._visibility.disableFederation }}</MkSwitch>
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
<MkSwitch v-model="keepCw">{{ i18n.ts.keepCw }}</MkSwitch>
|
||||||
</div>
|
</div>
|
||||||
<MkSwitch v-model="keepCw">{{ i18n.ts.keepCw }}</MkSwitch>
|
|
||||||
</FormSection>
|
</FormSection>
|
||||||
|
|
||||||
<FormSection>
|
<FormSection>
|
||||||
|
@ -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>
|
<span v-if="user.isBot" :title="i18n.ts.isBot"><i class="ti ti-robot"></i></span>
|
||||||
</div>
|
</div>
|
||||||
</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 }">
|
<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}`">
|
<MkA v-adaptive-bg :to="`/roles/${role.id}`">
|
||||||
<img v-if="role.iconUrl" style="height: 1.3em; vertical-align: -22%;" :src="role.iconUrl"/>
|
<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>
|
</MkA>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="iAmModerator" class="moderationNote">
|
<div v-if="!hideModerationNote" class="moderationNote">
|
||||||
<MkTextarea v-if="editModerationNote || (moderationNote != null && moderationNote !== '')" v-model="moderationNote" manualSave>
|
<MkTextarea v-if="editModerationNote || (moderationNote != null && moderationNote !== '')" v-model="moderationNote" manualSave>
|
||||||
<template #label>{{ i18n.ts.moderationNote }}</template>
|
<template #label>{{ i18n.ts.moderationNote }}</template>
|
||||||
</MkTextarea>
|
</MkTextarea>
|
||||||
@ -212,6 +212,7 @@ import { confetti } from '@/scripts/confetti.js';
|
|||||||
import { misskeyApi, misskeyApiGet } from '@/scripts/misskey-api.js';
|
import { misskeyApi, misskeyApiGet } from '@/scripts/misskey-api.js';
|
||||||
import { isFollowingVisibleForMe, isFollowersVisibleForMe } from '@/scripts/isFfVisibleForMe.js';
|
import { isFollowingVisibleForMe, isFollowersVisibleForMe } from '@/scripts/isFfVisibleForMe.js';
|
||||||
import { useRouter } from '@/router/supplier.js';
|
import { useRouter } from '@/router/supplier.js';
|
||||||
|
import { defaultStore } from '@/store.js';
|
||||||
|
|
||||||
function calcAge(birthdate: string): number {
|
function calcAge(birthdate: string): number {
|
||||||
const date = new Date(birthdate);
|
const date = new Date(birthdate);
|
||||||
@ -254,6 +255,9 @@ const isEditingMemo = ref(false);
|
|||||||
const moderationNote = ref(props.user.moderationNote);
|
const moderationNote = ref(props.user.moderationNote);
|
||||||
const editModerationNote = ref(false);
|
const editModerationNote = ref(false);
|
||||||
|
|
||||||
|
const hideModerationNote = !iAmModerator || (defaultStore.state.hideSensitiveInformation && defaultStore.state.hideModerationLog);
|
||||||
|
const hideRoleList = defaultStore.state.hideSensitiveInformation && defaultStore.state.hideRoleList;
|
||||||
|
|
||||||
watch(moderationNote, async () => {
|
watch(moderationNote, async () => {
|
||||||
await misskeyApi('admin/update-user-note', { userId: props.user.id, text: moderationNote.value });
|
await misskeyApi('admin/update-user-note', { userId: props.user.id, text: moderationNote.value });
|
||||||
});
|
});
|
||||||
@ -266,6 +270,7 @@ const style = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const age = computed(() => {
|
const age = computed(() => {
|
||||||
|
if (props.user.birthday == null) return 0;
|
||||||
return calcAge(props.user.birthday);
|
return calcAge(props.user.birthday);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user