diff --git a/AppImage/ProxMenux-1.2.3.AppImage b/AppImage/ProxMenux-1.2.3.AppImage index 017ad34e..c28d79a8 100755 Binary files a/AppImage/ProxMenux-1.2.3.AppImage and b/AppImage/ProxMenux-1.2.3.AppImage differ diff --git a/AppImage/ProxMenux-Monitor.AppImage.sha256 b/AppImage/ProxMenux-Monitor.AppImage.sha256 index 5545fbf5..a5524aa8 100644 --- a/AppImage/ProxMenux-Monitor.AppImage.sha256 +++ b/AppImage/ProxMenux-Monitor.AppImage.sha256 @@ -1 +1 @@ -740deb4de0a91d7ebbc8d7296c5f13500d6892480b207536c22ad2afc2de009c ProxMenux-1.2.3.AppImage +cd07523bc6d5127029d352fcd9488bb90b37c42809d5061cb22aa8a442f036bb ProxMenux-1.2.3.AppImage diff --git a/AppImage/components/pwa-register.tsx b/AppImage/components/pwa-register.tsx index 94196a59..4af78246 100644 --- a/AppImage/components/pwa-register.tsx +++ b/AppImage/components/pwa-register.tsx @@ -12,27 +12,63 @@ import { useEffect } from "react" // PWA-installability check from no-to-yes. // // Mounted from app/layout.tsx so it runs on every route. +// +// On every `visibilitychange` back to visible we call +// `registration.update()`. Mobile browsers (Brave / Firefox +// Android/iOS) are aggressive about deferring the SW's +// scheduled 24h `sw.js` re-check to save battery, which +// stranded users on the pre-v2 SW after the Cache Storage +// fix shipped — they saw the dashboard freeze until they +// force-stopped the browser. Forcing an `update()` on every +// return-to-foreground brings the SW check inline with +// user attention so future SW_VERSION bumps propagate at +// the first regreso a la pestaña instead of hours later. // =========================================================== export function PwaRegister() { useEffect(() => { if (typeof window === "undefined") return if (!("serviceWorker" in navigator)) return - // Wait for the load event to avoid competing with the - // initial render — the SW registration is not on the - // critical render path. + + let registration: ServiceWorkerRegistration | null = null + const register = () => { navigator.serviceWorker .register("/sw.js", { scope: "/" }) + .then((reg) => { + registration = reg + }) .catch((err) => { // Surface the failure only in DevTools — silent in prod. console.warn("[pwa] service worker registration failed:", err) }) } + + const onVisible = () => { + if (document.visibilityState !== "visible") return + // Prefer the captured registration from the initial register() + // call; fall back to `getRegistration()` in case that promise + // hadn't resolved yet on the first visibility change. + if (registration) { + registration.update().catch(() => {}) + } else { + navigator.serviceWorker + .getRegistration() + .then((reg) => reg?.update().catch(() => {})) + .catch(() => {}) + } + } + if (document.readyState === "complete") { register() } else { window.addEventListener("load", register, { once: true }) - return () => window.removeEventListener("load", register) + } + + document.addEventListener("visibilitychange", onVisible) + + return () => { + window.removeEventListener("load", register) + document.removeEventListener("visibilitychange", onVisible) } }, []) return null