diff --git a/src/JobsMedical.Web/Program.cs b/src/JobsMedical.Web/Program.cs index df2e616..96ae0d1 100644 --- a/src/JobsMedical.Web/Program.cs +++ b/src/JobsMedical.Web/Program.cs @@ -336,14 +336,27 @@ app.MapPost("/like", async (HttpContext ctx, AppDbContext db, [FromForm] string }).RequireAuthorization().DisableAntiforgery(); app.MapGet("/sw.js", () => Results.Content(""" -const CACHE = 'hamkadr-v1'; -self.addEventListener('install', e => { self.skipWaiting(); e.waitUntil(caches.open(CACHE).then(c => c.addAll(['/']))); }); +const CACHE = 'hamkadr-v2'; +const OFFLINE = '
صفحه باز نشد؛ اتصال خود را بررسی و دوباره تلاش کنید.
'; +self.addEventListener('install', e => { self.skipWaiting(); e.waitUntil(caches.open(CACHE).then(c => c.add('/'))); }); self.addEventListener('activate', e => { e.waitUntil(caches.keys().then(ks => Promise.all(ks.filter(k => k !== CACHE).map(k => caches.delete(k))))); self.clients.claim(); }); self.addEventListener('fetch', e => { const req = e.request; if (req.method !== 'GET' || new URL(req.url).origin !== location.origin) return; - e.respondWith(fetch(req).then(res => { const copy = res.clone(); caches.open(CACHE).then(c => c.put(req, copy)); return res; }) - .catch(() => caches.match(req).then(m => m || caches.match('/')))); + // Page navigations ALWAYS go to the network so listings are fresh (never a stale/archived card). + // We only fall back when the device is truly offline — to a cached copy of THAT exact page, or an + // offline notice. We never substitute the homepage for a detail page (that was the "clicking a job + // just shows the homepage" bug) and we never cache HTML, so a 410 can't poison the cache. + if (req.mode === 'navigate') { + e.respondWith(fetch(req).catch(() => caches.match(req).then(m => + m || new Response(OFFLINE, { headers: { 'Content-Type': 'text/html; charset=utf-8' } })))); + return; + } + // Static assets (css/js/fonts/images) are fingerprinted — cache-first is safe and fast. + e.respondWith(caches.match(req).then(hit => hit || fetch(req).then(res => { + if (res.ok && res.type === 'basic') { const copy = res.clone(); caches.open(CACHE).then(c => c.put(req, copy)); } + return res; + }))); }); self.addEventListener('push', e => { let d = { title: 'همکادر', body: 'فرصت جدید برای شما', url: '/' };