//// // The scrollback shows your history of interacting with the shell. // input, output, etc import { scrollback, $$ } from "./dom.js" import type { CommandOutput } from "../shared/types.js" type InputStatus = "waiting" | "streaming" | "ok" | "error" export function autoScroll() { setTimeout(() => { requestAnimationFrame(() => scrollback.scrollTop = scrollback.scrollHeight) }, 10) } export function addInput(id: string, input: string) { const parent = $$("li.input") const status = $$("span.status.yellow", "•") const content = $$("span.content", input) parent.append(status, content) parent.dataset.id = id scrollback.append(parent) } export function setStatus(id: string, status: InputStatus) { const statusEl = document.querySelector(`[data-id="${id}"].input .status`) if (!statusEl) return statusEl.className = "" switch (status) { case "waiting": statusEl.classList.add("yellow") break case "streaming": statusEl.classList.add("purple") break case "ok": statusEl.classList.add("green") break case "error": statusEl.classList.add("red") break } } export function addOutput(id: string, output: CommandOutput) { const item = $$("li") item.classList.add("output") item.dataset.id = id const [format, content] = processOutput(output) if (format === "html") item.innerHTML = content else item.textContent = content scrollback.append(item) autoScroll() } function processOutput(output: CommandOutput): ["html" | "text", string] { let content = "" let html = false if (typeof output === "string") { content = output } else if (output.html !== undefined) { html = true content = output.html } else { content = JSON.stringify(output) } return [html ? "html" : "text", content] }