feat: publish CodexPi contest snapshot
Some checks are pending
Qualité / tests (push) Waiting to run
Some checks are pending
Qualité / tests (push) Waiting to run
This commit is contained in:
58
frontend/public/sw.js
Normal file
58
frontend/public/sw.js
Normal file
@@ -0,0 +1,58 @@
|
||||
const CACHE = 'codexpi-shell-v18'
|
||||
const SHELL = ['/', '/manifest.webmanifest', '/icons/icon-192.png', '/icons/icon-512.png', '/icons/apple-touch-icon.png']
|
||||
|
||||
self.addEventListener('install', event => {
|
||||
event.waitUntil(caches.open(CACHE).then(cache => cache.addAll(SHELL)).then(() => self.skipWaiting()))
|
||||
})
|
||||
|
||||
self.addEventListener('activate', event => {
|
||||
event.waitUntil(caches.keys().then(keys => Promise.all(keys.filter(key => key !== CACHE).map(key => caches.delete(key)))).then(() => self.clients.claim()))
|
||||
})
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
const request = event.request
|
||||
const url = new URL(request.url)
|
||||
if (request.method !== 'GET' || url.origin !== location.origin || url.pathname.startsWith('/api/') || url.pathname.startsWith('/ws/')) return
|
||||
if (url.pathname === '/version.json' || url.pathname === '/sw.js') {
|
||||
event.respondWith(fetch(request, {cache: 'no-store'}))
|
||||
return
|
||||
}
|
||||
if (request.mode === 'navigate') {
|
||||
event.respondWith(fetch(request).then(response => {
|
||||
const copy = response.clone()
|
||||
caches.open(CACHE).then(cache => cache.put('/', copy))
|
||||
return response
|
||||
}).catch(() => caches.match('/')))
|
||||
return
|
||||
}
|
||||
event.respondWith(caches.match(request).then(cached => cached || fetch(request).then(response => {
|
||||
if (response.ok) caches.open(CACHE).then(cache => cache.put(request, response.clone()))
|
||||
return response
|
||||
})))
|
||||
})
|
||||
|
||||
self.addEventListener('push', event => {
|
||||
let message = {}
|
||||
try { message = event.data ? event.data.json() : {} } catch {}
|
||||
event.waitUntil(self.registration.showNotification(message.title || 'Tâche CodexPi terminée', {
|
||||
body: message.body || 'Ouvrez CodexPi pour consulter le résultat.',
|
||||
icon: '/icons/icon-192.png', badge: '/icons/icon-192.png',
|
||||
tag: message.tag || 'codexpi-task', data: {url: message.url || '/'},
|
||||
}))
|
||||
})
|
||||
|
||||
self.addEventListener('notificationclick', event => {
|
||||
event.notification.close()
|
||||
event.waitUntil((async () => {
|
||||
const target = new URL(event.notification.data?.url || '/', self.location.origin)
|
||||
if (target.origin !== self.location.origin) return
|
||||
const windows = await self.clients.matchAll({type: 'window', includeUncontrolled: true})
|
||||
for (const client of windows) {
|
||||
if (new URL(client.url).origin === target.origin && 'navigate' in client) {
|
||||
const navigated = await client.navigate(target.href)
|
||||
if (navigated) { await navigated.focus(); return }
|
||||
}
|
||||
}
|
||||
await self.clients.openWindow(target.href)
|
||||
})())
|
||||
})
|
||||
Reference in New Issue
Block a user