diff --git a/frontend/app.js b/frontend/app.js
index 8b67fb8..27ac065 100755
--- a/frontend/app.js
+++ b/frontend/app.js
@@ -2992,17 +2992,34 @@ function showUpdateBanner() {
{ label: 'Later', onClick: closeModal },
{ label: 'Refresh UI', primary: true, onClick: async () => {
closeModal();
- await hardReloadUI();
+ await applyUpdate();
}},
]);
}
+// Tracks the current SW registration so applyUpdate() can reach the
+// waiting worker without re-querying getRegistration().
+let _swReg = null;
+
+// Applies a pending SW update in place (see sw-update.js for the full
+// rationale — this used to call hardReloadUI(), which caused the "Update
+// ready" banner to reappear right after being applied).
+async function applyUpdate() {
+ const reg = _swReg || (('serviceWorker' in navigator) ? await navigator.serviceWorker.getRegistration() : null);
+ await window.SwUpdate.applyUpdate({
+ reg,
+ container: navigator.serviceWorker,
+ reload: () => window.location.reload(),
+ });
+}
+
async function registerServiceWorker() {
if (!WEB || !('serviceWorker' in navigator)) return;
try {
// updateViaCache:'none' prevents the browser from serving a stale
// cached copy of sw.js — the server always returns it fresh (no-store).
const reg = await navigator.serviceWorker.register('/sw.js', { updateViaCache: 'none' });
+ _swReg = reg;
// If a new SW is already waiting (e.g. user refreshed after an update),
// show the dialog right away.
diff --git a/frontend/index.html b/frontend/index.html
index cfae38d..015cf2c 100755
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -307,6 +307,7 @@
+