enhance(frontend): バックアップされた設定のプロファイルを削除できるように

This commit is contained in:
syuilo 2025-05-06 20:57:55 +09:00
parent 95a1d17cf6
commit 5d787e5bb9
6 changed files with 86 additions and 11 deletions

View File

@ -10,6 +10,7 @@
- Feat: マウスでもタイムラインを引っ張って更新できるように
- アクセシビリティ設定からオフにすることもできます
- Enhance: タイムラインのパフォーマンスを向上
- Enhance: バックアップされた設定のプロファイルを削除できるように
- Fix: 一部のブラウザでアコーディオンメニューのアニメーションが動作しない問題を修正
- Fix: ダイアログのお知らせが画面からはみ出ることがある問題を修正
- Fix: ユーザーポップアップでエラーが生じてもインジケーターが表示され続けてしまう問題を修正

4
locales/index.d.ts vendored
View File

@ -5745,6 +5745,10 @@ export interface Locale extends ILocale {
* : PC
*/
"profileNameDescription2": string;
/**
*
*/
"manageProfiles": string;
};
"_preferencesBackup": {
/**

View File

@ -1439,6 +1439,7 @@ _preferencesProfile:
profileName: "プロファイル名"
profileNameDescription: "このデバイスを識別する名前を設定してください。"
profileNameDescription2: "例: 「メインPC」、「スマホ」など"
manageProfiles: "プロファイルの管理"
_preferencesBackup:
autoBackup: "自動バックアップ"

View File

@ -0,0 +1,47 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<SearchMarker path="/settings/profiles" :label="i18n.ts._preferencesProfile.manageProfiles" :keywords="['profile', 'settings', 'preferences', 'manage']" icon="ti ti-settings-cog">
<div class="_gaps">
<MkFolder v-for="backup in backups">
<template #label>{{ backup.name }}</template>
<MkButton danger @click="del(backup)">{{ i18n.ts.delete }}</MkButton>
</MkFolder>
</div>
</SearchMarker>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import type { MenuItem } from '@/types/menu.js';
import MkButton from '@/components/MkButton.vue';
import MkFolder from '@/components/MkFolder.vue';
import * as os from '@/os.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import { $i } from '@/i.js';
import { i18n } from '@/i18n.js';
import { definePage } from '@/page.js';
import { prefer } from '@/preferences.js';
import { deleteCloudBackup, listCloudBackups } from '@/preferences/utility.js';
const backups = await listCloudBackups();
function del(backup) {
deleteCloudBackup(backup.name);
}
const headerActions = computed(() => []);
const headerTabs = computed(() => []);
definePage(() => ({
title: i18n.ts._preferencesProfile.manageProfiles,
icon: 'ti ti-settings-cog',
}));
</script>
<style lang="scss" module>
</style>

View File

@ -74,12 +74,17 @@ export function getPreferencesProfileMenu(): MenuItem[] {
action: () => {
importProfile();
},
}, {
type: 'divider',
}, {
type: 'link',
text: i18n.ts._preferencesProfile.manageProfiles + '...',
icon: 'ti ti-settings-cog',
to: '/settings/profiles',
}];
if (prefer.s.devMode) {
menu.push({
type: 'divider',
}, {
text: 'Copy profile as text',
icon: 'ti ti-clipboard',
action: () => {
@ -145,17 +150,30 @@ export async function cloudBackup() {
});
}
export async function restoreFromCloudBackup() {
if ($i == null) return;
// TODO: 更新日時でソートして取得したい
export async function listCloudBackups() {
const keys = await misskeyApi('i/registry/keys', {
scope: ['client', 'preferences', 'backups'],
});
if (_DEV_) console.log(keys);
return keys.map(k => ({
name: k,
}));
}
if (keys.length === 0) {
export async function deleteCloudBackup(key: string) {
await os.apiWithDialog('i/registry/remove', {
scope: ['client', 'preferences', 'backups'],
key,
});
}
export async function restoreFromCloudBackup() {
if ($i == null) return;
// TODO: 更新日時でソートしたい
const backups = await listCloudBackups();
if (backups.length === 0) {
os.alert({
type: 'warning',
title: i18n.ts._preferencesBackup.noBackupsFoundTitle,
@ -166,9 +184,9 @@ export async function restoreFromCloudBackup() {
const select = await os.select({
title: i18n.ts._preferencesBackup.selectBackupToRestore,
items: keys.map(k => ({
text: k,
value: k,
items: backups.map(backup => ({
text: backup.name,
value: backup.name,
})),
});
if (select.canceled) return;

View File

@ -180,6 +180,10 @@ export const ROUTE_DEF = [{
path: '/custom-css',
name: 'preferences',
component: page(() => import('@/pages/settings/custom-css.vue')),
}, {
path: '/profiles',
name: 'profiles',
component: page(() => import('@/pages/settings/profiles.vue')),
}, {
path: '/accounts',
name: 'profile',