// The status bar (spec ยง9): the proposal whose source is the current // bookmark, with its checks, refreshed on the hub's event stream. import * as vscode from "vscode"; import { HubAuth } from "./auth"; import type { HubRepo } from "./proposals"; export class ChecksBar implements vscode.Disposable { private readonly item = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 40); private timer: NodeJS.Timeout | undefined; constructor( private readonly auth: HubAuth, private readonly repos: () => Promise, ) { this.item.command = "oxygenhub.openProposal"; } async refresh(): Promise { const repos = await this.repos(); for (const repo of repos) { const bookmark = repo.handle.currentBookmark; if (!bookmark) { continue; } try { const list = await this.auth.clientFor(repo.base).proposals(repo.owner, repo.name); const p = list.find((x) => x.source.kind === "bookmark" && x.source.bookmark === bookmark && x.state === "open"); if (p) { const checks = await this.auth.clientFor(repo.base).proposalChecks(repo.owner, repo.name, p.number); const passed = checks.filter((c) => c.status === "passed").length; const failed = checks.filter((c) => c.status === "failed").length; const running = checks.filter((c) => c.status === "running" || c.status === "queued").length; const glyph = failed ? "$(error)" : running ? "$(sync~spin)" : checks.length ? "$(pass)" : "$(git-pull-request)"; this.item.text = `${glyph} #${p.number}${checks.length ? ` ${passed}/${checks.length}` : ""}`; this.item.tooltip = `${p.title}\n${p.landable ? "ready to land" : p.blockers.join("\n")}`; this.item.command = { title: "Open", command: "oxygenhub.openProposal", arguments: [{ kind: "proposal", repo, p }] }; this.item.show(); return; } } catch { // Not signed in or unreachable: nothing to show. } } this.item.hide(); } /** Poll on the configured interval; the hub's SSE stream needs a browser-grade EventSource, so the bar polls instead. */ start(): void { const seconds = vscode.workspace.getConfiguration("oxygenhub").get("autoRefresh") ?? 60; if (this.timer) { clearInterval(this.timer); } if (seconds > 0) { this.timer = setInterval(() => void this.refresh(), seconds * 1000); } void this.refresh(); } dispose(): void { if (this.timer) { clearInterval(this.timer); } this.item.dispose(); } }