feat(run-page): tick the run-duration timer between SSE pushes
Adds a 1s client-side ticker that rewrites .run-duration text from a
data-started-at attribute, so the header timer on /runs/{id}
increments every second while the run is active. When an SSE swap
lands a fresh header the new server-rendered value seamlessly takes
over; when the run goes terminal the template drops the attribute
and the ticker silently skips the node, leaving the final elapsed in
place.
Other templ_*.go churn is cosmetic — regenerator versions differ
between CI and local and only the filename field in templ.Error
callsites changed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -84,7 +84,42 @@
|
||||
});
|
||||
});
|
||||
|
||||
// --- 3. permalink scroll + highlight on load ------------------------
|
||||
// --- 3. live duration tick ------------------------------------------
|
||||
//
|
||||
// .run-duration spans carry data-started-at (RFC3339) while the run is
|
||||
// non-terminal. Every second we rewrite their text with the current
|
||||
// elapsed so the header timer ticks between SSE pushes. When an SSE
|
||||
// swap drops the attribute (run finished), the tick silently skips it
|
||||
// and the server-rendered final value stays put.
|
||||
|
||||
function formatDuration(ms) {
|
||||
if (ms < 0) { ms = 0; }
|
||||
if (ms < 1000) { return Math.floor(ms) + 'ms'; }
|
||||
if (ms < 10000) { return (ms / 1000).toFixed(1) + 's'; }
|
||||
if (ms < 60000) { return Math.floor(ms / 1000) + 's'; }
|
||||
if (ms < 3600000) {
|
||||
var m = Math.floor(ms / 60000);
|
||||
var s = Math.floor((ms % 60000) / 1000);
|
||||
return m + 'm ' + s + 's';
|
||||
}
|
||||
var h = Math.floor(ms / 3600000);
|
||||
var mm = Math.floor((ms % 3600000) / 60000);
|
||||
return h + 'h ' + mm + 'm';
|
||||
}
|
||||
|
||||
function tickDurations() {
|
||||
var now = Date.now();
|
||||
var nodes = document.querySelectorAll('.run-duration[data-started-at]');
|
||||
nodes.forEach(function (el) {
|
||||
var startMs = Date.parse(el.getAttribute('data-started-at'));
|
||||
if (isNaN(startMs)) { return; }
|
||||
el.textContent = formatDuration(now - startMs);
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(tickDurations, 1000);
|
||||
|
||||
// --- 4. permalink scroll + highlight on load ------------------------
|
||||
|
||||
function scrollToHash() {
|
||||
var hash = (location.hash || '').replace(/^#/, '');
|
||||
|
||||
Reference in New Issue
Block a user