From 419105c9062693fbba98650326bdbc4fb92a90aa Mon Sep 17 00:00:00 2001 From: librelad Date: Wed, 19 Aug 2026 21:02:46 +0100 Subject: [PATCH] fix(webui): spell out the auto-update window as am/pm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "06:00-08:00" is unambiguous on paper and ambiguous at a glance — the strip said updates install "during 06:00–08:00" and left the reader working out whether that meant morning or night. The window now renders as 6am–8am. The config stays 24-hour so there is still one canonical way to type it; only the display spells it out, and anything that is not a plain HH:MM-HH:MM passes through untouched. Co-Authored-By: Claude Opus 5 --- .../apps/overview/js/overview-manager.js | 3 ++- .../components/updater/js/updater-page.js | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/containers/libreportal/frontend/components/apps/overview/js/overview-manager.js b/containers/libreportal/frontend/components/apps/overview/js/overview-manager.js index c2e0c41..be6a851 100644 --- a/containers/libreportal/frontend/components/apps/overview/js/overview-manager.js +++ b/containers/libreportal/frontend/components/apps/overview/js/overview-manager.js @@ -441,7 +441,8 @@ class OverviewManager { // with no time reads as "any second now", which a 06:00-08:00 window // makes untrue for most of the day. const win = up.updates && up.updates.auto_window; - const winBit = (win && win !== 'always') ? ` during the ${esc(win).replace('-', '–')} window` : ''; + const winFmt = (this.updater && this.updater.fmtWindow) ? this.updater.fmtWindow(win) : String(win).replace('-', '–'); + const winBit = (win && win !== 'always') ? ` during the ${esc(winFmt)} window` : ''; rows.push({ hue: 'updates', icon: '⬆️', kind: 'ok', text: `${pending.length} update${pending.length === 1 ? '' : 's'} installing automatically${winBit}`, diff --git a/containers/libreportal/frontend/components/updater/js/updater-page.js b/containers/libreportal/frontend/components/updater/js/updater-page.js index 6ce0ead..8fdf022 100644 --- a/containers/libreportal/frontend/components/updater/js/updater-page.js +++ b/containers/libreportal/frontend/components/updater/js/updater-page.js @@ -184,6 +184,23 @@ class UpdaterPage { return null; } + // "06:00-08:00" -> "6am–8am"; "22:30-01:15" -> "10:30pm–1:15am". + // 24-hour time is unambiguous on paper and ambiguous at a glance: people read + // "06:00–08:00" and still have to work out whether that is morning or night. + // The config stays 24-hour (one canonical way to type it); only the display + // spells it out. Anything that is not a plain HH:MM-HH:MM is passed through. + fmtWindow(win) { + const m = String(win || '').match(/^(\d{1,2}):(\d{2})-(\d{1,2}):(\d{2})$/); + if (!m) return String(win || '').replace('-', '–'); + const one = (h, mi) => { + const H = parseInt(h, 10), M = parseInt(mi, 10); + const ap = H < 12 ? 'am' : 'pm'; + const hh = (H % 12) === 0 ? 12 : (H % 12); + return M ? `${hh}:${String(M).padStart(2, '0')}${ap}` : `${hh}${ap}`; + }; + return `${one(m[1], m[2])}–${one(m[3], m[4])}`; + } + sevRank(s) { const r = { critical: 0, high: 1, medium: 2, low: 3 }; return r[(s || '').toLowerCase()] ?? 4; @@ -750,7 +767,7 @@ class UpdaterPage { // iv === 0 the policy is moot and claiming otherwise would be a lie. // The window says WHEN: checks run all day, installs land inside it. const win = this.updates && this.updates.auto_window; - const winBit = (win && win !== 'always') ? ` during ${this.escape(win).replace('-', '–')}` : ''; + const winBit = (win && win !== 'always') ? ` during ${this.escape(this.fmtWindow(win))}` : ''; const auto = this.apps.filter((a) => a.update_type !== 'manual').length; let autoBit = ''; if (iv === 0 || !this.apps.length) autoBit = '';