diff --git a/packages/frontend/src/pages/settings/preferences-backups.vue b/packages/frontend/src/pages/settings/preferences-backups.vue index 1aa1a5f81c..535a8820d2 100644 --- a/packages/frontend/src/pages/settings/preferences-backups.vue +++ b/packages/frontend/src/pages/settings/preferences-backups.vue @@ -32,7 +32,7 @@ </template> <script lang="ts" setup> -import { computed, onMounted, onUnmounted } from 'vue'; +import { computed, onMounted, onUnmounted, ref } from 'vue'; import { v4 as uuid } from 'uuid'; import FormSection from '@/components/form/section.vue'; import MkButton from '@/components/MkButton.vue'; @@ -93,15 +93,6 @@ const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [ 'darkTheme', 'syncDeviceDarkMode', 'plugins', - 'mediaVolume', - 'sound_masterVolume', - 'sound_note', - 'sound_noteMy', - 'sound_notification', - 'sound_chat', - 'sound_chatBg', - 'sound_antenna', - 'sound_channel', ]; const scope = ['clientPreferencesProfiles']; @@ -125,18 +116,18 @@ type Profile = { const connection = $i && useStream().useChannel('main'); -let profiles = $ref<Record<string, Profile> | null>(null); +const profiles = ref<Record<string, Profile> | null>(null); os.api('i/registry/get-all', { scope }) .then(res => { - profiles = res || {}; + profiles.value = res || {}; }); function isObject(value: unknown): value is Record<string, unknown> { return value != null && typeof value === 'object' && !Array.isArray(value); } -function validate(profile: unknown): void { +function validate(profile: any): void { if (!isObject(profile)) throw new Error('not an object'); // Check if unnecessary properties exist @@ -147,9 +138,9 @@ function validate(profile: unknown): void { // Check if createdAt and updatedAt is Date // https://zenn.dev/lollipop_onl/articles/eoz-judge-js-invalid-date - if (!profile.createdAt || Number.isNaN(new Date(profile.createdAt).getTime())) throw new Error('createdAt is falsy or not Date'); + if (!profile.createdAt || Number.isNaN(new Date(profile.createdAt as any).getTime())) throw new Error('createdAt is falsy or not Date'); if (profile.updatedAt) { - if (Number.isNaN(new Date(profile.updatedAt).getTime())) { + if (Number.isNaN(new Date(profile.updatedAt as any).getTime())) { throw new Error('updatedAt is not Date'); } } else if (profile.updatedAt !== null) { @@ -181,14 +172,14 @@ function getSettings(): Profile['settings'] { } async function saveNew(): Promise<void> { - if (!profiles) return; + if (!profiles.value) return; const { canceled, result: name } = await os.inputText({ title: ts._preferencesBackups.inputName, }); if (canceled) return; - if (Object.values(profiles).some(x => x.name === name)) { + if (Object.values(profiles.value).some(x => x.name === name)) { return os.alert({ title: ts._preferencesBackups.cannotSave, text: t('_preferencesBackups.nameAlreadyExists', { name }), @@ -212,7 +203,7 @@ function loadFile(): void { input.type = 'file'; input.multiple = false; input.onchange = async () => { - if (!profiles) return; + if (!profiles.value) return; if (!input.files || input.files.length === 0) return; const file = input.files[0]; @@ -233,7 +224,7 @@ function loadFile(): void { return os.alert({ type: 'error', title: ts._preferencesBackups.cannotLoad, - text: err?.message, + text: (err as any)?.message ?? '', }); } @@ -252,9 +243,9 @@ function loadFile(): void { } async function applyProfile(id: string): Promise<void> { - if (!profiles) return; + if (!profiles.value) return; - const profile = profiles[id]; + const profile = profiles.value[id]; const { canceled: cancel1 } = await os.confirm({ type: 'warning', @@ -312,23 +303,23 @@ async function applyProfile(id: string): Promise<void> { } async function deleteProfile(id: string): Promise<void> { - if (!profiles) return; + if (!profiles.value) return; const { canceled } = await os.confirm({ type: 'info', title: ts.delete, - text: t('deleteAreYouSure', { x: profiles[id].name }), + text: t('deleteAreYouSure', { x: profiles.value[id].name }), }); if (canceled) return; await os.apiWithDialog('i/registry/remove', { scope, key: id }); - delete profiles[id]; + delete profiles.value[id]; } async function save(id: string): Promise<void> { - if (!profiles) return; + if (!profiles.value) return; - const { name, createdAt } = profiles[id]; + const { name, createdAt } = profiles.value[id]; const { canceled } = await os.confirm({ type: 'info', @@ -349,25 +340,25 @@ async function save(id: string): Promise<void> { } async function rename(id: string): Promise<void> { - if (!profiles) return; + if (!profiles.value) return; const { canceled: cancel1, result: name } = await os.inputText({ title: ts._preferencesBackups.inputName, }); - if (cancel1 || profiles[id].name === name) return; + if (cancel1 || profiles.value[id].name === name) return; - if (Object.values(profiles).some(x => x.name === name)) { + if (Object.values(profiles.value).some(x => x.name === name)) { return os.alert({ title: ts._preferencesBackups.cannotSave, text: t('_preferencesBackups.nameAlreadyExists', { name }), }); } - const registry = Object.assign({}, { ...profiles[id] }); + const registry = Object.assign({}, { ...profiles.value[id] }); const { canceled: cancel2 } = await os.confirm({ type: 'info', - title: ts._preferencesBackups.rename, + title: ts.rename, text: t('_preferencesBackups.renameConfirm', { old: registry.name, new: name }), }); if (cancel2) return; @@ -377,7 +368,7 @@ async function rename(id: string): Promise<void> { } function menu(ev: MouseEvent, profileId: string) { - if (!profiles) return; + if (!profiles.value) return; return os.popupMenu([{ text: ts._preferencesBackups.apply, @@ -387,8 +378,8 @@ function menu(ev: MouseEvent, profileId: string) { type: 'a', text: ts.download, icon: 'ti ti-download', - href: URL.createObjectURL(new Blob([JSON.stringify(profiles[profileId], null, 2)], { type: 'application/json' })), - download: `${profiles[profileId].name}.json`, + href: URL.createObjectURL(new Blob([JSON.stringify(profiles.value[profileId], null, 2)], { type: 'application/json' })), + download: `${profiles.value[profileId].name}.json`, }, null, { text: ts.rename, icon: 'ti ti-forms', @@ -402,16 +393,16 @@ function menu(ev: MouseEvent, profileId: string) { icon: 'ti ti-trash', action: () => deleteProfile(profileId), danger: true, - }], ev.currentTarget ?? ev.target); + }], (ev.currentTarget ?? ev.target ?? undefined) as unknown as HTMLElement | undefined); } onMounted(() => { // streamingのuser storage updateイベントを監視して更新 connection?.on('registryUpdated', ({ scope: recievedScope, key, value }) => { if (!recievedScope || recievedScope.length !== scope.length || recievedScope[0] !== scope[0]) return; - if (!profiles) return; + if (!profiles.value) return; - profiles[key] = value; + profiles.value[key] = value; }); });