mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-19 17:22:12 +00:00
progress
This commit is contained in:
1 parent
005cc7b305
commit
b0a3c3a9ba
18 files changed
+1721
-714
No files matched your search
@@ -0,0 +1,69 @@
|
||||
<script lang="ts">
|
||||
import * as AlertDialog from '$lib/components/ui/alert-dialog';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { i18n } from '$lib/i18n/i18n.svelte';
|
||||
import { unsavedPrompt } from './unsaved-prompt.svelte';
|
||||
|
||||
let prompt = $derived(unsavedPrompt.current);
|
||||
|
||||
/** Closes the dialog, and gives the answer to whoever asked. */
|
||||
function answer(choice: 'save' | 'discard' | 'reload' | 'cancel') {
|
||||
const current = unsavedPrompt.current;
|
||||
unsavedPrompt.current = undefined;
|
||||
if (current?.kind === 'unsaved' && choice !== 'reload') {
|
||||
current.resolve(choice);
|
||||
} else if (current?.kind === 'overwrite') {
|
||||
current.resolve(
|
||||
choice === 'save' ? 'overwrite' : choice === 'reload' ? 'reload' : 'cancel'
|
||||
);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<AlertDialog.Root
|
||||
open={prompt !== undefined}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) {
|
||||
answer('cancel');
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AlertDialog.Content>
|
||||
{#if prompt}
|
||||
<AlertDialog.Header>
|
||||
<AlertDialog.Title>
|
||||
{prompt.kind === 'unsaved'
|
||||
? i18n._('menu.unsaved_title')
|
||||
: i18n._('menu.overwrite_title')}
|
||||
</AlertDialog.Title>
|
||||
<AlertDialog.Description>
|
||||
{prompt.kind === 'unsaved'
|
||||
? i18n._('menu.unsaved_description')
|
||||
: i18n._('menu.overwrite_description')}
|
||||
</AlertDialog.Description>
|
||||
</AlertDialog.Header>
|
||||
<ul class="list-disc pl-6 text-sm max-h-40 overflow-y-auto">
|
||||
{#each prompt.names as name}
|
||||
<li>{name}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<AlertDialog.Footer>
|
||||
<Button variant="outline" onclick={() => answer('cancel')}>
|
||||
{i18n._('menu.cancel')}
|
||||
</Button>
|
||||
{#if prompt.kind === 'unsaved'}
|
||||
<Button variant="destructive" onclick={() => answer('discard')}>
|
||||
{i18n._('menu.discard')}
|
||||
</Button>
|
||||
{:else}
|
||||
<Button variant="destructive" onclick={() => answer('reload')}>
|
||||
{i18n._('menu.reload')}
|
||||
</Button>
|
||||
{/if}
|
||||
<Button onclick={() => answer('save')}>
|
||||
{prompt.kind === 'unsaved' ? i18n._('menu.save') : i18n._('menu.overwrite')}
|
||||
</Button>
|
||||
</AlertDialog.Footer>
|
||||
{/if}
|
||||
</AlertDialog.Content>
|
||||
</AlertDialog.Root>
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { UnsavedChoice } from '$lib/engine';
|
||||
|
||||
type Prompt =
|
||||
| { kind: 'unsaved'; names: string[]; resolve: (choice: UnsavedChoice | 'cancel') => void }
|
||||
| {
|
||||
kind: 'overwrite';
|
||||
names: string[];
|
||||
resolve: (choice: 'overwrite' | 'reload' | 'cancel') => void;
|
||||
};
|
||||
|
||||
/** The question that the user is asked, shown by `UnsavedDialog`. */
|
||||
export const unsavedPrompt: { current: Prompt | undefined } = $state({ current: undefined });
|
||||
|
||||
/**
|
||||
* Asks what to do with files that have unsaved changes when they are closed: save them, discard
|
||||
* the changes, or `'cancel'` to keep going as before.
|
||||
*/
|
||||
export function askUnsaved(names: string[]): Promise<UnsavedChoice | 'cancel'> {
|
||||
return new Promise((resolve) => {
|
||||
unsavedPrompt.current = { kind: 'unsaved', names, resolve };
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks what to do with files that have changes and were also changed on the disk: `'overwrite'` the
|
||||
* disk, `'reload'` the disk (the changes are lost), or `'cancel'`.
|
||||
*/
|
||||
export function askOverwrite(names: string[]): Promise<'overwrite' | 'reload' | 'cancel'> {
|
||||
return new Promise((resolve) => {
|
||||
unsavedPrompt.current = { kind: 'overwrite', names, resolve };
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user