import type { Save } from "../mirror/queries.ts";
import { type Html, html } from "./html.ts";
import { formatDate } from "./layout.ts";
/**
* §21.4's dotted timeline as SVG, so it draws without JavaScript (kepr.js swaps it for Kepr 2's
* drifting canvas, reading each save from its dot): one dot per save on a dashed line, x by
* time (as a percentage, so it scales without squashing dots), brighter and fuller where
* neighbours crowd within a fortieth of the span.
*/
export function timelineSvg(repo: string, saves: Save[]): Html {
const times = saves.map((save) => save.created_at);
// Replayed saves keep their own times, so the line is not in time order.
const first = times.reduce((a, b) => Math.min(a, b), times[0] ?? 0);
const span = times.reduce((a, b) => Math.max(a, b), first) - first;
const reach = Math.max(span / 40, 3600);
const dots = saves.map((save) => {
const x = span === 0 ? 50 : 1 + (98 * (save.created_at - first)) / span;
// ponytail: O(n²) neighbour count; a sliding window over sorted times if a repo
// reaches ~5,000 saves.
const near = times.filter((t) => Math.abs(t - save.created_at) <= reach).length;
const level = near >= 8 ? 3 : near >= 4 ? 2 : near >= 2 ? 1 : 0;
const meta = [formatDate(save.created_at), save.agent, save.session]
.filter(Boolean)
.join(" · ");
const tip = `${save.id}\n${save.message.split("\n")[0]}\n${meta}`;
return html`${tip}`;
});
return html``;
}