aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/refresh-on-refocus.ts46
1 files changed, 46 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);
+ };
+}