Skip to content

Commit f012a30

Browse files
committed
fix: share loader not showing — SW cache bust + precise hash detection
- Bump SW cache to textagent-v2/cdn-v2 (forces all users to get new index.html) - Switch HTML navigation to network-first strategy (prevents SW from serving stale index.html) - Fix hash detection: use URLSearchParams instead of indexOf (prevents false positives) - Add overflow:hidden on html element during share load to prevent scroll flash - Restore overflow in hideShareLoader() and safety timeout path
1 parent 971de55 commit f012a30

4 files changed

Lines changed: 45 additions & 15 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Share Link Loader Fix v2 — Debug & Service Worker Cache
2+
3+
- Fixed: hash detection now uses URLSearchParams instead of indexOf (prevents false positives)
4+
- Fixed: Service Worker was caching old index.html (cache-first) — bumped to textagent-v2/cdn-v2
5+
- Fixed: HTML navigation now uses network-first strategy so new deployments take effect immediately
6+
- Added: document.documentElement.style.overflow = 'hidden' during share load to prevent any scroll flash
7+
- Fixed: hideShareLoader() now also restores document overflow when dismissing

index.html

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,17 @@
158158
<script>
159159
(function () {
160160
var h = window.location.hash;
161-
if (h && (h.indexOf('s=') !== -1 || h.indexOf('id=') !== -1 || h.indexOf('d=') !== -1 || h.indexOf('space=') !== -1)) {
162-
// Will be activated once the overlay element exists (see body)
163-
window.__showShareLoader = true;
161+
if (h && h.length > 1) {
162+
// Use URLSearchParams for precise matching — avoid false positives
163+
try {
164+
var params = new URLSearchParams(h.substring(1));
165+
var hasShare = params.has('s') || params.has('id') || params.has('d') || params.has('space');
166+
if (hasShare) {
167+
window.__showShareLoader = true;
168+
// Hide body early to eliminate flash — overlay will unhide it
169+
document.documentElement.style.overflow = 'hidden';
170+
}
171+
} catch (e) { /* ignore parse errors */ }
164172
}
165173
})();
166174
</script>
@@ -223,7 +231,10 @@
223231
setTimeout(function () {
224232
if (_sloEl.classList.contains('slo-active')) {
225233
_sloEl.classList.add('slo-fade-out');
226-
setTimeout(function () { _sloEl.classList.remove('slo-active', 'slo-fade-out'); }, 400);
234+
setTimeout(function () {
235+
_sloEl.classList.remove('slo-active', 'slo-fade-out');
236+
document.documentElement.style.overflow = '';
237+
}, 400);
227238
}
228239
}, 15000);
229240
}

js/cloud-share.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
var overlay = document.getElementById('share-loading-overlay');
1919
if (!overlay || !overlay.classList.contains('slo-active')) return;
2020
overlay.classList.add('slo-fade-out');
21+
document.documentElement.style.overflow = '';
2122
setTimeout(function () {
2223
overlay.classList.remove('slo-active', 'slo-fade-out');
2324
}, 380);

sw.js

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// Strategy: Cache app shell for offline use, network-first for everything else.
55
// CDN libraries are cached on first fetch for full offline capability.
66

7-
const CACHE_NAME = 'textagent-v1';
7+
const CACHE_NAME = 'textagent-v2';
88

99
// Core app shell files to precache on install
1010
const APP_SHELL = [
@@ -17,7 +17,7 @@ const APP_SHELL = [
1717
];
1818

1919
// CDN libraries to cache on first fetch (runtime caching)
20-
const CDN_CACHE_NAME = 'textagent-cdn-v1';
20+
const CDN_CACHE_NAME = 'textagent-cdn-v2';
2121
const CDN_HOSTS = [
2222
'cdnjs.cloudflare.com',
2323
'cdn.jsdelivr.net',
@@ -97,29 +97,40 @@ self.addEventListener('fetch', (event) => {
9797
return;
9898
}
9999

100-
// App shell (same-origin): cache-first, network as fallback
100+
// App shell (same-origin): network-first for HTML nav (to always get fresh index.html),
101+
// cache-first for JS/CSS/images (stable assets).
101102
if (url.origin === self.location.origin) {
103+
// Always network-first for HTML navigation so new deployments take effect immediately
104+
if (event.request.mode === 'navigate' || url.pathname.endsWith('.html') || url.pathname === '/') {
105+
event.respondWith(
106+
fetch(event.request)
107+
.then((response) => {
108+
if (response.ok) {
109+
const clone = response.clone();
110+
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone));
111+
}
112+
return response;
113+
})
114+
.catch(() => caches.match(event.request).then((cached) => cached || caches.match('/')))
115+
);
116+
return;
117+
}
118+
119+
// Cache-first for JS/CSS/images (stable versioned assets)
102120
event.respondWith(
103121
caches.match(event.request)
104122
.then((cached) => {
105123
if (cached) return cached;
106124

107125
return fetch(event.request).then((response) => {
108-
// Cache JS, CSS, HTML, and image files from our origin
109126
if (response.ok && shouldCacheResponse(url)) {
110127
const clone = response.clone();
111128
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone));
112129
}
113130
return response;
114131
});
115132
})
116-
.catch(() => {
117-
// Offline fallback for navigation requests
118-
if (event.request.mode === 'navigate') {
119-
return caches.match('/');
120-
}
121-
return new Response('Offline', { status: 503, statusText: 'Offline' });
122-
})
133+
.catch(() => new Response('Offline', { status: 503, statusText: 'Offline' }))
123134
);
124135
return;
125136
}

0 commit comments

Comments
 (0)