// Diffusion in the editor, without VS Code (oxygenhub-vscode#5): how a pin // between an upstream and its consumer looks. The hub's pill has two halves, // the upstream's state and the consumer's; a tree row has one icon, so it // shows the more urgent of the two and says both in words. import type { DiffusionHalf, DiffusionPin } from "./hubapi"; /** A codicon and a theme colour id. */ export interface Look { icon: string; color: string; } /** Most urgent first: a failure, then what nothing checked, then waiting. */ const URGENCY = ["red", "amber", "grey", "green", "off"]; /** The tone a row shows: the more urgent half, ignoring a consumer that does not follow. */ export function tone(pin: DiffusionPin): string { const tones = [pin.upstream_state.tone, pin.consumer_state.tone].filter((t) => t !== "off"); return tones.sort((a, b) => rank(a) - rank(b))[0] ?? "off"; } function rank(t: string): number { const i = URGENCY.indexOf(t); return i < 0 ? URGENCY.length : i; } export function look(t: string): Look { switch (t) { case "green": return { icon: "pass-filled", color: "testing.iconPassed" }; case "red": return { icon: "error", color: "testing.iconFailed" }; case "amber": return { icon: "warning", color: "list.warningForeground" }; case "grey": return { icon: "clock", color: "testing.iconQueued" }; default: return { icon: "circle-outline", color: "disabledForeground" }; } } /** The row's name: the repository on the other end of the pin. */ export function pinLabel(pin: DiffusionPin, side: "takes" | "gives"): string { return side === "takes" ? pin.upstream : pin.consumer; } /** "untested │ passes · 2 behind · bump #304", as the hub's pill reads. */ export function pinDescription(pin: DiffusionPin): string { const parts = [`${pin.upstream_state.word} │ ${pin.consumer_state.word}`]; if (pin.behind !== null && pin.behind !== undefined && pin.behind > 0) { parts.push(`${pin.behind} behind`); } if (pin.bump !== null && pin.bump !== undefined) { parts.push(`bump #${pin.bump}`); } return parts.join(" · "); } const FOLLOW: Record = { off: "does not follow", green: "follows when the upstream is green", any: "follows every move" }; /** The tooltip, in Markdown: both halves' sentences, then the pin. */ export function pinTooltip(pin: DiffusionPin): string { const half = (who: string, h: DiffusionHalf) => `**${who}: ${h.word}.** ${h.title}`; const run = pin.run !== null && pin.run !== undefined ? ` · run #${pin.run}${pin.run_status ? ` ${pin.run_status}` : ""}` : ""; return [ half(pin.upstream, pin.upstream_state), half(pin.consumer, pin.consumer_state), `Pinned at \`${pin.path}\` on \`${pin.bookmark}\`; ${pin.consumer} ${FOLLOW[pin.follow] ?? pin.follow}.${pin.bump !== null && pin.bump !== undefined ? ` Open bump #${pin.bump}${run}.` : ""}`, ].join("\n\n"); }