refactor(account): account delete, truncate, auto note removal
This commit is contained in:
parent
4e99008e8d
commit
d84bff37ec
@ -1273,6 +1273,8 @@ temporarilySeeThis: "Nevermind, just show me this"
|
||||
sensitiveDoubleClickRequired: "Require double-click to open sensitive media"
|
||||
mutualLink: "Mutual Link"
|
||||
saveThisFile: "Save this file to Drive"
|
||||
autoRemoval: "Automatic note deletion"
|
||||
autoRemovalDescription: "You can delete your note when it exceeds period you set."
|
||||
_bubbleGame:
|
||||
howToPlay: "How to play"
|
||||
hold: "Hold"
|
||||
@ -1331,6 +1333,14 @@ _announcement:
|
||||
dialogAnnouncementUxWarn: "Having two or more dialog-style notifications simultaneously can significantly impact the user experience, so please use them carefully."
|
||||
silence: "No notification"
|
||||
silenceDescription: "Turning this on will skip the notification of this announcement and the user won't need to read it."
|
||||
_autoRemoval:
|
||||
use: "Use automatic note deletion"
|
||||
deleteAfter: "Period threshold"
|
||||
deleteAfterDescription: "When your notes exceeds this period, notes will be deleted."
|
||||
noPiningNotes: "Exclude pinned notes"
|
||||
noPiningNotesDescription: "Delete notes except that are not pinned in profile."
|
||||
noSpecifiedNotes: "Exclude direct notes"
|
||||
noSpecifiedNotesDescription: "Delete notes without direct visibility."
|
||||
_initialAccountSetting:
|
||||
accountCreated: "Your account was successfully created!"
|
||||
letsStartAccountSetup: "For starters, let's set up your profile."
|
||||
@ -1742,29 +1752,31 @@ _role:
|
||||
canCreateContent: "Can create contents"
|
||||
canUpdateContent: "Can edit contents"
|
||||
canDeleteContent: "Can delete contents"
|
||||
canUseAutoNoteRemoval: "Can use automatic note deletion"
|
||||
canUseAccountRemoval: "Can delete account"
|
||||
canUseAccountTruncate: "Can truncate account"
|
||||
canPurgeAccount: "Can delete account completely"
|
||||
canUpdateAvatar: "Can change avatar"
|
||||
canUpdateBanner: "Can change banner"
|
||||
mentionMax: "Maximum number of mentions in a note"
|
||||
mentionLimit: "Maximum number of mentions in a note"
|
||||
canInvite: "Can create instance invite codes"
|
||||
inviteLimit: "Invite limit"
|
||||
inviteLimitCycle: "Invite limit cooldown"
|
||||
inviteExpirationTime: "Invite expiration interval"
|
||||
canManageCustomEmojis: "Can manage custom emojis"
|
||||
canManageAvatarDecorations: "Manage avatar decorations"
|
||||
driveCapacity: "Drive capacity"
|
||||
driveCapacityMb: "Drive capacity (MB)"
|
||||
alwaysMarkNsfw: "Always mark files as NSFW"
|
||||
skipNsfwDetection: "Skip NSFW detection by AI"
|
||||
pinMax: "Maximum number of pinned notes"
|
||||
antennaMax: "Maximum number of antennas"
|
||||
antennaNotesMax: "Maximum number of notes stored in antennas"
|
||||
wordMuteMax: "Maximum number of characters allowed in word mutes"
|
||||
webhookMax: "Maximum number of Webhooks"
|
||||
clipMax: "Maximum number of Clips"
|
||||
noteEachClipsMax: "Maximum number of notes within a clip"
|
||||
userListMax: "Maximum number of user lists"
|
||||
userEachUserListsMax: "Maximum number of users within a user list"
|
||||
pinLimit: "Maximum number of pinned notes"
|
||||
antennaLimit: "Maximum number of antennas"
|
||||
antennaNotesLimit: "Maximum number of notes stored in antennas"
|
||||
wordMuteLimit: "Maximum number of words allowed in word mutes"
|
||||
webhookLimit: "Maximum number of Webhooks"
|
||||
clipLimit: "Maximum number of Clips"
|
||||
noteEachClipsLimit: "Maximum number of notes within a clip"
|
||||
userListLimit: "Maximum number of user lists"
|
||||
userEachUserListsLimit: "Maximum number of users within a user list"
|
||||
rateLimitFactor: "Rate limit"
|
||||
descriptionOfRateLimitFactor: "Lower rate limits are less restrictive, higher ones more restrictive. "
|
||||
canHideAds: "Can hide ads"
|
||||
@ -1822,17 +1834,19 @@ _accountDelete:
|
||||
accountDelete: "Delete account"
|
||||
mayTakeTime: "As account deletion is a resource-heavy process, it may take some time to complete depending on how much content you have created and how many files you have uploaded."
|
||||
sendEmail: "Once account deletion has been completed, an email will be sent to the email address registered to this account."
|
||||
requestAccountDelete: "Request account deletion"
|
||||
requestAccountDelete: "Request to delete my account"
|
||||
started: "Deletion has been started."
|
||||
inProgress: "Deletion is currently in progress"
|
||||
inProgress: "Your account is currently being deleted"
|
||||
youCantUseThisTime: "You can't request account deletion for now."
|
||||
youAreRootAndCantUseThisTime: "You can't request account deletion 'cause you are root."
|
||||
_accountTruncate:
|
||||
accountTruncate: "Truncate account"
|
||||
purgeDriveFiles: "Also purge drive's files"
|
||||
mayTakeTime: "As account deletion is a resource-heavy process, it may take some time to complete depending on how much content you have created and how many files you have uploaded."
|
||||
purgeDriveFiles: "Also truncate drive's files"
|
||||
mayTakeTime: "As account truncate task is a resource-heavy process, it may take some time to complete depending on how much content you have created and how many files you have uploaded."
|
||||
requestAccountTruncate: "Request to truncate my account"
|
||||
started: "Truncate task has been started."
|
||||
inProgress: "Your account is currently being truncated"
|
||||
youCantUseThisTime: "You can't request account truncate task for now."
|
||||
_ad:
|
||||
back: "Back"
|
||||
reduceFrequencyOfThisAd: "Show this ad less"
|
||||
|
72
locales/index.d.ts
vendored
72
locales/index.d.ts
vendored
@ -5224,9 +5224,21 @@ export interface Locale extends ILocale {
|
||||
*/
|
||||
"youAreOnVacation": string;
|
||||
/**
|
||||
* 노트 자동 삭제
|
||||
* ノート自動削除
|
||||
*/
|
||||
"autoRemoval": string;
|
||||
/**
|
||||
* ノート自動削除は、作成してから一定期間が経過したノートを削除してくれる機能です。
|
||||
*/
|
||||
"autoRemovalDescription": string;
|
||||
/**
|
||||
* 危険区域
|
||||
*/
|
||||
"dangerZone": string;
|
||||
/**
|
||||
* 以下の機能を利用する際は、特にご注意ください。
|
||||
*/
|
||||
"dangerZoneDescription": string;
|
||||
"_bubbleGame": {
|
||||
/**
|
||||
* 遊び方
|
||||
@ -5432,33 +5444,37 @@ export interface Locale extends ILocale {
|
||||
};
|
||||
"_autoRemoval": {
|
||||
/**
|
||||
* 노트 자동 삭제를 사용하기
|
||||
* ノート自動削除を使用する
|
||||
*/
|
||||
"use": string;
|
||||
/**
|
||||
* 이 기간이 지난 후에 자동으로 삭제
|
||||
* この期間が過ぎたら自動的に削除する
|
||||
*/
|
||||
"deleteAfter": string;
|
||||
/**
|
||||
* 여기에 적힌 일 수가 지나면 노트를 자동으로 삭제합니다. 활성화 이후에는 삭제 대상인 노트도 같이 제거됩니다.
|
||||
* ここに書かれた日数が過ぎるとノートを自動的に削除します。有効化後は、削除対象のノートも一緒に削除されます。
|
||||
*/
|
||||
"deleteAfterDescription": string;
|
||||
/**
|
||||
* 고정된 노트를 제외하기
|
||||
* 固定されたノートを除外する
|
||||
*/
|
||||
"noPiningNotes": string;
|
||||
/**
|
||||
* 프로필에 고정된 노트를 제외하고 삭제합니다.
|
||||
* プロフィールに固定されたノートを除いて削除します。
|
||||
*/
|
||||
"noPiningNotesDescription": string;
|
||||
/**
|
||||
* 다이렉트 노트를 제외하기
|
||||
* ダイレクトノートを除外する
|
||||
*/
|
||||
"noSpecifiedNotes": string;
|
||||
/**
|
||||
* 다이렉트 노트를 제외하고 삭제합니다.
|
||||
* ダイレクトノートを除いて削除します。
|
||||
*/
|
||||
"noSpecifiedNotesDescription": string;
|
||||
/**
|
||||
* 現在、ノートの自動削除を設定することはできません。
|
||||
*/
|
||||
"youCantUseThisTime": string;
|
||||
};
|
||||
"_initialTutorial": {
|
||||
/**
|
||||
@ -6974,10 +6990,18 @@ export interface Locale extends ILocale {
|
||||
* コンテンツの削除
|
||||
*/
|
||||
"canDeleteContent": string;
|
||||
/**
|
||||
* ノート自動削除の利用
|
||||
*/
|
||||
"canUseAutoNoteRemoval": string;
|
||||
/**
|
||||
* アカウントの削除
|
||||
*/
|
||||
"canUseAccountRemoval": string;
|
||||
/**
|
||||
* アカウントの整理
|
||||
*/
|
||||
"canUseAccountTruncate": string;
|
||||
/**
|
||||
* 完全なアカウントの削除
|
||||
*/
|
||||
@ -6993,7 +7017,7 @@ export interface Locale extends ILocale {
|
||||
/**
|
||||
* ノート内の最大メンション数
|
||||
*/
|
||||
"mentionMax": string;
|
||||
"mentionLimit": string;
|
||||
/**
|
||||
* サーバー招待コードの発行
|
||||
*/
|
||||
@ -7019,9 +7043,9 @@ export interface Locale extends ILocale {
|
||||
*/
|
||||
"canManageAvatarDecorations": string;
|
||||
/**
|
||||
* ドライブ容量
|
||||
* ドライブ容量 (MB)
|
||||
*/
|
||||
"driveCapacity": string;
|
||||
"driveCapacityMb": string;
|
||||
/**
|
||||
* ファイルにNSFWを常に付与
|
||||
*/
|
||||
@ -7033,39 +7057,39 @@ export interface Locale extends ILocale {
|
||||
/**
|
||||
* ノートのピン留めの最大数
|
||||
*/
|
||||
"pinMax": string;
|
||||
"pinLimit": string;
|
||||
/**
|
||||
* アンテナの作成可能数
|
||||
*/
|
||||
"antennaMax": string;
|
||||
"antennaLimit": string;
|
||||
/**
|
||||
* アンテナに保持する最大ノート数
|
||||
*/
|
||||
"antennaNotesMax": string;
|
||||
"antennaNotesLimit": string;
|
||||
/**
|
||||
* ワードミュートの最大文字数
|
||||
*/
|
||||
"wordMuteMax": string;
|
||||
"wordMuteLimit": string;
|
||||
/**
|
||||
* Webhookの作成可能数
|
||||
*/
|
||||
"webhookMax": string;
|
||||
"webhookLimit": string;
|
||||
/**
|
||||
* クリップの作成可能数
|
||||
*/
|
||||
"clipMax": string;
|
||||
"clipLimit": string;
|
||||
/**
|
||||
* クリップ内のノートの最大数
|
||||
*/
|
||||
"noteEachClipsMax": string;
|
||||
"noteEachClipsLimit": string;
|
||||
/**
|
||||
* ユーザーリストの作成可能数
|
||||
*/
|
||||
"userListMax": string;
|
||||
"userListLimit": string;
|
||||
/**
|
||||
* ユーザーリスト内のユーザーの最大数
|
||||
*/
|
||||
"userEachUserListsMax": string;
|
||||
"userEachUserListsLimit": string;
|
||||
/**
|
||||
* レートリミット
|
||||
*/
|
||||
@ -7299,6 +7323,10 @@ export interface Locale extends ILocale {
|
||||
* 現在、アカウントの削除はできません。
|
||||
*/
|
||||
"youCantUseThisTime": string;
|
||||
/**
|
||||
* あなたは最高管理者であるため、アカウントを削除することはできません。
|
||||
*/
|
||||
"youAreRootAndCantUseThisTime": string;
|
||||
};
|
||||
"_accountTruncate": {
|
||||
/**
|
||||
@ -7325,6 +7353,10 @@ export interface Locale extends ILocale {
|
||||
* 整理が進行中
|
||||
*/
|
||||
"inProgress": string;
|
||||
/**
|
||||
* 現在、アカウントの整理はできません。
|
||||
*/
|
||||
"youCantUseThisTime": string;
|
||||
};
|
||||
"_ad": {
|
||||
/**
|
||||
|
@ -1301,7 +1301,10 @@ mindControlDescription: "必要に応じて、Misskeyの疲労感を少なくす
|
||||
hideCounters: "すべてのカウンターを隠す"
|
||||
hideCountersDescription: "ユーザーページのノート、フォロー、フォロワー数、およびこれらの統計をすべて非表示にします。"
|
||||
youAreOnVacation: "現在、休暇モードを使用しています。 このメッセージを閉じるにはここをクリックしてください。"
|
||||
autoRemoval: "노트 자동 삭제"
|
||||
autoRemoval: "ノート自動削除"
|
||||
autoRemovalDescription: "ノート自動削除は、作成してから一定期間が経過したノートを削除してくれる機能です。"
|
||||
dangerZone: "危険区域"
|
||||
dangerZoneDescription: "以下の機能を利用する際は、特にご注意ください。"
|
||||
|
||||
_bubbleGame:
|
||||
howToPlay: "遊び方"
|
||||
@ -1360,13 +1363,14 @@ _announcement:
|
||||
silenceDescription: "オンにすると、このお知らせは通知されず、既読にする必要もなくなります。"
|
||||
|
||||
_autoRemoval:
|
||||
use: "노트 자동 삭제를 사용하기"
|
||||
deleteAfter: "이 기간이 지난 후에 자동으로 삭제"
|
||||
deleteAfterDescription: "여기에 적힌 일 수가 지나면 노트를 자동으로 삭제합니다. 활성화 이후에는 삭제 대상인 노트도 같이 제거됩니다."
|
||||
noPiningNotes: "고정된 노트를 제외하기"
|
||||
noPiningNotesDescription: "프로필에 고정된 노트를 제외하고 삭제합니다."
|
||||
noSpecifiedNotes: "다이렉트 노트를 제외하기"
|
||||
noSpecifiedNotesDescription: "다이렉트 노트를 제외하고 삭제합니다."
|
||||
use: "ノート自動削除を使用する"
|
||||
deleteAfter: "この期間が過ぎたら自動的に削除する"
|
||||
deleteAfterDescription: "ここに書かれた日数が過ぎるとノートを自動的に削除します。有効化後は、削除対象のノートも一緒に削除されます。"
|
||||
noPiningNotes: "固定されたノートを除外する"
|
||||
noPiningNotesDescription: "プロフィールに固定されたノートを除いて削除します。"
|
||||
noSpecifiedNotes: "ダイレクトノートを除外する"
|
||||
noSpecifiedNotesDescription: "ダイレクトノートを除いて削除します。"
|
||||
youCantUseThisTime: "現在、ノートの自動削除を設定することはできません。"
|
||||
|
||||
_initialTutorial:
|
||||
launchTutorial: "チュートリアルを見る"
|
||||
@ -1801,29 +1805,31 @@ _role:
|
||||
canCreateContent: "コンテンツの作成"
|
||||
canUpdateContent: "コンテンツの編集"
|
||||
canDeleteContent: "コンテンツの削除"
|
||||
canUseAutoNoteRemoval: "ノート自動削除の利用"
|
||||
canUseAccountRemoval: "アカウントの削除"
|
||||
canUseAccountTruncate: "アカウントの整理"
|
||||
canPurgeAccount: "完全なアカウントの削除"
|
||||
canUpdateAvatar: "アイコンの変更"
|
||||
canUpdateBanner: "バナーの変更"
|
||||
mentionMax: "ノート内の最大メンション数"
|
||||
mentionLimit: "ノート内の最大メンション数"
|
||||
canInvite: "サーバー招待コードの発行"
|
||||
inviteLimit: "招待コードの作成可能数"
|
||||
inviteLimitCycle: "招待コードの発行間隔"
|
||||
inviteExpirationTime: "招待コードの有効期限"
|
||||
canManageCustomEmojis: "カスタム絵文字の管理"
|
||||
canManageAvatarDecorations: "アバターデコレーションの管理"
|
||||
driveCapacity: "ドライブ容量"
|
||||
driveCapacityMb: "ドライブ容量 (MB)"
|
||||
alwaysMarkNsfw: "ファイルにNSFWを常に付与"
|
||||
skipNsfwDetection: "AIによるNSFW検出を無視"
|
||||
pinMax: "ノートのピン留めの最大数"
|
||||
antennaMax: "アンテナの作成可能数"
|
||||
antennaNotesMax: "アンテナに保持する最大ノート数"
|
||||
wordMuteMax: "ワードミュートの最大文字数"
|
||||
webhookMax: "Webhookの作成可能数"
|
||||
clipMax: "クリップの作成可能数"
|
||||
noteEachClipsMax: "クリップ内のノートの最大数"
|
||||
userListMax: "ユーザーリストの作成可能数"
|
||||
userEachUserListsMax: "ユーザーリスト内のユーザーの最大数"
|
||||
pinLimit: "ノートのピン留めの最大数"
|
||||
antennaLimit: "アンテナの作成可能数"
|
||||
antennaNotesLimit: "アンテナに保持する最大ノート数"
|
||||
wordMuteLimit: "ワードミュートの最大文字数"
|
||||
webhookLimit: "Webhookの作成可能数"
|
||||
clipLimit: "クリップの作成可能数"
|
||||
noteEachClipsLimit: "クリップ内のノートの最大数"
|
||||
userListLimit: "ユーザーリストの作成可能数"
|
||||
userEachUserListsLimit: "ユーザーリスト内のユーザーの最大数"
|
||||
rateLimitFactor: "レートリミット"
|
||||
descriptionOfRateLimitFactor: "小さいほど制限が緩和され、大きいほど制限が強化されます。"
|
||||
canHideAds: "広告の非表示"
|
||||
@ -1890,6 +1896,7 @@ _accountDelete:
|
||||
started: "削除処理が開始されました。"
|
||||
inProgress: "削除が進行中"
|
||||
youCantUseThisTime: "現在、アカウントの削除はできません。"
|
||||
youAreRootAndCantUseThisTime: "あなたは最高管理者であるため、アカウントを削除することはできません。"
|
||||
|
||||
_accountTruncate:
|
||||
accountDelete: "アカウントの整理"
|
||||
@ -1898,6 +1905,7 @@ _accountTruncate:
|
||||
requestAccountTruncate: "アカウント整理をリクエスト"
|
||||
started: "整理処理が開始されました。"
|
||||
inProgress: "整理が進行中"
|
||||
youCantUseThisTime: "現在、アカウントの整理はできません。"
|
||||
|
||||
_ad:
|
||||
back: "戻る"
|
||||
|
@ -797,7 +797,7 @@ saveConfirm: "저장하시겠습니까?"
|
||||
deleteConfirm: "삭제하시겠습니까?"
|
||||
invalidValue: "올바른 값이 아닙니다."
|
||||
registry: "레지스트리"
|
||||
closeAccount: "계정 폐쇄"
|
||||
closeAccount: "계정 삭제"
|
||||
currentVersion: "현재 버전"
|
||||
latestVersion: "최신 버전"
|
||||
youAreRunningUpToDateClient: "사용 중인 클라이언트는 최신입니다."
|
||||
@ -1287,11 +1287,14 @@ hideCounters: "모든 카운터를 가리기"
|
||||
hideCountersDescription: "유저 페이지의 노트, 팔로잉, 팔로워 수 및 이러한 통계를 모두 숨깁니다."
|
||||
youAreOnVacation: "현재 휴가 모드를 사용 중입니다. 이 메시지를 닫으려면 여기를 클릭하세요."
|
||||
autoRemoval: "노트 자동 삭제"
|
||||
autoRemovalDescription: "노트 자동 삭제는 작성한 지 일정 기간이 지난 노트를 삭제해주는 기능입니다."
|
||||
abuseReportCategory: "신고 유형"
|
||||
selectCategory: "카테고리 선택"
|
||||
reportComplete: "신고 완료"
|
||||
blockThisUser: "이 유저 차단하기"
|
||||
muteThisUser: "이 유저 뮤트하기"
|
||||
dangerZone: "위험한 것들"
|
||||
dangerZoneDescription: "함부로 실행하면 어딘가 고장날 수 있는 설정들이니, 실행할 때는 주의하세요."
|
||||
_bubbleGame:
|
||||
howToPlay: "설명"
|
||||
hold: "홀드"
|
||||
@ -1348,11 +1351,12 @@ _announcement:
|
||||
_autoRemoval:
|
||||
use: "노트 자동 삭제를 사용하기"
|
||||
deleteAfter: "이 기간이 지난 후에 자동으로 삭제"
|
||||
deleteAfterDescription: 여기에 적힌 일 수가 지나면 노트를 자동으로 삭제합니다. 활성화 이후에는 삭제 대상인 노트도 같이 제거됩니다.
|
||||
deleteAfterDescription: "여기에 적힌 일 수가 지나면 노트를 자동으로 삭제합니다. 활성화 이후에는 삭제 대상인 노트도 같이 제거됩니다."
|
||||
noPiningNotes: "고정된 노트를 제외하기"
|
||||
noPiningNotesDescription: "프로필에 고정된 노트를 제외하고 삭제합니다."
|
||||
noSpecifiedNotes: "다이렉트 노트를 제외하기"
|
||||
noSpecifiedNotesDescription: "다이렉트 노트를 제외하고 삭제합니다."
|
||||
youCantUseThisTime: "지금은 노트 자동 삭제를 설정할 수 없습니다."
|
||||
_initialTutorial:
|
||||
launchTutorial: "튜토리얼 보기"
|
||||
title: "튜토리얼"
|
||||
@ -1777,11 +1781,13 @@ _role:
|
||||
ltlAvailable: "로컬 타임라인 보이기"
|
||||
canPublicNote: "공개 노트 허용"
|
||||
canInitiateConversation: "멘션, 답글, 인용 허용"
|
||||
mentionMax: "노트에 넣을 수 있는 멘션 수"
|
||||
mentionLimit: "노트에 넣을 수 있는 멘션 수"
|
||||
canCreateContent: "컨텐츠 생성 허용"
|
||||
canUpdateContent: "컨텐츠 수정 허용"
|
||||
canDeleteContent: "컨텐츠 삭제 허용"
|
||||
canUseAutoNoteRemoval: "노트 자동 삭제 허용"
|
||||
canUseAccountRemoval: "계정 삭제 허용"
|
||||
canUseAccountTruncate: "계정 청소 허용"
|
||||
canPurgeAccount: "완전한 계정 삭제 허용"
|
||||
canUpdateAvatar: "아바타 변경 허용"
|
||||
canUpdateBanner: "배너 변경 허용"
|
||||
@ -1791,18 +1797,18 @@ _role:
|
||||
inviteExpirationTime: "초대장 만료 기간"
|
||||
canManageCustomEmojis: "커스텀 이모지 관리"
|
||||
canManageAvatarDecorations: "아바타 장식 관리"
|
||||
driveCapacity: "드라이브 용량"
|
||||
driveCapacityMb: "드라이브 용량 (MB)"
|
||||
alwaysMarkNsfw: "파일을 항상 NSFW로 지정"
|
||||
skipNsfwDetection: "자동 NSFW 감지 기능 미사용"
|
||||
pinMax: "고정할 수 있는 노트 수"
|
||||
antennaMax: "만들 수 있는 안테나 수"
|
||||
antennaNotesMax: "안테나에서 저장할 수 있는 노트 수"
|
||||
wordMuteMax: "단어 뮤트할 수 있는 문자 수"
|
||||
webhookMax: "만들 수 있는 웹후크 수"
|
||||
clipMax: "만들 수 있는 클립 수"
|
||||
noteEachClipsMax: "클립에 넣을 수 있는 노트 수"
|
||||
userListMax: "만들 수 있는 유저 리스트 수"
|
||||
userEachUserListsMax: "유저 리스트에 넣을 수 있는 유저 수"
|
||||
pinLimit: "고정할 수 있는 노트 수"
|
||||
antennaLimit: "만들 수 있는 안테나 수"
|
||||
antennaNotesLimit: "안테나에서 저장할 수 있는 노트 수"
|
||||
wordMuteLimit: "단어 뮤트할 수 있는 문자 수"
|
||||
webhookLimit: "만들 수 있는 웹후크 수"
|
||||
clipLimit: "만들 수 있는 클립 수"
|
||||
noteEachClipsLimit: "클립에 넣을 수 있는 노트 수"
|
||||
userListLimit: "만들 수 있는 유저 리스트 수"
|
||||
userEachUserListsLimit: "유저 리스트에 넣을 수 있는 유저 수"
|
||||
rateLimitFactor: "요청 빈도 제한"
|
||||
descriptionOfRateLimitFactor: "작을수록 제한이 완화되고, 클수록 제한이 강화됩니다."
|
||||
canHideAds: "광고 숨기기"
|
||||
@ -1859,6 +1865,7 @@ _accountDelete:
|
||||
started: "삭제 작업이 시작되었습니다."
|
||||
inProgress: "삭제 진행 중"
|
||||
youCantUseThisTime: "지금은 계정 삭제를 진행할 수 없습니다."
|
||||
youAreRootAndCantUseThisTime: "당신은 최고 관리자이므로, 지금은 계정 삭제를 진행할 수 없습니다."
|
||||
_accountTruncate:
|
||||
accountTruncate: "계정 청소"
|
||||
purgeDriveFiles: "드라이브의 파일도 정리하기"
|
||||
@ -1866,6 +1873,7 @@ _accountTruncate:
|
||||
requestAccountTruncate: "계정 청소를 요청하기"
|
||||
started: "청소 작업이 시작되었습니다."
|
||||
inProgress: "청소 진행 중"
|
||||
youCantUseThisTime: "지금은 계정 청소를 진행할 수 없습니다."
|
||||
_ad:
|
||||
back: "뒤로"
|
||||
reduceFrequencyOfThisAd: "이 광고의 표시 빈도 낮추기"
|
||||
|
@ -2,18 +2,12 @@ export class AutoNoteRemoval1725706236633 {
|
||||
name = 'AutoNoteRemoval1725706236633'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`CREATE TABLE "auto_removal_condition" ("id" character varying(32) NOT NULL, "deleteAfter" bigint NOT NULL DEFAULT '7', "noPiningNotes" boolean NOT NULL DEFAULT true, "noSpecifiedNotes" boolean NOT NULL DEFAULT true, CONSTRAINT "PK_e6a0b2b5bc8fbc0a07d7e34be7d" PRIMARY KEY ("id"))`);
|
||||
await queryRunner.query(`CREATE TABLE "auto_removal_condition" ("userId" character varying(32) NOT NULL, "deleteAfter" bigint NOT NULL DEFAULT '7', "noPiningNotes" boolean NOT NULL DEFAULT true, "noSpecifiedNotes" boolean NOT NULL DEFAULT true)`);
|
||||
await queryRunner.query(`ALTER TABLE "user" ADD "autoRemoval" boolean NOT NULL DEFAULT false`);
|
||||
await queryRunner.query(`COMMENT ON COLUMN "user"."autoRemoval" IS 'Whether the User is using note auto removal.'`);
|
||||
await queryRunner.query(`ALTER TABLE "user" ADD "autoRemovalConditionId" character varying(32) NOT NULL`);
|
||||
await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "UQ_051c1df368299ee71088b7508b8" UNIQUE ("autoRemovalConditionId")`);
|
||||
await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "FK_051c1df368299ee71088b7508b8" FOREIGN KEY ("autoRemovalConditionId") REFERENCES "auto_removal_condition"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_051c1df368299ee71088b7508b8"`);
|
||||
await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "UQ_051c1df368299ee71088b7508b8"`);
|
||||
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "autoRemovalConditionId"`);
|
||||
await queryRunner.query(`COMMENT ON COLUMN "user"."autoRemoval" IS 'Whether the User is using note auto removal.'`);
|
||||
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "autoRemoval"`);
|
||||
await queryRunner.query(`DROP TABLE "auto_removal_condition"`);
|
||||
|
@ -40,6 +40,9 @@ export type RolePolicies = {
|
||||
canCreateContent: boolean;
|
||||
canUpdateContent: boolean;
|
||||
canDeleteContent: boolean;
|
||||
canUseAutoNoteRemoval: boolean;
|
||||
canUseAccountRemoval: boolean;
|
||||
canUseAccountTruncate: boolean;
|
||||
canPurgeAccount: boolean;
|
||||
canUpdateAvatar: boolean;
|
||||
canUpdateBanner: boolean;
|
||||
@ -69,7 +72,6 @@ export type RolePolicies = {
|
||||
userEachUserListsLimit: number;
|
||||
rateLimitFactor: number;
|
||||
avatarDecorationLimit: number;
|
||||
canUseAccountRemoval: boolean;
|
||||
mutualLinkSectionLimit: number;
|
||||
mutualLinkLimit: number;
|
||||
};
|
||||
@ -82,6 +84,9 @@ export const DEFAULT_POLICIES: RolePolicies = {
|
||||
canCreateContent: true,
|
||||
canUpdateContent: true,
|
||||
canDeleteContent: true,
|
||||
canUseAutoNoteRemoval: true,
|
||||
canUseAccountRemoval: true,
|
||||
canUseAccountTruncate: true,
|
||||
canPurgeAccount: true,
|
||||
canUpdateAvatar: true,
|
||||
canUpdateBanner: true,
|
||||
@ -111,7 +116,6 @@ export const DEFAULT_POLICIES: RolePolicies = {
|
||||
userEachUserListsLimit: 50,
|
||||
rateLimitFactor: 1,
|
||||
avatarDecorationLimit: 1,
|
||||
canUseAccountRemoval: true,
|
||||
mutualLinkSectionLimit: 1,
|
||||
mutualLinkLimit: 3,
|
||||
};
|
||||
@ -397,7 +401,9 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
||||
canCreateContent: calc('canCreateContent', vs => vs.some(v => v === true)),
|
||||
canUpdateContent: calc('canUpdateContent', vs => vs.some(v => v === true)),
|
||||
canDeleteContent: calc('canDeleteContent', vs => vs.some(v => v === true)),
|
||||
canUseAutoNoteRemoval: calc('canUseAutoNoteRemoval', vs => vs.some(v => v === true)),
|
||||
canUseAccountRemoval: calc('canUseAccountRemoval', vs => vs.some(v => v === true)),
|
||||
canUseAccountTruncate: calc('canUseAccountTruncate', vs => vs.some(v => v === true)),
|
||||
canPurgeAccount: calc('canPurgeAccount', vs => vs.some(v => v === true)),
|
||||
canUpdateAvatar: calc('canUpdateAvatar', vs => vs.some(v => v === true)),
|
||||
canUpdateBanner: calc('canUpdateBanner', vs => vs.some(v => v === true)),
|
||||
|
@ -196,6 +196,18 @@ export const packedRolePoliciesSchema = {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
canUseAutoNoteRemoval: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
canUseAccountRemoval: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
canUseAccountTruncate: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
canPurgeAccount: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
@ -312,10 +324,6 @@ export const packedRolePoliciesSchema = {
|
||||
type: 'integer',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
canUseAccountRemoval: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
mutualLinkSectionLimit: {
|
||||
type: 'integer',
|
||||
optional: false, nullable: false,
|
||||
|
@ -151,7 +151,7 @@ export class QueueProcessorService implements OnApplicationShutdown {
|
||||
case 'aggregateRetention': return this.aggregateRetentionProcessorService.process();
|
||||
case 'checkExpiredMutings': return this.checkExpiredMutingsProcessorService.process();
|
||||
case 'clean': return this.cleanProcessorService.process();
|
||||
case 'autoNoteRemoval': return this.autoNoteRemovalProcessorService.process();
|
||||
case 'autoNoteRemoval': return this.autoNoteRemovalProcessorService.process(job);
|
||||
default: throw new Error(`unrecognized job type ${job.name} for system`);
|
||||
}
|
||||
}, {
|
||||
|
@ -12,6 +12,7 @@ import type { MiNote } from '@/models/Note.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { NoteDeleteService } from '@/core/NoteDeleteService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||
import type * as Bull from 'bullmq';
|
||||
|
||||
@ -33,6 +34,7 @@ export class AutoNoteRemovalProcessorService {
|
||||
private autoRemovalConditionRepository: AutoRemovalConditionRepository,
|
||||
|
||||
private idService: IdService,
|
||||
private roleService: RoleService,
|
||||
private noteDeleteService: NoteDeleteService,
|
||||
private queueLoggerService: QueueLoggerService,
|
||||
) {
|
||||
@ -40,7 +42,7 @@ export class AutoNoteRemovalProcessorService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async process(): Promise<void> {
|
||||
public async process(job: Bull.Job<Record<string, unknown>>): Promise<void> {
|
||||
this.logger.info('Checking notes that to remove automatically...');
|
||||
this.logger.info('Checking users that enabled note auto-removal');
|
||||
const users = await this.usersRepository.find({ where: { autoRemoval: true } });
|
||||
@ -51,6 +53,8 @@ export class AutoNoteRemovalProcessorService {
|
||||
const now = Date.now();
|
||||
|
||||
for (const user of users) {
|
||||
const policies = await this.roleService.getUserPolicies(user.id);
|
||||
if (!policies.canUseAutoNoteRemoval) continue;
|
||||
const autoRemovalCondition = await this.autoRemovalConditionRepository.findOneByOrFail({ userId: user.id });
|
||||
const pinings: MiUserNotePining[] = await this.userNotePiningsRepository.findBy({ userId: user.id });
|
||||
const piningNoteIds: string[] = pinings.map(pining => pining.noteId); // pining.note always undefined (bug?)
|
||||
@ -65,11 +69,11 @@ export class AutoNoteRemovalProcessorService {
|
||||
// Delete notes
|
||||
let cursor: MiNote['id'] | null = null;
|
||||
let condition: string[] = [];
|
||||
if (autoRemovalCondition.noSpecifiedNotes === true) {
|
||||
if (autoRemovalCondition.noSpecifiedNotes) {
|
||||
condition = [...condition, ...specifiedNoteIds];
|
||||
}
|
||||
|
||||
if (autoRemovalCondition.noPiningNotes === true) {
|
||||
if (autoRemovalCondition.noPiningNotes) {
|
||||
condition = [...condition, ...piningNoteIds];
|
||||
}
|
||||
|
||||
@ -99,11 +103,13 @@ export class AutoNoteRemovalProcessorService {
|
||||
const createdAt: number = this.idService.parse(note.id).date.getTime();
|
||||
const delta: number = now - createdAt;
|
||||
if (delta > deleteAfter) {
|
||||
await Promise.bind(this.noteDeleteService.delete(user, note, false, user));
|
||||
Promise.bind(this.noteDeleteService.delete(user, note, false, user));
|
||||
}
|
||||
}
|
||||
await job.updateProgress(100 / users.length * users.indexOf(user));
|
||||
}
|
||||
|
||||
await job.updateProgress(100);
|
||||
this.logger.succ('All of auto-removable notes deleted');
|
||||
}
|
||||
|
||||
|
@ -17,13 +17,9 @@ export const meta = {
|
||||
requireCredential: true,
|
||||
|
||||
secure: true,
|
||||
requireRolePolicy: 'canUseAccountRemoval',
|
||||
|
||||
errors: {
|
||||
removalDisabled: {
|
||||
message: 'Account removal is disabled by your role.',
|
||||
code: 'REMOVAL_DISABLED',
|
||||
id: '453d954b-3d8b-4df0-a261-b26ec6660ea3',
|
||||
},
|
||||
authenticationFailed: {
|
||||
message: 'Your password or 2FA token is invalid.',
|
||||
code: 'AUTHENTICATION_FAILED',
|
||||
@ -57,16 +53,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
|
||||
private userAuthService: UserAuthService,
|
||||
private deleteAccountService: DeleteAccountService,
|
||||
private roleService: RoleService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
|
||||
|
||||
const policies = await this.roleService.getUserPolicies(me.id);
|
||||
if (!policies.canUseAccountRemoval) {
|
||||
throw new ApiError(meta.errors.removalDisabled);
|
||||
}
|
||||
|
||||
const userDetailed = await this.usersRepository.findOneByOrFail({ id: me.id });
|
||||
if (userDetailed.isDeleted) {
|
||||
throw new ApiError(meta.errors.alreadyRemoved);
|
||||
|
@ -10,11 +10,26 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { TruncateAccountService } from '@/core/TruncateAccountService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { UserAuthService } from '@/core/UserAuthService.js';
|
||||
import {ApiError} from "@/server/api/error.js";
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
||||
secure: true,
|
||||
requireRolePolicy: 'canUseAccountTruncate',
|
||||
|
||||
errors: {
|
||||
authenticationFailed: {
|
||||
message: 'Your password or 2FA token is invalid.',
|
||||
code: 'AUTHENTICATION_FAILED',
|
||||
id: 'ea791cff-63e7-4b2a-92fc-646ab641794e',
|
||||
},
|
||||
alreadyRemoved: {
|
||||
message: 'Your account is removed.',
|
||||
code: 'ACCOUNT_REMOVED',
|
||||
id: '59b8f0e6-6eb2-4dc1-a080-1de3108416d0',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
@ -40,30 +55,26 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
private truncateAccountService: TruncateAccountService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const token = ps.token;
|
||||
const purgeDrive = ps.purgeDrive ? true : false;
|
||||
const purgeDrive = !!ps.purgeDrive;
|
||||
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: me.id });
|
||||
|
||||
if (profile.twoFactorEnabled) {
|
||||
if (token == null) {
|
||||
throw new Error('authentication failed');
|
||||
}
|
||||
|
||||
try {
|
||||
await this.userAuthService.twoFactorAuthenticate(profile, token);
|
||||
} catch (e) {
|
||||
throw new Error('authentication failed');
|
||||
}
|
||||
}
|
||||
|
||||
const userDetailed = await this.usersRepository.findOneByOrFail({ id: me.id });
|
||||
if (userDetailed.isDeleted) {
|
||||
return;
|
||||
throw new ApiError(meta.errors.alreadyRemoved);
|
||||
}
|
||||
|
||||
const passwordMatched = await bcrypt.compare(ps.password, profile.password!);
|
||||
if (!passwordMatched) {
|
||||
throw new Error('incorrect password');
|
||||
throw new ApiError(meta.errors.authenticationFailed);
|
||||
}
|
||||
|
||||
if (profile.twoFactorEnabled) {
|
||||
const token = ps.token;
|
||||
if (token == null) {
|
||||
throw new ApiError(meta.errors.authenticationFailed);
|
||||
}
|
||||
|
||||
await this.userAuthService.twoFactorAuthenticate(profile, token);
|
||||
}
|
||||
|
||||
await this.truncateAccountService.truncateAccount(me, purgeDrive);
|
||||
|
@ -79,6 +79,9 @@ export const ROLE_POLICIES = [
|
||||
'canCreateContent',
|
||||
'canUpdateContent',
|
||||
'canDeleteContent',
|
||||
'canUseAutoNoteRemoval',
|
||||
'canUseAccountRemoval',
|
||||
'canUseAccountTruncate',
|
||||
'canPurgeAccount',
|
||||
'canUpdateAvatar',
|
||||
'canUpdateBanner',
|
||||
@ -108,7 +111,6 @@ export const ROLE_POLICIES = [
|
||||
'userEachUserListsLimit',
|
||||
'rateLimitFactor',
|
||||
'avatarDecorationLimit',
|
||||
'canUseAccountRemoval',
|
||||
'mutualLinkSectionLimit',
|
||||
'mutualLinkLimit',
|
||||
] as const;
|
||||
|
@ -245,6 +245,26 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.canUseAutoNoteRemoval, 'canUseAutoNoteRemoval'])">
|
||||
<template #label>{{ i18n.ts._role._options.canUseAutoNoteRemoval }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.canUseAutoNoteRemoval.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.canUseAutoNoteRemoval.value ? i18n.ts.yes : i18n.ts.no }}</span>
|
||||
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.canUseAutoNoteRemoval)"></i></span>
|
||||
</template>
|
||||
<div class="_gaps">
|
||||
<MkSwitch v-model="role.policies.canUseAutoNoteRemoval.useDefault" :readonly="readonly">
|
||||
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="role.policies.canUseAutoNoteRemoval.value" :disabled="role.policies.canUseAutoNoteRemoval.useDefault" :readonly="readonly">
|
||||
<template #label>{{ i18n.ts.enable }}</template>
|
||||
</MkSwitch>
|
||||
<MkRange v-model="role.policies.canUseAutoNoteRemoval.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
|
||||
<template #label>{{ i18n.ts._role.priority }}</template>
|
||||
</MkRange>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.canUseAccountRemoval, 'canUseAccountRemoval'])">
|
||||
<template #label>{{ i18n.ts._role._options.canUseAccountRemoval }}</template>
|
||||
<template #suffix>
|
||||
@ -265,6 +285,26 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.canUseAccountTruncate, 'canUseAccountTruncate'])">
|
||||
<template #label>{{ i18n.ts._role._options.canUseAccountTruncate }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.canUseAccountTruncate.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.canUseAccountTruncate.value ? i18n.ts.yes : i18n.ts.no }}</span>
|
||||
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.canUseAccountTruncate)"></i></span>
|
||||
</template>
|
||||
<div class="_gaps">
|
||||
<MkSwitch v-model="role.policies.canUseAccountTruncate.useDefault" :readonly="readonly">
|
||||
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="role.policies.canUseAccountTruncate.value" :disabled="role.policies.canUseAccountTruncate.useDefault" :readonly="readonly">
|
||||
<template #label>{{ i18n.ts.enable }}</template>
|
||||
</MkSwitch>
|
||||
<MkRange v-model="role.policies.canUseAccountTruncate.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
|
||||
<template #label>{{ i18n.ts._role.priority }}</template>
|
||||
</MkRange>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.canPurgeAccount, 'canPurgeAccount'])">
|
||||
<template #label>{{ i18n.ts._role._options.canPurgeAccount }}</template>
|
||||
<template #suffix>
|
||||
@ -325,8 +365,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.mentionMax, 'mentionLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.mentionMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.mentionLimit, 'mentionLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.mentionLimit }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.mentionLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.mentionLimit.value }}</span>
|
||||
@ -543,8 +583,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.driveCapacity, 'driveCapacityMb'])">
|
||||
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.driveCapacityMb, 'driveCapacityMb'])">
|
||||
<template #label>{{ i18n.ts._role._options.driveCapacityMb }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.driveCapacityMb.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.driveCapacityMb.value + 'MB' }}</span>
|
||||
@ -603,8 +643,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.pinMax, 'pinLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.pinMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.pinLimit, 'pinLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.pinLimit }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.pinLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.pinLimit.value }}</span>
|
||||
@ -622,8 +662,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaMax, 'antennaLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.antennaMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaLimit, 'antennaLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.antennaLimit }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.antennaLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.antennaLimit.value }}</span>
|
||||
@ -641,8 +681,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaNotesMax, 'antennaNotesLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.antennaNotesMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaNotesLimit, 'antennaNotesLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.antennaNotesLimit }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.antennaNotesLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.antennaNotesLimit.value }}</span>
|
||||
@ -660,8 +700,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.wordMuteMax, 'wordMuteLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.wordMuteMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.wordMuteLimit, 'wordMuteLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.wordMuteLimit }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.wordMuteLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.wordMuteLimit.value }}</span>
|
||||
@ -680,8 +720,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.webhookMax, 'webhookLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.webhookMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.webhookLimit, 'webhookLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.webhookLimit }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.webhookLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.webhookLimit.value }}</span>
|
||||
@ -699,8 +739,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.clipMax, 'clipLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.clipMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.clipLimit, 'clipLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.clipLimit }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.clipLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.clipLimit.value }}</span>
|
||||
@ -718,8 +758,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.noteEachClipsMax, 'noteEachClipsLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.noteEachClipsMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.noteEachClipsLimit, 'noteEachClipsLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.noteEachClipsLimit }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.noteEachClipsLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.noteEachClipsLimit.value }}</span>
|
||||
@ -737,8 +777,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.userListMax, 'userListLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.userListMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.userListLimit, 'userListLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.userListLimit }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.userListLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.userListLimit.value }}</span>
|
||||
@ -756,8 +796,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.userEachUserListsMax, 'userEachUserListsLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.userEachUserListsMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.userEachUserListsLimit, 'userEachUserListsLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.userEachUserListsLimit }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.userEachUserListsLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.userEachUserListsLimit.value }}</span>
|
||||
|
@ -80,6 +80,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.canUseAutoNoteRemoval, 'canUseAutoNoteRemoval'])">
|
||||
<template #label>{{ i18n.ts._role._options.canUseAutoNoteRemoval }}</template>
|
||||
<template #suffix>{{ policies.canUseAutoNoteRemoval ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
<MkSwitch v-model="policies.canUseAutoNoteRemoval">
|
||||
<template #label>{{ i18n.ts.enable }}</template>
|
||||
</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.canUseAccountRemoval, 'canUseAccountRemoval'])">
|
||||
<template #label>{{ i18n.ts._role._options.canUseAccountRemoval }}</template>
|
||||
<template #suffix>{{ policies.canUseAccountRemoval ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
@ -88,6 +96,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.canUseAccountTruncate, 'canUseAccountTruncate'])">
|
||||
<template #label>{{ i18n.ts._role._options.canUseAccountTruncate }}</template>
|
||||
<template #suffix>{{ policies.canUseAccountTruncate ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
<MkSwitch v-model="policies.canUseAccountTruncate">
|
||||
<template #label>{{ i18n.ts.enable }}</template>
|
||||
</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.canPurgeAccount, 'canPurgeAccount'])">
|
||||
<template #label>{{ i18n.ts._role._options.canPurgeAccount }}</template>
|
||||
<template #suffix>{{ policies.canPurgeAccount ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
@ -112,8 +128,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.mentionMax, 'mentionLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.mentionMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.mentionLimit, 'mentionLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.mentionLimit }}</template>
|
||||
<template #suffix>{{ policies.mentionLimit }}</template>
|
||||
<MkInput v-model="policies.mentionLimit" type="number">
|
||||
</MkInput>
|
||||
@ -198,8 +214,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.driveCapacity, 'driveCapacityMb'])">
|
||||
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.driveCapacityMb, 'driveCapacityMb'])">
|
||||
<template #label>{{ i18n.ts._role._options.driveCapacityMb }}</template>
|
||||
<template #suffix>{{ policies.driveCapacityMb }}MB</template>
|
||||
<MkInput v-model="policies.driveCapacityMb" type="number">
|
||||
<template #suffix>MB</template>
|
||||
@ -222,65 +238,65 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.pinMax, 'pinLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.pinMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.pinLimit, 'pinLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.pinLimit }}</template>
|
||||
<template #suffix>{{ policies.pinLimit }}</template>
|
||||
<MkInput v-model="policies.pinLimit" type="number">
|
||||
</MkInput>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaMax, 'antennaLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.antennaMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaLimit, 'antennaLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.antennaLimit }}</template>
|
||||
<template #suffix>{{ policies.antennaLimit }}</template>
|
||||
<MkInput v-model="policies.antennaLimit" type="number">
|
||||
</MkInput>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaNotesMax, 'antennaNotesLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.antennaNotesMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaNotesLimit, 'antennaNotesLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.antennaNotesLimit }}</template>
|
||||
<template #suffix>{{ policies.antennaNotesLimit }}</template>
|
||||
<MkInput v-model="policies.antennaNotesLimit" type="number">
|
||||
</MkInput>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.wordMuteMax, 'wordMuteLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.wordMuteMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.wordMuteLimit, 'wordMuteLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.wordMuteLimit }}</template>
|
||||
<template #suffix>{{ policies.wordMuteLimit }}</template>
|
||||
<MkInput v-model="policies.wordMuteLimit" type="number">
|
||||
<template #suffix>items</template>
|
||||
</MkInput>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.webhookMax, 'webhookLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.webhookMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.webhookLimit, 'webhookLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.webhookLimit }}</template>
|
||||
<template #suffix>{{ policies.webhookLimit }}</template>
|
||||
<MkInput v-model="policies.webhookLimit" type="number">
|
||||
</MkInput>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.clipMax, 'clipLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.clipMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.clipLimit, 'clipLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.clipLimit }}</template>
|
||||
<template #suffix>{{ policies.clipLimit }}</template>
|
||||
<MkInput v-model="policies.clipLimit" type="number">
|
||||
</MkInput>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.noteEachClipsMax, 'noteEachClipsLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.noteEachClipsMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.noteEachClipsLimit, 'noteEachClipsLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.noteEachClipsLimit }}</template>
|
||||
<template #suffix>{{ policies.noteEachClipsLimit }}</template>
|
||||
<MkInput v-model="policies.noteEachClipsLimit" type="number">
|
||||
</MkInput>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.userListMax, 'userListLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.userListMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.userListLimit, 'userListLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.userListLimit }}</template>
|
||||
<template #suffix>{{ policies.userListLimit }}</template>
|
||||
<MkInput v-model="policies.userListLimit" type="number">
|
||||
</MkInput>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.userEachUserListsMax, 'userEachUserListsLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.userEachUserListsMax }}</template>
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.userEachUserListsLimit, 'userEachUserListsLimit'])">
|
||||
<template #label>{{ i18n.ts._role._options.userEachUserListsLimit }}</template>
|
||||
<template #suffix>{{ policies.userEachUserListsLimit }}</template>
|
||||
<MkInput v-model="policies.userEachUserListsLimit" type="number">
|
||||
</MkInput>
|
||||
|
@ -16,6 +16,40 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<FormSection>
|
||||
<template #label><i class="ti ti-time-duration-off"></i> {{ i18n.ts.autoRemoval }}</template>
|
||||
<template #description>{{ i18n.ts.autoRemovalDescription }}</template>
|
||||
|
||||
<div v-if="$i.policies.canUseAutoNoteRemoval" class="_gaps_m">
|
||||
<MkInfo warn rounded>
|
||||
{{ i18n.ts.thisIsExperimentalFeature }}
|
||||
</MkInfo>
|
||||
|
||||
<MkSwitch v-model="autoRemoval" @update:modelValue="saveRemovalCondition()">{{ i18n.ts._autoRemoval.use }}</MkSwitch>
|
||||
|
||||
<template v-if="autoRemoval">
|
||||
<MkInput v-model="deleteAfter" :type="'number'" :placeholder="'7'" :required="true" @update:modelValue="periodChanged = true">
|
||||
<template #label>{{ i18n.ts._autoRemoval.deleteAfter }}</template>
|
||||
<template #caption>{{ i18n.ts._autoRemoval.deleteAfterDescription }}</template>
|
||||
</MkInput>
|
||||
<MkButton v-if="periodChanged" primary class="save" @click="saveRemovalCondition"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
|
||||
|
||||
<MkSwitch v-model="noPiningNotes" @update:modelValue="saveRemovalCondition()">
|
||||
<template #label>{{ i18n.ts._autoRemoval.noPiningNotes }}</template>
|
||||
<template #caption>{{ i18n.ts._autoRemoval.noPiningNotesDescription }}</template>
|
||||
</MkSwitch>
|
||||
|
||||
<MkSwitch v-model="noSpecifiedNotes" @update:modelValue="saveRemovalCondition()">
|
||||
<template #label>{{ i18n.ts._autoRemoval.noSpecifiedNotes }}</template>
|
||||
<template #caption>{{ i18n.ts._autoRemoval.noSpecifiedNotesDescription }}</template>
|
||||
</MkSwitch>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else class="_gaps_m">
|
||||
<MkInfo>{{ i18n.ts._autoRemoval.youCantUseThisTime }}</MkInfo>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<FormSection>
|
||||
<template #label><i class="ti ti-lock-access"></i> {{ i18n.ts.hideSensitiveInformation }}</template>
|
||||
<template #description>{{ i18n.ts._hideSensitiveInformation.about }}</template>
|
||||
@ -97,39 +131,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkSwitch>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<!--
|
||||
<MkSelect v-model="followingVisibility" @update:modelValue="save()">
|
||||
<template #label>{{ i18n.ts.followingVisibility }}</template>
|
||||
<option value="public">{{ i18n.ts._ffVisibility.public }}</option>
|
||||
<option value="followers">{{ i18n.ts._ffVisibility.followers }}</option>
|
||||
<option value="private">{{ i18n.ts._ffVisibility.private }}</option>
|
||||
</MkSelect>
|
||||
|
||||
<MkSelect v-model="followersVisibility" @update:modelValue="save()">
|
||||
<template #label>{{ i18n.ts.followersVisibility }}</template>
|
||||
<option value="public">{{ i18n.ts._ffVisibility.public }}</option>
|
||||
<option value="followers">{{ i18n.ts._ffVisibility.followers }}</option>
|
||||
<option value="private">{{ i18n.ts._ffVisibility.private }}</option>
|
||||
</MkSelect>
|
||||
|
||||
<MkSwitch v-model="hideOnlineStatus" @update:modelValue="save()">
|
||||
{{ i18n.ts.hideOnlineStatus }}
|
||||
<template #caption>{{ i18n.ts.hideOnlineStatusDescription }}</template>
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="noCrawle" @update:modelValue="save()">
|
||||
{{ i18n.ts.noCrawle }}
|
||||
<template #caption>{{ i18n.ts.noCrawleDescription }}</template>
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="preventAiLearning" @update:modelValue="save()">
|
||||
{{ i18n.ts.preventAiLearning }}<span class="_beta">{{ i18n.ts.beta }}</span>
|
||||
<template #caption>{{ i18n.ts.preventAiLearningDescription }}</template>
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="isExplorable" @update:modelValue="save()">
|
||||
{{ i18n.ts.makeExplorable }}
|
||||
<template #caption>{{ i18n.ts.makeExplorableDescription }}</template>
|
||||
</MkSwitch>
|
||||
-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -147,10 +148,16 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import * as os from '@/os.js';
|
||||
import { unisonReload } from '@/scripts/unison-reload.js';
|
||||
import MkButton from "@/components/MkButton.vue";
|
||||
import MkInput from "@/components/MkInput.vue";
|
||||
|
||||
const $i = signinRequired();
|
||||
|
||||
const isVacation = ref<boolean | undefined>($i.isVacation !== null ? $i.isVacation : undefined);
|
||||
const autoRemoval = ref<boolean>($i.autoRemovalCondition.active);
|
||||
const deleteAfter = ref<number>($i.autoRemovalCondition.deleteAfter || 7);
|
||||
const noPiningNotes = ref<boolean>($i.autoRemovalCondition.noPiningNotes);
|
||||
const noSpecifiedNotes = ref<boolean>($i.autoRemovalCondition.noSpecifiedNotes);
|
||||
const periodChanged = ref<boolean>(false);
|
||||
|
||||
const hideCounters = computed(defaultStore.makeGetterSetter('hideCounters'));
|
||||
const enableCondensedLineForAcct = computed(defaultStore.makeGetterSetter('enableCondensedLineForAcct'));
|
||||
@ -160,6 +167,15 @@ const hideDriveFileList = computed(defaultStore.makeGetterSetter('hideDriveFileL
|
||||
const hideModerationLog = computed(defaultStore.makeGetterSetter('hideModerationLog'));
|
||||
const hideRoleList = computed(defaultStore.makeGetterSetter('hideRoleList'));
|
||||
|
||||
function saveRemovalCondition() {
|
||||
misskeyApi('i/update-removal-condition', {
|
||||
active: autoRemoval.value,
|
||||
deleteAfter: deleteAfter.value,
|
||||
noPiningNotes: noPiningNotes.value,
|
||||
noSpecifiedNotes: noSpecifiedNotes.value,
|
||||
});
|
||||
}
|
||||
|
||||
function save() {
|
||||
if (isVacation.value === true) {
|
||||
defaultStore.set('vacationAlert', true);
|
||||
|
@ -36,61 +36,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder>
|
||||
<template #label>{{ i18n.ts.autoRemoval }}</template>
|
||||
|
||||
<div class="_gaps_m">
|
||||
<MkSwitch v-model="autoRemoval">{{ i18n.ts._autoRemoval.use }}</MkSwitch>
|
||||
|
||||
<template v-if="autoRemoval">
|
||||
<MkInput v-model="deleteAfter" :type="'number'" :placeholder="'7'" :required="true">
|
||||
<template #label>{{ i18n.ts._autoRemoval.deleteAfter }}</template>
|
||||
<template #caption>{{ i18n.ts._autoRemoval.deleteAfterDescription }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkSwitch v-model="noPiningNotes">
|
||||
<template #label>{{ i18n.ts._autoRemoval.noPiningNotes }}</template>
|
||||
<template #caption>{{ i18n.ts._autoRemoval.noPiningNotesDescription }}</template>
|
||||
</MkSwitch>
|
||||
|
||||
<MkSwitch v-model="noSpecifiedNotes">
|
||||
<template #label>{{ i18n.ts._autoRemoval.noSpecifiedNotes }}</template>
|
||||
<template #caption>{{ i18n.ts._autoRemoval.noSpecifiedNotesDescription }}</template>
|
||||
</MkSwitch>
|
||||
</template>
|
||||
<MkButton primary class="save" @click="saveRemovalCondition"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder>
|
||||
<template #icon><i class="ti ti-alert-triangle"></i></template>
|
||||
<template #label>{{ i18n.ts.closeAccount }}</template>
|
||||
|
||||
<div v-if="$i.policies.canUseAccountRemoval" class="_gaps_m">
|
||||
<MkInfo warn>{{ i18n.ts._accountDelete.mayTakeTime }}</MkInfo>
|
||||
<MkInfo>{{ i18n.ts._accountDelete.sendEmail }}</MkInfo>
|
||||
<MkButton v-if="!$i.isDeleted" danger @click="deleteAccount">{{ i18n.ts._accountDelete.requestAccountDelete }}</MkButton>
|
||||
<MkButton v-else disabled>{{ i18n.ts._accountDelete.inProgress }}</MkButton>
|
||||
</div>
|
||||
<div v-else class="_gaps_m">
|
||||
<MkInfo warn>{{ i18n.ts._accountDelete.youCantUseThisTime }}</MkInfo>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder>
|
||||
<template #icon><i class="ti ti-recycle"></i></template>
|
||||
<template #label>{{ i18n.ts.truncateAccount }}</template>
|
||||
|
||||
<div class="_gaps_m">
|
||||
<FormInfo warn>{{ i18n.ts._accountTruncate.mayTakeTime }}</FormInfo>
|
||||
<MkSwitch v-model="purgeDrive">
|
||||
<template #label>{{ i18n.ts._accountTruncate.purgeDriveFiles }}</template>
|
||||
</MkSwitch>
|
||||
<MkButton v-if="!$i.isDeleted" danger @click="truncateAccount">{{ i18n.ts._accountTruncate.requestAccountTruncate }}</MkButton>
|
||||
<MkButton v-else disabled>{{ i18n.ts._accountTruncate.inProgress }}</MkButton>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder>
|
||||
<template #icon><i class="ti ti-code"></i></template>
|
||||
<template #label>{{ i18n.ts.developer }}</template>
|
||||
@ -115,6 +60,48 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkButton danger @click="updateRepliesAll(false)"><i class="ti ti-messages-off"></i> {{ i18n.ts.hideRepliesToOthersInTimelineAll }}</MkButton>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<FormSection>
|
||||
<template #label><i class="ti ti-alert-circle"></i> {{ i18n.ts.dangerZone }}</template>
|
||||
<template #description>{{ i18n.ts.dangerZoneDescription }}</template>
|
||||
|
||||
<div class="_gaps_s">
|
||||
<MkFolder>
|
||||
<template #icon><i class="ti ti-trash"></i></template>
|
||||
<template #label>{{ i18n.ts.closeAccount }}</template>
|
||||
|
||||
<div v-if="$i.policies.canUseAccountRemoval && !$i.isRoot" class="_gaps_m">
|
||||
<MkInfo warn>{{ i18n.ts._accountDelete.mayTakeTime }}</MkInfo>
|
||||
<MkInfo>{{ i18n.ts._accountDelete.sendEmail }}</MkInfo>
|
||||
<MkButton v-if="!$i.isDeleted" danger @click="deleteAccount">{{ i18n.ts._accountDelete.requestAccountDelete }}</MkButton>
|
||||
<MkButton v-else disabled>{{ i18n.ts._accountDelete.inProgress }}</MkButton>
|
||||
</div>
|
||||
<div v-else-if="$i.isRoot === true" class="_gaps_m">
|
||||
<MkInfo>{{ i18n.ts._accountDelete.youAreRootAndCantUseThisTime }}</MkInfo>
|
||||
</div>
|
||||
<div v-else class="_gaps_m">
|
||||
<MkInfo>{{ i18n.ts._accountDelete.youCantUseThisTime }}</MkInfo>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder>
|
||||
<template #icon><i class="ti ti-bomb"></i></template>
|
||||
<template #label>{{ i18n.ts.truncateAccount }}</template>
|
||||
|
||||
<div v-if="$i.policies.canUseAccountTruncate" class="_gaps_m">
|
||||
<MkInfo warn>{{ i18n.ts._accountTruncate.mayTakeTime }}</MkInfo>
|
||||
<MkSwitch v-model="purgeDrive">
|
||||
<template #label>{{ i18n.ts._accountTruncate.purgeDriveFiles }}</template>
|
||||
</MkSwitch>
|
||||
<MkButton v-if="!$i.isDeleted" danger @click="truncateAccount">{{ i18n.ts._accountTruncate.requestAccountTruncate }}</MkButton>
|
||||
<MkButton v-else disabled>{{ i18n.ts._accountTruncate.inProgress }}</MkButton>
|
||||
</div>
|
||||
<div v-else class="_gaps_m">
|
||||
<MkInfo>{{ i18n.ts._accountTruncate.youCantUseThisTime }}</MkInfo>
|
||||
</div>
|
||||
</MkFolder>
|
||||
</div>
|
||||
</FormSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -140,19 +127,6 @@ const $i = signinRequired();
|
||||
const purgeDrive = ref<boolean>(false);
|
||||
const devMode = computed(defaultStore.makeGetterSetter('devMode'));
|
||||
const defaultWithReplies = computed(defaultStore.makeGetterSetter('defaultWithReplies'));
|
||||
const autoRemoval = ref<boolean>($i.autoRemovalCondition.active);
|
||||
const deleteAfter = ref<number>($i.autoRemovalCondition.deleteAfter || 7);
|
||||
const noPiningNotes = ref<boolean>($i.autoRemovalCondition.noPiningNotes);
|
||||
const noSpecifiedNotes = ref<boolean>($i.autoRemovalCondition.noSpecifiedNotes);
|
||||
|
||||
function saveRemovalCondition() {
|
||||
misskeyApi('i/update-removal-condition', {
|
||||
active: autoRemoval.value,
|
||||
deleteAfter: deleteAfter.value,
|
||||
noPiningNotes: noPiningNotes.value,
|
||||
noSpecifiedNotes: noSpecifiedNotes.value,
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteAccount() {
|
||||
{
|
||||
|
@ -4972,6 +4972,9 @@ export type components = {
|
||||
canCreateContent: boolean;
|
||||
canUpdateContent: boolean;
|
||||
canDeleteContent: boolean;
|
||||
canUseAutoNoteRemoval: boolean;
|
||||
canUseAccountRemoval: boolean;
|
||||
canUseAccountTruncate: boolean;
|
||||
canPurgeAccount: boolean;
|
||||
canUpdateAvatar: boolean;
|
||||
canUpdateBanner: boolean;
|
||||
@ -5001,7 +5004,6 @@ export type components = {
|
||||
userEachUserListsLimit: number;
|
||||
rateLimitFactor: number;
|
||||
avatarDecorationLimit: number;
|
||||
canUseAccountRemoval: boolean;
|
||||
mutualLinkSectionLimit: number;
|
||||
mutualLinkLimit: number;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user