diff --git a/console/index.html b/console/index.html index 9edeacc..88fc820 100644 --- a/console/index.html +++ b/console/index.html @@ -28,6 +28,7 @@ +
diff --git a/console/src/main.ts b/console/src/main.ts index 2958162..f5b8c9a 100644 --- a/console/src/main.ts +++ b/console/src/main.ts @@ -596,13 +596,22 @@ interface UpdateInfo { } function setupUpdater(): void { const el = document.getElementById("update-btn") as HTMLButtonElement | null; + const dismissEl = document.getElementById("update-dismiss") as HTMLButtonElement | null; const invoke = tauriInvoke(); if (!el || !invoke) return; // browser build — no updater el.hidden = false; let pending: UpdateInfo | null = null; + // Finding an update must not force installing it (you may want to keep working + // or wait for a later nightly). The install button + this dismiss share the + // pending state; dismiss clears it back to "Check for updates". + const setPending = (info: UpdateInfo | null): void => { + pending = info; + if (dismissEl) dismissEl.hidden = info === null; + }; + const reset = (): void => { - pending = null; + setPending(null); el.textContent = "Check for updates"; el.classList.remove("has-update"); }; @@ -613,10 +622,10 @@ function setupUpdater(): void { try { const info = await inv("check_update"); if (info) { - pending = info; + setPending(info); btn.textContent = `Update to v${info.version} ↻`; btn.classList.add("has-update"); - note("info", `update: v${info.version} available (current v${info.current}) — click to install`); + note("info", `update: v${info.version} available (current v${info.current}) — click to install, or Later to keep this build`); } else { note("info", "update: already up to date"); btn.textContent = "Up to date"; @@ -633,17 +642,24 @@ function setupUpdater(): void { async function install(btn: HTMLButtonElement, inv: Invoke): Promise { btn.disabled = true; btn.textContent = "Installing…"; + if (dismissEl) dismissEl.hidden = true; try { // On success the backend restarts the app, so this may never resolve. await inv("install_update"); } catch (e) { btn.disabled = false; btn.textContent = pending ? `Update to v${pending.version} ↻` : "Check for updates"; + if (dismissEl) dismissEl.hidden = pending === null; note("error", `update: install failed — ${errText(e)}`); } } el.addEventListener("click", () => void (pending ? install(el, invoke) : check(el, invoke))); + dismissEl?.addEventListener("click", () => { + const skipped = pending?.version; + reset(); + if (skipped) note("info", `update: skipped v${skipped} — staying on the current build`); + }); } // Live remote-connection status: the backend pushes `remote-status` events as the diff --git a/console/src/styles.css b/console/src/styles.css index 8042e10..47e017a 100644 --- a/console/src/styles.css +++ b/console/src/styles.css @@ -133,6 +133,22 @@ body { background: var(--s-starting); border-color: var(--s-starting); } +/* Skip an available update and keep the current build (shown only while an + update is pending) — so finding a nightly doesn't force installing it. */ +.update-dismiss { + appearance: none; + border: 0; + background: transparent; + color: var(--muted); + font: inherit; + font-size: 12px; + padding: 3px 6px; + cursor: pointer; + text-decoration: underline; +} +.update-dismiss:hover { + color: var(--text); +} /* Appearance toggle — cycles System / Light / Dark. Mirrors the update button; fixed min-width so the label swap doesn't shift the toolbar. */