Files
ha-dashboard-studio/dashboard_studio/web/sw.js
T
veenm 3d958d0411 Dashboard Studio 2.0.0: Admin, Builder and Dashboard screens, roles, Haven
- Home Assistant administrators are admins: Dashboard, Builder and Admin screens
- Everyone else only sees the dashboards an admin chose, always in kiosk mode;
  the server enforces it (saving, people, devices, history are admin-only, and
  the websocket only allows reading states and controlling devices)
- Admin screen: dashboards, people and what each sees (with preview), devices,
  messages to the screens, the Haven app, activity, about
- Haven: new Android app (haven/) that only shows dashboards; replaces the
  Dashboard Studio Android app and signs in through Home Assistant's page
- Screens pick up dashboard and access changes within a minute
- Version history records who made each change; panel visible to all users

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 23:20:55 +01:00

34 lines
1.6 KiB
JavaScript

/* Dashboard Studio service worker: always the network first, so updates show straight away.
* When the network fails (or Home Assistant's ingress session has run out), it answers with
* the last good copy, so the app can start, show the last known states and reconnect. */
const CACHE = "ds-__VERSION__";
const SKIP = /\/(ws|api\/camera|api\/immich|api\/history)/;
self.addEventListener("install", () => self.skipWaiting());
self.addEventListener("activate", (e) => {
e.waitUntil(caches.keys().then((keys) => Promise.all(keys.filter((k) => k.startsWith("ds-") && k !== CACHE).map((k) => caches.delete(k)))).then(() => self.clients.claim()));
});
self.addEventListener("fetch", (e) => {
const req = e.request, url = new URL(req.url);
if (req.method !== "GET" || url.origin !== location.origin || SKIP.test(url.pathname)) return;
const page = req.mode === "navigate";
e.respondWith((async () => {
const cache = await caches.open(CACHE);
try {
const res = await fetch(req);
if (res.ok) {
cache.put(page ? new Request(new URL("./", self.registration.scope)) : req, res.clone());
return res;
}
if (!page) return res;
// Signed out of Home Assistant: the last good copy renews the session itself. Without one, pass
// the refusal on, so Haven knows to sign in again.
return (await cache.match(new URL("./", self.registration.scope).href)) || res;
} catch (err) {
const hit = page ? await cache.match(new URL("./", self.registration.scope).href) : await cache.match(req);
if (hit) return hit;
throw err;
}
})());
});