| f0b06dea Andy McCall |
1 |
// The status bar (spec §9): the proposal whose source is the current |
| 2 |
// bookmark, with its checks, refreshed on the hub's event stream. |
| 3 |
|
| 4 |
import * as vscode from "vscode"; |
| 5 |
import { HubAuth } from "./auth"; |
| 6 |
import type { HubRepo } from "./proposals"; |
| 7 |
|
| 8 |
export class ChecksBar implements vscode.Disposable { |
| 9 |
private readonly item = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 40); |
| 10 |
private timer: NodeJS.Timeout | undefined; |
| 11 |
|
| 12 |
constructor( |
| 13 |
private readonly auth: HubAuth, |
| 14 |
private readonly repos: () => Promise<HubRepo[]>, |
| 15 |
) { |
| 16 |
this.item.command = "oxygenhub.openProposal"; |
| 17 |
} |
| 18 |
|
| 19 |
async refresh(): Promise<void> { |
| 20 |
const repos = await this.repos(); |
| 21 |
for (const repo of repos) { |
| 22 |
const bookmark = repo.handle.currentBookmark; |
| 23 |
if (!bookmark) { |
| 24 |
continue; |
| 25 |
} |
| 26 |
try { |
| 27 |
const list = await this.auth.clientFor(repo.base).proposals(repo.owner, repo.name); |
| 28 |
const p = list.find((x) => x.source.kind === "bookmark" && x.source.bookmark === bookmark && x.state === "open"); |
| 29 |
if (p) { |
| 30 |
const checks = await this.auth.clientFor(repo.base).proposalChecks(repo.owner, repo.name, p.number); |
| 31 |
const passed = checks.filter((c) => c.status === "passed").length; |
| 32 |
const failed = checks.filter((c) => c.status === "failed").length; |
| 33 |
const running = checks.filter((c) => c.status === "running" || c.status === "queued").length; |
| 34 |
const glyph = failed ? "$(error)" : running ? "$(sync~spin)" : checks.length ? "$(pass)" : "$(git-pull-request)"; |
| 35 |
this.item.text = `${glyph} #${p.number}${checks.length ? ` ${passed}/${checks.length}` : ""}`; |
| 36 |
this.item.tooltip = `${p.title}\n${p.landable ? "ready to land" : p.blockers.join("\n")}`; |
| 37 |
this.item.command = { title: "Open", command: "oxygenhub.openProposal", arguments: [{ kind: "proposal", repo, p }] }; |
| 38 |
this.item.show(); |
| 39 |
return; |
| 40 |
} |
| 41 |
} catch { |
| 42 |
// Not signed in or unreachable: nothing to show. |
| 43 |
} |
| 44 |
} |
| 45 |
this.item.hide(); |
| 46 |
} |
| 47 |
|
| 48 |
/** Poll on the configured interval; the hub's SSE stream needs a browser-grade EventSource, so the bar polls instead. */ |
| 49 |
start(): void { |
| 50 |
const seconds = vscode.workspace.getConfiguration("oxygenhub").get<number>("autoRefresh") ?? 60; |
| 51 |
if (this.timer) { |
| 52 |
clearInterval(this.timer); |
| 53 |
} |
| 54 |
if (seconds > 0) { |
| 55 |
this.timer = setInterval(() => void this.refresh(), seconds * 1000); |
| 56 |
} |
| 57 |
void this.refresh(); |
| 58 |
} |
| 59 |
|
| 60 |
dispose(): void { |
| 61 |
if (this.timer) { |
| 62 |
clearInterval(this.timer); |
| 63 |
} |
| 64 |
this.item.dispose(); |
| 65 |
} |
| 66 |
} |