From a94cd1718681e0083e0ca4f0cf95cf89175e2d3a Mon Sep 17 00:00:00 2001 From: Aaron Date: Sun, 14 Dec 2025 18:48:00 -0500 Subject: [PATCH] Redesign updater UI with manual version picker and status bar --- pikit-web/assets/css/modal.css | 54 ++++++++++++++++ pikit-web/assets/releases.js | 111 ++++++++++++++++++++++++--------- pikit-web/index.html | 22 ++++++- 3 files changed, 154 insertions(+), 33 deletions(-) diff --git a/pikit-web/assets/css/modal.css b/pikit-web/assets/css/modal.css index 271a16e..46afd90 100644 --- a/pikit-web/assets/css/modal.css +++ b/pikit-web/assets/css/modal.css @@ -94,6 +94,60 @@ text-align: right; } +.release-status-bar { + display: flex; + gap: 8px; + flex-wrap: wrap; + align-items: center; + margin-bottom: 6px; +} + +.release-advanced { + border: 1px dashed var(--border); + border-radius: 12px; + padding: 10px; + margin-top: 8px; + background: rgba(255, 255, 255, 0.02); +} + +.release-advanced-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-bottom: 6px; +} + +.release-list { + display: grid; + gap: 8px; +} + +.release-card { + border: 1px solid var(--border); + border-radius: 10px; + padding: 8px 10px; + display: grid; + grid-template-columns: auto 1fr; + gap: 10px; + align-items: center; + cursor: pointer; +} + +.release-card input[type="radio"] { + accent-color: var(--accent); +} + +.release-card-title { + font-weight: 600; +} + +.release-card-tags { + display: flex; + gap: 8px; + align-items: center; +} + .modal-card .status-msg { overflow-wrap: anywhere; margin-top: 6px; diff --git a/pikit-web/assets/releases.js b/pikit-web/assets/releases.js index ec4a9fb..9034c0c 100644 --- a/pikit-web/assets/releases.js +++ b/pikit-web/assets/releases.js @@ -25,9 +25,14 @@ export function initReleaseUI({ showToast, showBusy, hideBusy, confirmAction, lo const releaseProgress = document.getElementById("releaseProgress"); const releaseCheckBtn = document.getElementById("releaseCheckBtn"); const releaseApplyBtn = document.getElementById("releaseApplyBtn"); - const releaseVersionSelect = document.getElementById("releaseVersionSelect"); + const releaseAdvancedToggle = document.getElementById("releaseAdvancedToggle"); + const releaseAdvanced = document.getElementById("releaseAdvanced"); + const releaseList = document.getElementById("releaseList"); const releaseApplyVersionBtn = document.getElementById("releaseApplyVersionBtn"); const releaseAutoCheck = document.getElementById("releaseAutoCheck"); + const releaseStatusChip = document.getElementById("releaseStatusChip"); + const releaseChannelChip = document.getElementById("releaseChannelChip"); + const releaseLastCheckChip = document.getElementById("releaseLastCheckChip"); const releaseLog = document.getElementById("releaseLog"); const releaseLogStatus = document.getElementById("releaseLogStatus"); const releaseLogCopy = document.getElementById("releaseLogCopy"); @@ -68,40 +73,70 @@ export function initReleaseUI({ showToast, showBusy, hideBusy, confirmAction, lo }; async function loadReleaseList() { - if (!releaseVersionSelect) return; + if (!releaseList) return; try { const data = await listReleases(); releaseOptions = data.releases || []; - releaseVersionSelect.innerHTML = ""; - if (!releaseOptions.length) { - const opt = document.createElement("option"); - opt.value = ""; - opt.textContent = "No releases found"; - releaseVersionSelect.appendChild(opt); - releaseVersionSelect.disabled = true; - releaseApplyVersionBtn && (releaseApplyVersionBtn.disabled = true); - return; - } - releaseVersionSelect.disabled = false; - releaseOptions.forEach((r) => { - const opt = document.createElement("option"); - opt.value = r.version; - const tag = r.prerelease ? " (dev)" : ""; - opt.textContent = `${r.version}${tag}${r.published_at ? ` — ${fmtDate(r.published_at)}` : ""}`; - releaseVersionSelect.appendChild(opt); - }); - if (releaseApplyVersionBtn) releaseApplyVersionBtn.disabled = false; + renderReleaseList(); } catch (e) { - releaseVersionSelect.innerHTML = ""; - const opt = document.createElement("option"); - opt.value = ""; - opt.textContent = "Failed to load releases"; - releaseVersionSelect.appendChild(opt); - releaseVersionSelect.disabled = true; - if (releaseApplyVersionBtn) releaseApplyVersionBtn.disabled = true; + renderReleaseList(true); } } + function renderReleaseList(error = false) { + if (!releaseList) return; + releaseList.innerHTML = ""; + if (error) { + releaseList.textContent = "Failed to load releases."; + return; + } + if (!releaseOptions.length) { + releaseList.textContent = "No releases found."; + return; + } + releaseOptions.forEach((r, idx) => { + const card = document.createElement("label"); + card.className = "release-card"; + card.setAttribute("role", "option"); + const input = document.createElement("input"); + input.type = "radio"; + input.name = "releaseVersion"; + input.value = r.version; + if (idx === 0) input.checked = true; + const meta = document.createElement("div"); + meta.className = "release-card-meta"; + const title = document.createElement("div"); + title.className = "release-card-title"; + title.textContent = r.version; + const tags = document.createElement("div"); + tags.className = "release-card-tags"; + const chip = document.createElement("span"); + chip.className = "status-chip ghost"; + chip.textContent = r.prerelease ? "Dev" : "Stable"; + tags.appendChild(chip); + if (r.published_at) { + const date = document.createElement("span"); + date.className = "hint quiet"; + date.textContent = fmtDate(r.published_at); + tags.appendChild(date); + } + meta.appendChild(title); + meta.appendChild(tags); + if (r.changelog_url) { + const link = document.createElement("a"); + link.href = r.changelog_url; + link.target = "_blank"; + link.className = "hint"; + link.textContent = "Changelog"; + meta.appendChild(link); + } + card.appendChild(input); + card.appendChild(meta); + releaseList.appendChild(card); + }); + if (releaseApplyVersionBtn) releaseApplyVersionBtn.disabled = false; + } + function setReleaseChip(state) { if (!releaseFlagTop) return; releaseFlagTop.textContent = "Pi-Kit: n/a"; @@ -193,6 +228,7 @@ export function initReleaseUI({ showToast, showBusy, hideBusy, confirmAction, lo current_release_date = null, latest_release_date = null, changelog_url = null, + last_check = null, } = data || {}; releaseChannel = channel || "dev"; if (releaseChannelToggle) releaseChannelToggle.checked = releaseChannel === "dev"; @@ -214,6 +250,13 @@ export function initReleaseUI({ showToast, showBusy, hideBusy, confirmAction, lo if (releaseLatest) releaseLatest.textContent = latest_version; if (releaseCurrentDate) releaseCurrentDate.textContent = fmtDate(current_release_date); if (releaseLatestDate) releaseLatestDate.textContent = fmtDate(latest_release_date); + if (releaseStatusChip) { + releaseStatusChip.textContent = `Status: ${status.replaceAll("_", " ")}`; + releaseStatusChip.classList.toggle("chip-warm", status === "update_available"); + releaseStatusChip.classList.toggle("chip-off", status === "error"); + } + if (releaseChannelChip) releaseChannelChip.textContent = `Channel: ${releaseChannel}`; + if (releaseLastCheckChip) releaseLastCheckChip.textContent = `Last check: ${last_check ? fmtDate(last_check) : "—"}`; if (releaseAutoCheck) releaseAutoCheck.checked = !!auto_check; if (releaseProgress) releaseProgress.textContent = ""; if (status === "in_progress" && progress) { @@ -338,14 +381,22 @@ export function initReleaseUI({ showToast, showBusy, hideBusy, confirmAction, lo } }); + releaseAdvancedToggle?.addEventListener("click", async () => { + releaseAdvanced?.classList.toggle("hidden"); + if (!releaseAdvanced?.classList.contains("hidden")) { + await loadReleaseList(); + } + }); + releaseApplyVersionBtn?.addEventListener("click", async () => { - if (!releaseVersionSelect || !releaseVersionSelect.value) { + const selected = releaseList?.querySelector("input[name='releaseVersion']:checked"); + if (!selected) { showToast("Select a version first", "error"); return; } try { lastReleaseToastKey = null; - const ver = releaseVersionSelect.value; + const ver = selected.value; logUi(`Install version ${ver} requested`); releaseBusyActive = true; showBusy(`Installing ${ver}…`, "Applying selected release. This can take up to a minute."); diff --git a/pikit-web/index.html b/pikit-web/index.html index 053dd7b..eb1c08d 100644 --- a/pikit-web/index.html +++ b/pikit-web/index.html @@ -144,6 +144,11 @@
+
+ Status: n/a + Channel: n/a + Last check: — +

Current version

@@ -165,9 +170,8 @@ - -
+