177 lines
4.8 KiB
Vue
177 lines
4.8 KiB
Vue
<script setup lang="ts">
|
|
import { ref } from 'vue';
|
|
import Button from 'primevue/button';
|
|
import InputText from 'primevue/inputtext';
|
|
import { useConfirm } from 'primevue/useconfirm';
|
|
import * as path from '@tauri-apps/api/path';
|
|
import { invoke } from '../invoke';
|
|
import { useGeneralStore, usePrfStore } from '../stores';
|
|
import { ProfileMeta } from '../types';
|
|
|
|
const general = useGeneralStore();
|
|
const prf = usePrfStore();
|
|
const confirmDialog = useConfirm();
|
|
|
|
const isEditing = ref(false);
|
|
|
|
const props = defineProps({
|
|
p: Object as () => ProfileMeta,
|
|
});
|
|
|
|
if (props.p === undefined) {
|
|
throw new Error('Invalid ProfileListEntry');
|
|
}
|
|
|
|
const renameProfile = async (event: KeyboardEvent) => {
|
|
if (event.key !== 'Enter') {
|
|
return;
|
|
}
|
|
|
|
isEditing.value = false;
|
|
|
|
if (
|
|
event.target !== null &&
|
|
'value' in event.target &&
|
|
typeof event.target.value === 'string'
|
|
) {
|
|
const value = event.target.value
|
|
.trim()
|
|
.replaceAll(' ', '-')
|
|
.replaceAll('..', '')
|
|
.replaceAll('\\', '')
|
|
.replaceAll('/', '');
|
|
|
|
if (value.length > 0) {
|
|
await prf.rename(props.p!, value);
|
|
}
|
|
}
|
|
};
|
|
|
|
const duplicateProfile = async () => {
|
|
await invoke('duplicate_profile', { profile: props.p });
|
|
await prf.reloadList();
|
|
};
|
|
|
|
const deleteProfile = async () => {
|
|
await invoke('delete_profile', { profile: props.p });
|
|
await prf.reloadList();
|
|
await prf.reload();
|
|
};
|
|
|
|
const promptDeleteProfile = async () => {
|
|
confirmDialog.require({
|
|
message: `Are you sure you want to delete ${props.p?.game}-${props.p?.name}?`,
|
|
header: 'Delete profile',
|
|
accept: deleteProfile,
|
|
});
|
|
};
|
|
|
|
const dataExists = ref(false);
|
|
|
|
path.join(general.dataDir, `profile-${props.p!.game}-${props.p!.name}`).then(
|
|
async (p) => {
|
|
dataExists.value = await invoke('file_exists', { path: p });
|
|
}
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex flex-row flex-wrap align-middle gap-2">
|
|
<Button
|
|
:disabled="
|
|
prf.current?.meta.game === p!.game &&
|
|
prf.current?.meta.name === p!.name
|
|
"
|
|
:class="
|
|
(p!.game === 'chunithm' ? 'chunithm-button' : 'ongeki-button') +
|
|
' ' +
|
|
'self-center profile-button'
|
|
"
|
|
@click="prf.switchTo(p!.game, p!.name)"
|
|
>
|
|
<div v-if="!isEditing">{{ p!.name }}</div>
|
|
<div v-else>
|
|
<InputText
|
|
unstyled
|
|
class="text-center"
|
|
:model-value="p!.name"
|
|
@vue:mounted="$event?.el?.focus()"
|
|
@keyup="renameProfile"
|
|
@focusout="isEditing = false"
|
|
>
|
|
</InputText></div
|
|
></Button>
|
|
<Button
|
|
rounded
|
|
icon="pi pi-trash"
|
|
severity="danger"
|
|
aria-label="remove"
|
|
size="small"
|
|
class="self-center ml-2"
|
|
style="width: 2rem; height: 2rem"
|
|
@click="promptDeleteProfile"
|
|
/>
|
|
<Button
|
|
rounded
|
|
icon="pi pi-clone"
|
|
severity="help"
|
|
aria-label="duplicate"
|
|
size="small"
|
|
class="self-center"
|
|
style="width: 2rem; height: 2rem"
|
|
@click="duplicateProfile"
|
|
/>
|
|
<Button
|
|
rounded
|
|
icon="pi pi-pencil"
|
|
severity="help"
|
|
aria-label="rename"
|
|
size="small"
|
|
class="self-center"
|
|
style="width: 2rem; height: 2rem"
|
|
@click="isEditing = true"
|
|
/>
|
|
<Button
|
|
rounded
|
|
icon="pi pi-cog"
|
|
severity="help"
|
|
aria-label="open-config-directory"
|
|
size="small"
|
|
class="self-center"
|
|
style="width: 2rem; height: 2rem"
|
|
@click="
|
|
path
|
|
.join(general.configDir, `profile-${p!.game}-${p!.name}`)
|
|
.then(async (path) => {
|
|
await invoke('open_file', { path });
|
|
})
|
|
"
|
|
/>
|
|
<Button
|
|
v-if="dataExists"
|
|
rounded
|
|
icon="pi pi-folder"
|
|
severity="help"
|
|
aria-label="open-data-directory"
|
|
size="small"
|
|
class="self-center"
|
|
style="width: 2rem; height: 2rem"
|
|
@click="
|
|
path
|
|
.join(general.dataDir, `profile-${p!.game}-${p!.name}`)
|
|
.then(async (path) => {
|
|
await invoke('open_file', { path });
|
|
})
|
|
"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="css">
|
|
.p-tablist-tab-list {
|
|
border: none !important;
|
|
border-color: transparent !important;
|
|
border-radius: 0 !important;
|
|
}
|
|
</style>
|