6e85917f73
Kids math practice (SL/EN) in a Vite React app, wrapped with Capacitor for Android (net.bit76.matematika). Includes session refactor, i18n, and text-free difficulty icons with translated overlays.
75 lines
2.0 KiB
JavaScript
75 lines
2.0 KiB
JavaScript
// Cache the app shell with paths relative to this worker's scope
|
|
// so a subfolder deploy (Vite base: './') keeps working.
|
|
const CACHE_NAME = 'matematika-shell-v3'
|
|
|
|
function scopeUrl(path) {
|
|
return new URL(path, self.registration.scope).href
|
|
}
|
|
|
|
const ASSETS_TO_CACHE = [
|
|
'./',
|
|
'./index.html',
|
|
'./manifest.json',
|
|
'./favicon/site.webmanifest',
|
|
'./favicon/web-app-manifest-192x192.png',
|
|
'./favicon/web-app-manifest-512x512.png',
|
|
'./favicon/apple-touch-icon.png',
|
|
'./favicon/favicon-96x96.png'
|
|
].map(scopeUrl)
|
|
|
|
self.addEventListener('install', event => {
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME).then(cache =>
|
|
cache.addAll(ASSETS_TO_CACHE).catch(err => {
|
|
console.warn('Precache failed (continuing):', err)
|
|
})
|
|
)
|
|
)
|
|
self.skipWaiting()
|
|
})
|
|
|
|
self.addEventListener('activate', event => {
|
|
event.waitUntil(
|
|
caches.keys().then(keys => Promise.all(
|
|
keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k))
|
|
))
|
|
)
|
|
self.clients.claim()
|
|
})
|
|
|
|
self.addEventListener('fetch', event => {
|
|
if (event.request.method !== 'GET') return
|
|
|
|
if (event.request.mode === 'navigate') {
|
|
event.respondWith(
|
|
fetch(event.request).then(resp => {
|
|
if (resp && resp.status === 200) {
|
|
const respClone = resp.clone()
|
|
caches.open(CACHE_NAME).then(cache => cache.put(event.request, respClone))
|
|
}
|
|
return resp
|
|
}).catch(() => caches.match(scopeUrl('./index.html')))
|
|
)
|
|
return
|
|
}
|
|
|
|
event.respondWith(
|
|
caches.match(event.request).then(cached => {
|
|
const networkFetch = fetch(event.request).then(resp => {
|
|
if (resp && resp.status === 200) {
|
|
const respClone = resp.clone()
|
|
caches.open(CACHE_NAME).then(cache => cache.put(event.request, respClone))
|
|
}
|
|
return resp
|
|
}).catch(() => null)
|
|
return cached || networkFetch
|
|
})
|
|
)
|
|
})
|
|
|
|
self.addEventListener('message', event => {
|
|
if (event.data && event.data.type === 'SKIP_WAITING') {
|
|
self.skipWaiting()
|
|
}
|
|
})
|