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 = '';