OXYGENHUB
# 77998d682d47 oxygenhub-vscode / src / checks.ts
2.6 KiB · last changed 0.1.0: sign in, hub client with generated types, remote provider, proposals and issues views, review threads on atoms, seal and land through oxy, checks status bar 1 month ago source blame history raw
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
}