feat(*): svelte 5 panel view sharing the gateway ui, obsidian theme, preview and tests
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
import { Component } from "obsidian";
|
||||
import { mount } from "svelte";
|
||||
import { PanelState } from "../src/state.svelte";
|
||||
import App from "../src/ui/app.svelte";
|
||||
import { BRANCH_BLASTER, DEEP_PANEL, FakeClient, MASTER } from "./fake-client";
|
||||
|
||||
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
// bits-ui opens menus on pointerdown and tabs on pointer or click: send both.
|
||||
function press(element: Element | null | undefined): void {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
element.dispatchEvent(
|
||||
new PointerEvent("pointerdown", {
|
||||
bubbles: true,
|
||||
button: 0,
|
||||
cancelable: true,
|
||||
pointerType: "mouse",
|
||||
})
|
||||
);
|
||||
(element as HTMLElement).focus();
|
||||
(element as HTMLElement).click();
|
||||
}
|
||||
|
||||
// Scenes for screenshots: open the page with a hash to land in a state.
|
||||
// Width comes from the window (``--window-size``), the state from here.
|
||||
async function main(): Promise<void> {
|
||||
const client = new FakeClient();
|
||||
const state = new PanelState();
|
||||
const scene = location.hash.slice(1) || "thread";
|
||||
state.selected = MASTER;
|
||||
if (scene === "empty") {
|
||||
state.selected = null;
|
||||
}
|
||||
if (scene === "question") {
|
||||
state.selected = BRANCH_BLASTER;
|
||||
}
|
||||
if (scene === "deep") {
|
||||
state.selected = DEEP_PANEL;
|
||||
}
|
||||
if (scene === "offline") {
|
||||
state.selected = MASTER;
|
||||
}
|
||||
document.body.classList.toggle("theme-light", scene.endsWith("-light"));
|
||||
document.body.classList.toggle("theme-dark", !scene.endsWith("-light"));
|
||||
|
||||
const app = {
|
||||
workspace: {
|
||||
openLinkText: (target: string) => console.log("open", target),
|
||||
},
|
||||
};
|
||||
mount(App, {
|
||||
props: {
|
||||
app: app as never,
|
||||
client: scene === "offline" ? null : client,
|
||||
component: new Component() as never,
|
||||
onOpenSettings: () => console.log("settings"),
|
||||
state,
|
||||
vaultSubpath: () => "💬 чаты",
|
||||
},
|
||||
target: document.getElementById("app") as HTMLElement,
|
||||
});
|
||||
await wait(80);
|
||||
|
||||
if (scene.startsWith("closed")) {
|
||||
press(document.querySelector('[aria-label="Switch conversation"]'));
|
||||
await wait(60);
|
||||
press(document.querySelector('[title="Show closed conversations"]'));
|
||||
}
|
||||
if (scene.startsWith("switcher")) {
|
||||
document
|
||||
.querySelector<HTMLButtonElement>('[aria-label="Switch conversation"]')
|
||||
?.click();
|
||||
}
|
||||
if (scene.startsWith("menu")) {
|
||||
const row =
|
||||
document.querySelector<HTMLElement>(`[data-row="${BRANCH_BLASTER}"]`) ??
|
||||
(await (async () => {
|
||||
document
|
||||
.querySelector<HTMLButtonElement>(
|
||||
'[aria-label="Switch conversation"]'
|
||||
)
|
||||
?.click();
|
||||
await wait(60);
|
||||
return document.querySelector<HTMLElement>(
|
||||
`[data-row="${BRANCH_BLASTER}"]`
|
||||
);
|
||||
})());
|
||||
row?.dispatchEvent(
|
||||
new MouseEvent("contextmenu", {
|
||||
bubbles: true,
|
||||
clientX: row.getBoundingClientRect().left + 120,
|
||||
clientY: row.getBoundingClientRect().top + 16,
|
||||
})
|
||||
);
|
||||
}
|
||||
if (scene.startsWith("actions")) {
|
||||
press(document.querySelector('[aria-label="Conversation actions"]'));
|
||||
}
|
||||
if (scene.startsWith("activity")) {
|
||||
for (const trigger of document.querySelectorAll<HTMLButtonElement>(
|
||||
'[data-slot="tabs-trigger"]'
|
||||
)) {
|
||||
if (trigger.textContent?.trim() === "Activity") {
|
||||
press(trigger);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scene.startsWith("branch")) {
|
||||
document
|
||||
.querySelector<HTMLButtonElement>(
|
||||
'[aria-label="Branch off this conversation"]'
|
||||
)
|
||||
?.click();
|
||||
}
|
||||
await wait(60);
|
||||
if (scene.startsWith("stream")) {
|
||||
// A tool lands while you watch: the tree grows without a reload.
|
||||
client.emit({
|
||||
conversation_id: MASTER,
|
||||
input: { command: "curl -sI https://b.hhhhh.dev/healthz" },
|
||||
name: "Bash",
|
||||
parent_tool_use_id: null,
|
||||
tool_use_id: "tu_live",
|
||||
turn_id: "t-run",
|
||||
type: "tool",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
Reference in New Issue
Block a user