|
|
|
@ -8,7 +8,7 @@
|
|
|
|
* Objetivo: modo resgate offline — frases + áudio já baixados funcionam no avião.
|
|
|
|
* Objetivo: modo resgate offline — frases + áudio já baixados funcionam no avião.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
const CACHE_NAME = "italiano-vivo-v1";
|
|
|
|
const CACHE_NAME = "italiano-vivo-v2";
|
|
|
|
const SHELL_ASSETS = ["/", "/index.html"];
|
|
|
|
const SHELL_ASSETS = ["/", "/index.html"];
|
|
|
|
|
|
|
|
|
|
|
|
// ─── Install: pré-cache do shell ───
|
|
|
|
// ─── Install: pré-cache do shell ───
|
|
|
|
@ -54,10 +54,28 @@ self.addEventListener("fetch", (event) => {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Cache-first: tenta cache, se não achar vai na rede (sem salvar no cache).
|
|
|
|
* Network-first para o shell (HTML): sempre busca a versao mais nova e
|
|
|
|
* Usado para shell/assets que são pré-cachados no install.
|
|
|
|
* atualiza o cache em background. Evita o app ficar preso numa build antiga
|
|
|
|
|
|
|
|
* apos deploy. Assets versionados (/assets/*-hash) podem ser cache-first
|
|
|
|
|
|
|
|
* porque o nome muda a cada build.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
async function cacheFirst(request) {
|
|
|
|
async function cacheFirst(request) {
|
|
|
|
|
|
|
|
const url = new URL(request.url);
|
|
|
|
|
|
|
|
const isShellHtml = url.pathname === "/" || url.pathname === "/index.html" || url.pathname === "/sw.js";
|
|
|
|
|
|
|
|
if (isShellHtml) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const fresh = await fetch(request);
|
|
|
|
|
|
|
|
if (fresh.ok) {
|
|
|
|
|
|
|
|
const cache = await caches.open(CACHE_NAME);
|
|
|
|
|
|
|
|
cache.put(request, fresh.clone());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return fresh;
|
|
|
|
|
|
|
|
} catch (_err) {
|
|
|
|
|
|
|
|
const cached = await caches.match(request);
|
|
|
|
|
|
|
|
if (cached) return cached;
|
|
|
|
|
|
|
|
throw _err;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
const cached = await caches.match(request);
|
|
|
|
const cached = await caches.match(request);
|
|
|
|
if (cached) return cached;
|
|
|
|
if (cached) return cached;
|
|
|
|
return fetch(request);
|
|
|
|
return fetch(request);
|
|
|
|
@ -69,6 +87,28 @@ async function cacheFirst(request) {
|
|
|
|
* Usado para /content/* e /audio/* que são baixados sob demanda.
|
|
|
|
* Usado para /content/* e /audio/* que são baixados sob demanda.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
async function cacheFirstWithRuntimeCache(request) {
|
|
|
|
async function cacheFirstWithRuntimeCache(request) {
|
|
|
|
|
|
|
|
// Network-first para /content/* (JSON de missoes pode ser corrigido a qualquer
|
|
|
|
|
|
|
|
// momento; cache antigo nao deve esconder o novo). Audio e imutavel -> cache-first.
|
|
|
|
|
|
|
|
const url = new URL(request.url);
|
|
|
|
|
|
|
|
if (url.pathname.startsWith("/content/")) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const response = await fetch(request);
|
|
|
|
|
|
|
|
if (response.ok) {
|
|
|
|
|
|
|
|
const cache = await caches.open(CACHE_NAME);
|
|
|
|
|
|
|
|
cache.put(request, response.clone());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return response;
|
|
|
|
|
|
|
|
} catch (_err) {
|
|
|
|
|
|
|
|
const cached = await caches.match(request);
|
|
|
|
|
|
|
|
if (cached) return cached;
|
|
|
|
|
|
|
|
return new Response("Offline — Italiano Vivo", {
|
|
|
|
|
|
|
|
status: 503,
|
|
|
|
|
|
|
|
statusText: "Service Unavailable",
|
|
|
|
|
|
|
|
headers: { "Content-Type": "text/plain" },
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const cached = await caches.match(request);
|
|
|
|
const cached = await caches.match(request);
|
|
|
|
if (cached) return cached;
|
|
|
|
if (cached) return cached;
|
|
|
|
|
|
|
|
|
|
|
|
|