Import source: app/public/service-worker

Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
arsam
2026-09-18 23:22:51 +03:30
parent 987782d4b2
commit 5cdffcbd1b
+92
View File
@@ -0,0 +1,92 @@
const CACHE_NAME = 'teknav-v5';
const ASSETS_TO_CACHE = [
'/',
'/index.html',
'/manifest.json',
'/favicon.png'
];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => cache.addAll(ASSETS_TO_CACHE))
.then(() => self.skipWaiting())
);
});
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys()
.then((keys) => Promise.all(keys.filter((key) => key !== CACHE_NAME).map((key) => caches.delete(key))))
.then(() => self.clients.claim())
);
});
self.addEventListener('fetch', (event) => {
const { request } = event;
if (request.method !== 'GET') return;
const url = new URL(request.url);
if (url.origin === location.origin && (url.pathname.startsWith('/article/') || url.pathname === '/' || url.pathname === '/articles')) {
event.respondWith(
fetch(request)
.then((response) => {
const copy = response.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(request, copy));
return response;
})
.catch(() => caches.match(request).then((cached) => cached || caches.match('/index.html')))
);
return;
}
if (url.origin === location.origin && url.pathname.startsWith('/api/articles')) {
event.respondWith(fetch(request));
return;
}
if (request.headers.get('Accept')?.includes('text/html')) {
event.respondWith(
fetch(request)
.then((response) => {
const copy = response.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(request, copy));
return response;
})
.catch(() => caches.match(request).then((cached) => cached || caches.match('/index.html')))
);
return;
}
event.respondWith(caches.match(request).then((response) => response || fetch(request)));
});
self.addEventListener('push', (event) => {
const data = event.data ? event.data.json() : { title: 'تکناو', body: '', url: '/', icon: '/icons/icon-192x192.png' };
event.waitUntil(
self.registration.showNotification(data.title, {
body: data.body,
icon: data.icon || '/icons/icon-192x192.png',
badge: '/icons/badge-72x72.png',
dir: 'rtl',
lang: 'fa',
data: { url: data.url || '/' },
})
);
});
self.addEventListener('notificationclick', (event) => {
event.notification.close();
const targetUrl = (event.notification.data && event.notification.data.url) || '/';
event.waitUntil(
clients.matchAll({ type: 'window', includeUncontrolled: true }).then((list) => {
for (const client of list) {
if ('focus' in client) {
client.navigate(targetUrl);
return client.focus();
}
}
return clients.openWindow(targetUrl);
})
);
});