128 lines · 5.2 KB
import * as vscode from "vscode";
import { DocumentBinding } from "./binding";
import { Cursors } from "./cursors";
import { ForgeApi } from "./forge";
import type { EditorSessionInfo } from "./forge";
import { GitforFileSystem } from "./fs";
import { RoomClient } from "./room-client";
import { GitforScm } from "./scm";
import { registerContainer } from "./terminal";

const SESSION_COMMAND = "gitfor.session";
const REFRESH_COMMAND = "gitfor.refreshSession";

/**
 * gitfor-fs: the built-in web extension that turns the VS Code for the Web workbench into a gitfor
 * editor. It gets its ref-scoped token from the embedding page (never cookies), mounts the branch as
 * `gitfor:`, joins the branch's co-editing room and commits through the forge.
 */
export async function activate(context: vscode.ExtensionContext): Promise<void> {
  const session = await vscode.commands.executeCommand<EditorSessionInfo>(SESSION_COMMAND);
  if (!session) throw new Error("No gitfor editor session");
  const api = new ForgeApi(session);
  const root = `/${session.owner}/${session.repo}`;
  const status = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100);
  status.text = "$(sync~spin) Connecting";
  status.show();

  let scm: GitforScm | null = null;
  let cursors: Cursors | null = null;
  const room = new RoomClient(api.roomUrl(), session.token, {
    onControl(message) {
      if (message.type === "status") scm?.onStatus(message);
      if (message.type === "committed") {
        fs.refresh();
        void vscode.window.showInformationMessage(
          `${message.by} committed ${message.sha.slice(0, 7)} to ${message.branch}${message.pullUrl ? " (pull request opened)" : ""}.`,
        );
      }
      if (message.type === "error" && !message.path) void vscode.window.showWarningMessage(message.message);
    },