mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-12-25 09:43:09 +02:00
Merge branch 'develop' into pag-back
This commit is contained in:
commit
848b72ae21
1 changed files with 28 additions and 37 deletions
|
@ -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';
|
||||
|
@ -94,15 +94,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'];
|
||||
|
@ -126,18 +117,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
|
||||
|
@ -148,9 +139,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) {
|
||||
|
@ -182,14 +173,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 }),
|
||||
|
@ -213,7 +204,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];
|
||||
|
@ -234,7 +225,7 @@ function loadFile(): void {
|
|||
return os.alert({
|
||||
type: 'error',
|
||||
title: ts._preferencesBackups.cannotLoad,
|
||||
text: err?.message,
|
||||
text: (err as any)?.message ?? '',
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -253,9 +244,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',
|
||||
|
@ -313,23 +304,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',
|
||||
|
@ -350,25 +341,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;
|
||||
|
@ -378,7 +369,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,
|
||||
|
@ -388,8 +379,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',
|
||||
|
@ -403,16 +394,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;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue