aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/refresh-on-refocus.ts46
-rw-r--r--src/routes/+layout.svelte4
2 files changed, 50 insertions, 0 deletions
diff --git a/src/lib/refresh-on-refocus.ts b/src/lib/refresh-on-refocus.ts
new file mode 100644
index 0000000..fcb042a
--- /dev/null
+++ b/src/lib/refresh-on-refocus.ts
@@ -0,0 +1,46 @@
+import { invalidateAll } from '$app/navigation';
+import { page } from '$app/stores';
+import { get } from 'svelte/store';
+
+// Skip the refocus refresh on login and edit pages (in-progress edits).
+const EXCLUDED_ROUTES: Record<string, true> = {
+ '/login': true,
+ '/grocery/[id]': true,
+ '/projects/[projectId]/routine/[routineId]': true,
+};
+
+const MIN_AWAY_MS = 10_000;
+
+/** Re-run page loads on refocus after MIN_AWAY_MS away; call from onMount. */
+export function refreshOnRefocus(): () => void {
+ let deactivatedAt: number | null = null;
+
+ const deactivate = () => {
+ deactivatedAt ??= Date.now();
+ };
+
+ const activate = () => {
+ if (deactivatedAt === null || document.visibilityState !== 'visible')
+ return;
+ const awayMs = Date.now() - deactivatedAt;
+ deactivatedAt = null;
+ if (awayMs < MIN_AWAY_MS) return;
+ if ((get(page).route.id ?? '') in EXCLUDED_ROUTES) return;
+ invalidateAll();
+ };
+
+ const onVisibilityChange = () => {
+ if (document.visibilityState === 'hidden') deactivate();
+ else activate();
+ };
+
+ document.addEventListener('visibilitychange', onVisibilityChange);
+ window.addEventListener('blur', deactivate);
+ window.addEventListener('focus', activate);
+
+ return () => {
+ document.removeEventListener('visibilitychange', onVisibilityChange);
+ window.removeEventListener('blur', deactivate);
+ window.removeEventListener('focus', activate);
+ };
+}
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index add22ee..2956cd8 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -1,9 +1,13 @@
<script>
import '../app.css';
import { page } from '$app/stores';
+ import { onMount } from 'svelte';
import Nav from '$lib/components/Nav.svelte';
+ import { refreshOnRefocus } from '$lib/refresh-on-refocus';
let { children } = $props();
+
+ onMount(refreshOnRefocus);
</script>
<svelte:head>