diff options
Diffstat (limited to 'ui/routes/(app)')
| -rw-r--r-- | ui/routes/(app)/+layout.svelte | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/ui/routes/(app)/+layout.svelte b/ui/routes/(app)/+layout.svelte index 1ba3fa9..116767d 100644 --- a/ui/routes/(app)/+layout.svelte +++ b/ui/routes/(app)/+layout.svelte @@ -14,7 +14,7 @@ let gesture = null; const { data, children } = $props(); - const { session } = data; + const { session, outbox } = data; onMount(session.begin.bind(session)); onDestroy(session.end.bind(session)); @@ -89,8 +89,44 @@ async function createChannel(name) { await api.createChannel(name); } + + function onbeforeunload(event) { + if (outbox.pending.length > 0) { + // Prompt the user that they have unsaved (unsent) messages that may be lost. + event.preventDefault(); + } + } </script> +<!-- + In theory, we [should be][bfcache-why] using an ephemeral event handler for this, rather than + leaving it hooked up at all times. Some browsers decide whether a page is eligible for + back/forward caching based on whether it has a beforeunload handler (among other factors), and + having the event handler registered can slow down navigation on those browsers by forcing a + network reload when the page could have been restored from memory. + + Most browsers _apparently_ no longer use that criterion, but I would have been inclined to follow + the advice regardless as I don't feel up to the task of cataloguing which browsers it applies to. + Unfortunately, it wouldn't matter if we did: SvelteKit itself registers beforeunload handlers, so + (at least as of this writing) any work we do to try to dynamically register or unregister + beforeunload handlers dynamically state would be wasted effort. + + For posterity, though, the appropriate code for doing so based on outbox state looks like + + $effect(() => { + if (outbox.pending.length > 0) { + window.addEventListener('beforeunload', onbeforeunload); + } + + return () => { + window.removeEventListener('beforeunload', onbeforeunload); + }; + }); + + [bfcache-why]: https://web.dev/articles/bfcache#beforeunload-caution +--> +<svelte:window {onbeforeunload} /> + <svelte:head> <!-- TODO: unread count? --> <title>pilcrow</title> |
