feat: profile imports/exports

This commit is contained in:
2025-04-21 04:15:52 -12:00
parent 890d26e883
commit 407b34a884
8 changed files with 274 additions and 21 deletions

View File

@ -1,29 +1,154 @@
<script setup lang="ts">
import { Ref, ref } from 'vue';
import Button from 'primevue/button';
import Dialog from 'primevue/dialog';
import ToggleSwitch from 'primevue/toggleswitch';
import * as path from '@tauri-apps/api/path';
import { open } from '@tauri-apps/plugin-dialog';
import ProfileListEntry from './ProfileListEntry.vue';
import { usePrfStore } from '../stores';
import { invoke } from '../invoke';
import { useClientStore, useGeneralStore, usePrfStore } from '../stores';
const prf = usePrfStore();
const client = useClientStore();
const general = useGeneralStore();
const exportVisible = ref(false);
const exportKeychip = ref(false);
const files = new Set<string>();
const exportTemplate = async () => {
const fl = [...files.values()];
exportVisible.value = false;
await invoke('export_profile', {
exportKeychip: exportKeychip.value,
files: fl,
});
await invoke('open_file', {
path: await path.join(general.configDir, 'exports'),
});
};
const fileList = {
ongeki: ['aime.txt', 'inohara.cfg', 'mu3.ini', 'segatools-base.ini'],
chunithm: ['aime.txt', 'saekawa.toml', 'segatools-base.ini'],
};
const fileListCurrent: Ref<string[]> = ref([]);
const recalcFileList = async () => {
const res: string[] = [];
files.clear();
for (const idx in fileList[prf.current!.meta.game]) {
const f = fileList[prf.current!.meta.game][idx];
const p = await path.join(await prf.configDir, f);
if (await invoke('file_exists', { path: p })) {
res.push(f);
files.add(f);
}
}
fileListCurrent.value = res;
};
const openExportDialog = async () => {
await recalcFileList();
exportVisible.value = true;
};
const importPick = async () => {
const res = await open({
multiple: false,
directory: false,
filters: [
{
name: 'STARTLINER template',
extensions: ['zip'],
},
],
});
if (res != null) {
await invoke('import_profile', { path: res });
await prf.reloadList();
}
};
</script>
<template>
<Dialog
modal
:visible="exportVisible"
:closable="false /*this shit doesn't work */"
:header="`Export ${prf.current?.meta.name}`"
:style="{ width: '300px', scale: client.scaleValue }"
>
<div class="flex flex-col gap-4">
<div class="flex flex-row">
<div class="grow">Export keychip</div>
<ToggleSwitch v-model="exportKeychip" />
</div>
<div class="flex flex-row" v-for="f in fileListCurrent">
<div class="grow">Export {{ f }}</div>
<ToggleSwitch
:model-value="true"
@update:model-value="
(v) => {
if (v === true) {
files.add(f);
} else {
files.delete(f);
}
}
"
/>
</div>
<div style="width: 100%; text-align: center">
<Button
class="m-auto mr-3"
style="width: 80px"
label="OK"
@click="() => exportTemplate()"
/>
<Button
class="m-auto"
style="width: 80px"
label="Cancel"
@click="() => (exportVisible = false)"
/>
</div>
</div>
</Dialog>
<div v-if="prf.list.length === 0">
Welcome to STARTLINER! Start by creating a profile.
</div>
<div class="mt-4 flex flex-row flex-wrap align-middle gap-4">
<Button
label="O.N.G.E.K.I. profile"
icon="pi pi-plus"
icon="pi pi-file-plus"
class="ongeki-button profile-button"
@click="() => prf.create('ongeki')"
/>
<Button
label="CHUNITHM profile"
icon="pi pi-plus"
icon="pi pi-file-plus"
class="chunithm-button profile-button"
@click="() => prf.create('chunithm')"
/>
</div>
<div class="mt-4 flex flex-row flex-wrap align-middle gap-4">
<Button
label="Import template"
icon="pi pi-file-import"
class="import-button profile-button"
@click="() => importPick()"
/>
<Button
:disabled="prf.current === null"
label="Export template"
icon="pi pi-file-export"
class="profile-button"
@click="() => openExportDialog()"
/>
</div>
<div class="mt-12 flex flex-col flex-wrap align-middle gap-4">
<div v-for="p in prf.list">
<ProfileListEntry :p="p" />
@ -57,4 +182,14 @@ const prf = usePrfStore();
background-color: var(--p-yellow-300) !important;
border-color: var(--p-yellow-300) !important;
}
.import-button {
background-color: var(--p-purple-400) !important;
border-color: var(--p-purple-400) !important;
}
.import-button:hover,
.import-button:active {
background-color: var(--p-purple-300) !important;
border-color: var(--p-purple-300) !important;
}
</style>