Question formatting
This commit is contained in:
Vendored
+20
-87
@@ -1,110 +1,43 @@
|
||||
import { get } from "./api.js";
|
||||
import { errorText, h, replace } from "./dom.js";
|
||||
import { 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 = "";
|
||||
export function previewLinks() {
|
||||
const root = h("nav", { class: "preview-links" });
|
||||
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;
|
||||
const started = ++target;
|
||||
if (!taskId) {
|
||||
render();
|
||||
replace(root);
|
||||
return;
|
||||
}
|
||||
const started = ++target;
|
||||
try {
|
||||
const fresh = await get("/api/tasks/{taskId}/previews", { path: { taskId } });
|
||||
if (started === target) {
|
||||
previews = fresh;
|
||||
error = "";
|
||||
const previews = await get("/api/tasks/{taskId}/previews", { path: { taskId } });
|
||||
if (started !== target) {
|
||||
return;
|
||||
}
|
||||
replace(root, ...previews.map((p) => h("a", { class: "preview-link", href: previewURL(p.port), target: "_blank", rel: "noopener", title: `Open ${p.name} (port ${p.port}) in a new window` }, p.name, " ↗")));
|
||||
}
|
||||
catch (err) {
|
||||
if (started === target) {
|
||||
previews = undefined;
|
||||
error = errorText(err);
|
||||
replace(root);
|
||||
}
|
||||
}
|
||||
if (!disposed && started === target) {
|
||||
render();
|
||||
console.error("list previews", err);
|
||||
}
|
||||
};
|
||||
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();
|
||||
onEach(["selection"], () => {
|
||||
replace(root);
|
||||
void load();
|
||||
});
|
||||
onEach(["transcript"], (fresh) => {
|
||||
if (fresh?.some((ev) => ev.kind === "preview.exposed")) {
|
||||
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();
|
||||
}
|
||||
};
|
||||
});
|
||||
void load();
|
||||
return root;
|
||||
}
|
||||
//# sourceMappingURL=preview.js.map
|
||||
Reference in New Issue
Block a user