import { get } from "./api.js"; import { errorText, h, replace } from "./dom.js"; import { onEach, state } from "./state.js"; const chosen = new Map(); export function previewURL(port) { return `https://${location.hostname}:${port}/`; } export function mountPreview(root) { const head = h("header", { class: "preview-header" }); const body = h("div", { class: "preview-body" }); let previews; let error = ""; let target = 0; let framed = ""; let disposed = false; const current = () => { const taskId = state.selectedTaskId; const name = taskId ? chosen.get(taskId) : undefined; return previews?.find((p) => p.name === name) ?? previews?.[0]; }; const load = async () => { const taskId = state.selectedTaskId; if (!taskId) { render(); return; } const started = ++target; try { const fresh = await get("/api/tasks/{taskId}/previews", { path: { taskId } }); if (started === target) { previews = fresh; error = ""; } } catch (err) { if (started === target) { previews = undefined; error = errorText(err); } } if (!disposed && started === target) { render(); } }; const render = () => { const taskId = state.selectedTaskId; const shown = current(); replace(head, h("nav", { class: "preview-names" }, ...(previews ?? []).map((p) => { const b = h("button", { type: "button", class: p === shown ? "preview-name active" : "preview-name" }, p.name, h("span", { class: "preview-port" }, ` :${p.port}`)); b.onclick = () => { if (taskId) { chosen.set(taskId, p.name); } render(); }; return b; })), shown ? h("a", { class: "preview-open", href: previewURL(shown.port), target: "_blank", rel: "noopener" }, "open ↗") : null); if (!taskId) { framed = ""; replace(body, h("div", { class: "empty" }, "No task selected.")); return; } if (error) { framed = ""; replace(body, h("div", { class: "empty error-text" }, error)); return; } if (!previews) { framed = ""; replace(body, h("div", { class: "empty" }, "Loading…")); return; } if (!shown) { framed = ""; replace(body, h("div", { class: "empty" }, "Nothing exposed. The task's agent shows a running server here with expose_port.")); return; } const url = previewURL(shown.port); if (url === framed) { return; } framed = url; replace(body, h("iframe", { class: "preview-frame", src: url, title: shown.name })); }; const offs = [ onEach(["selection"], () => { target++; previews = undefined; error = ""; render(); void load(); }), onEach(["transcript"], (fresh) => { if (fresh.some((ev) => ev.kind === "preview.exposed")) { framed = ""; void load(); } }), ]; replace(root, h("div", { class: "preview-view" }, head, body)); render(); void load(); return () => { disposed = true; for (const off of offs) { off(); } }; } //# sourceMappingURL=preview.js.map