Fix /set offline cache: save markers and page assets on first visit
Deploy / deploy (push) Successful in 29s
Deploy / deploy (push) Successful in 29s
The worker isn't controlling the page on the first visit, so warm-up fetches bypassed it and no images were cached. The page now writes markers, its own JS/CSS/fonts and /set/ straight into the cache and only then shows 'Works offline'. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,8 @@ type Showing = { src: string; label: string; detail: string; screen?: MarkerScre
|
||||
|
||||
const KIND_LABEL: Record<Kind, string> = { phone: "Phones", tablet: "Tablets", laptop: "Laptops", monitor: "Monitors" };
|
||||
const MODE_KEY = "ttvfx-set-mode";
|
||||
// Must match CACHE in public/set/sw.js
|
||||
const OFFLINE_CACHE = "ttvfx-set-v1";
|
||||
|
||||
function detectScreen() {
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
@@ -139,18 +141,35 @@ export default function MarkerPicker({ screens, extras }: { screens: MarkerScree
|
||||
if (!showing && document.fullscreenElement) document.exitFullscreen?.().catch(() => {});
|
||||
}, [showing]);
|
||||
|
||||
// Offline: register the service worker, then warm its cache with every marker
|
||||
// Offline: register the service worker, then put every marker plus this page's own
|
||||
// scripts/styles/fonts straight into its cache. Writing from the page (rather than
|
||||
// relying on the worker intercepting fetches) also covers the very first visit,
|
||||
// before the worker controls the page.
|
||||
useEffect(() => {
|
||||
if (process.env.NODE_ENV !== "production" || !("serviceWorker" in navigator)) return;
|
||||
navigator.serviceWorker
|
||||
.register("/set/sw.js", { scope: "/set/" })
|
||||
.then(async () => {
|
||||
if (process.env.NODE_ENV !== "production" || !("serviceWorker" in navigator) || !("caches" in window)) return;
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
try {
|
||||
await navigator.serviceWorker.register("/set/sw.js", { scope: "/set/" });
|
||||
await navigator.serviceWorker.ready;
|
||||
if (cancelled) return;
|
||||
setOffline("saving");
|
||||
const urls = [...screens.flatMap((s) => [s.full, s.edge]), ...extras.map((e) => e.src)].filter(Boolean) as string[];
|
||||
await Promise.all(urls.map((u) => fetch(u).catch(() => null)));
|
||||
setOffline("ready");
|
||||
})
|
||||
.catch(() => {});
|
||||
const markers = [...screens.flatMap((s) => [s.full, s.edge]), ...extras.map((e) => e.src)].filter(Boolean) as string[];
|
||||
const assets = performance
|
||||
.getEntriesByType("resource")
|
||||
.map((e) => new URL(e.name))
|
||||
.filter((u) => u.origin === location.origin && /^\/(_next\/|icon|apple-icon)/.test(u.pathname))
|
||||
.map((u) => u.pathname + u.search);
|
||||
const cache = await caches.open(OFFLINE_CACHE);
|
||||
await cache.addAll(["/set/", ...new Set([...markers, ...assets])]);
|
||||
if (!cancelled) setOffline("ready");
|
||||
} catch {
|
||||
if (!cancelled) setOffline("idle");
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [screens, extras]);
|
||||
|
||||
const showScreen = (s: MarkerScreen) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Offline cache for /set (screen markers). Crews often have no signal on set:
|
||||
// once the page has loaded once, it and every marker image work offline.
|
||||
// Must match OFFLINE_CACHE in components/set/MarkerPicker.tsx
|
||||
const CACHE = "ttvfx-set-v1";
|
||||
|
||||
self.addEventListener("install", (event) => {
|
||||
|
||||
Reference in New Issue
Block a user