From e5e1482b1f5aea4a50de44801c81c81750042201 Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Fri, 25 Sep 2026 09:10:31 +0200 Subject: Refresh page data on refocus after 10s away, skip edit pages --- src/lib/refresh-on-refocus.ts | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/lib/refresh-on-refocus.ts (limited to 'src/lib/refresh-on-refocus.ts') 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 = { + '/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); + }; +} -- cgit v1.3