| … | … | @@ -1496,6 +1496,13 @@ export function updateSettings (u) { |
| 1496 | 1496 | if (!u) return '' |
| 1497 | 1497 | const short = (h) => (h ? esc(String(h).slice(0, 12)) + '…' : '<span class="who">unknown</span>') |
| 1498 | 1498 | const checked = u.checkedAt ? '<p class="who">Last checked ' + esc(u.checkedAt) + '</p>' : '' |
| 1499 | // ⛔ THE VERSION FIRST, because it is the only line here a person can compare against a release | |
| 1500 | // page. Two tree hashes say something differs; they do not answer "is my update installed?", which | |
| 1501 | // is the question anyone opening this section actually has. | |
| 1502 | const built = u.builtAt ? ' <span class="who">built ' + esc(new Date(Number(u.builtAt)).toISOString()) + '</span>' : '' | |
| 1503 | const version = u.version | |
| 1504 | ? '<p><strong>Running ' + esc(u.version) + '</strong>' + built + '</p>' | |
| 1505 | : '<p class="who">This build does not report its version — it predates the stamp.</p>' | |
| 1499 | 1506 | |
| 1500 | 1507 | // ⛔ STAGED AND DIFFERENT is the only state that means "an update is waiting". Staged and IDENTICAL |
| 1501 | 1508 | // is the ordinary case — the node re-verified the bundle it is already running — and calling that |
| … | … | @@ -1507,7 +1514,7 @@ export function updateSettings (u) { |
| 1507 | 1514 | (u.ota ? '<p><button id="app-restart">restart now</button></p>' : '<p class="who">This app cannot restart itself; close and reopen it.</p>') |
| 1508 | 1515 | : '<p>Up to date.</p><p class="who">running ' + short(u.running) + '</p>' |
| 1509 | 1516 | |
| 1510 | return '<h2>App updates</h2>' + body + checked + | |
| 1517 | return '<h2>App updates</h2>' + version + body + checked + | |
| 1511 | 1518 | (u.ota ? '<p><button id="app-check">check now</button> <span id="app-msg" class="who"></span></p>' : '') + |
| 1512 | 1519 | (u.ota ? '<script type="module">\n' + UPDATE_JS + '\n</script>' : '') |
| 1513 | 1520 | } |
| … | … | @@ -1,6 +1,6 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "favela-surface", |
| 3 | "version": "0.0.52", | |
| 3 | "version": "0.0.53", | |
| 4 | 4 | "description": "The favela renderer \u2014 server-side HTML over the daemon's socket. No storage, no keys, no swarm.", |
| 5 | 5 | "type": "module", |
| 6 | 6 | "main": "index.js", |
| … | … | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | import test from 'brittle' |
| 4 | 4 | import fs from '#node:fs' |
| 5 | import { timeline, search, following, knocks, post, esc, layout, who, person, settings, handleSettings, namespaceSettings, composer, mentions, notifications, thread as pages_thread, withUpdateBanner } from '../lib/pages.js' | |
| 5 | import { timeline, search, following, knocks, post, esc, layout, who, person, settings, handleSettings, namespaceSettings, composer, mentions, notifications, thread as pages_thread, withUpdateBanner, updateSettings } from '../lib/pages.js' | |
| 6 | 6 | |
| 7 | 7 | const row = (over = {}) => ({ |
| 8 | 8 | author: 'ab'.repeat(32), collection: 'post', name: 'p1', |
| … | … | @@ -601,3 +601,17 @@ test('the banner sits at the top of the document, not wherever a page happens to |
| 601 | 601 | const out = withUpdateBanner('<html lang="en"><body><h1>x</h1></body></html>', { running: 'a', staged: 'b' }) |
| 602 | 602 | t.ok(out.indexOf('update-bar') < out.indexOf('<h1>'), 'it cannot be pushed below the fold') |
| 603 | 603 | }) |
| 604 | ||
| 605 | // ⛔ The version is the only line in the update section a person can compare against a release page. | |
| 606 | // Without it, settings showed two tree hashes and "is my update installed?" was unanswerable from | |
| 607 | // the device — which is exactly the state this section exists to prevent. | |
| 608 | test('★ the update section names the running VERSION, not just tree hashes', (t) => { | |
| 609 | const html = updateSettings({ ota: true, running: 'aaaa', staged: 'aaaa', version: '0.0.4', builtAt: 1789054155366 }) | |
| 610 | t.ok(html.includes('Running 0.0.4'), 'the version a release page would show') | |
| 611 | ||
| 612 | // ⚠ An older build predates the stamp. It must say so rather than render a blank or, worse, a | |
| 613 | // plausible-looking wrong version. | |
| 614 | const old = updateSettings({ ota: true, running: 'aaaa', staged: 'aaaa' }) | |
| 615 | t.ok(old.includes('predates the stamp'), 'and an unstamped build says why it cannot tell you') | |
| 616 | t.absent(old.includes('Running undefined'), 'never a fabricated version') | |
| 617 | }) |