Drag-dropping page images then clicking a nav link silently discarded the whole form. Add a reusable guardUnsavedChanges helper (SvelteKit beforeNavigate confirm + native beforeunload) and wire it into the manga upload, manga edit, and chapter upload forms. The dirty check returns false while submitting so the post-save redirect isn't prompted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
37 lines
1.4 KiB
TypeScript
37 lines
1.4 KiB
TypeScript
import { beforeNavigate } from '$app/navigation';
|
|
import { onMount } from 'svelte';
|
|
|
|
/**
|
|
* Warn before leaving a page with unsaved form state. Call once from a
|
|
* component's script (during init). `isDirty` is read live on each navigation,
|
|
* so pass a closure over the form's reactive state — and have it return `false`
|
|
* once a save has succeeded (or is in flight) so the post-save redirect doesn't
|
|
* prompt.
|
|
*
|
|
* Covers both in-app navigation (SvelteKit `beforeNavigate`, with a confirm) and
|
|
* full-page unload / tab close / reload (the native `beforeunload` prompt).
|
|
*/
|
|
export function guardUnsavedChanges(isDirty: () => boolean): void {
|
|
beforeNavigate((nav) => {
|
|
// `leave` (tab close / reload) can't show a custom confirm here — the
|
|
// beforeunload handler below covers it. Only guard in-app navigations.
|
|
if (nav.type === 'leave') return;
|
|
if (!isDirty()) return;
|
|
if (!confirm('You have unsaved changes. Leave this page and discard them?')) {
|
|
nav.cancel();
|
|
}
|
|
});
|
|
|
|
onMount(() => {
|
|
const handler = (e: BeforeUnloadEvent) => {
|
|
if (isDirty()) {
|
|
e.preventDefault();
|
|
// Legacy browsers require returnValue to be set.
|
|
e.returnValue = '';
|
|
}
|
|
};
|
|
window.addEventListener('beforeunload', handler);
|
|
return () => window.removeEventListener('beforeunload', handler);
|
|
});
|
|
}
|