feat(ui): make chat the landing view

This commit is contained in:
Peter Steinberger
2025-12-21 11:24:29 +00:00
parent 3791db006e
commit 6ddd36666e
3 changed files with 28 additions and 5 deletions

View File

@@ -70,7 +70,7 @@ const DEFAULT_CRON_FORM: CronFormState = {
export class ClawdisApp extends LitElement {
@state() settings: UiSettings = loadSettings();
@state() password = "";
@state() tab: Tab = "overview";
@state() tab: Tab = "chat";
@state() connected = false;
@state() hello: GatewayHelloOk | null = null;
@state() lastError: string | null = null;
@@ -156,6 +156,7 @@ export class ClawdisApp extends LitElement {
@state() debugCallError: string | null = null;
client: GatewayBrowserClient | null = null;
private chatScrollFrame: number | null = null;
createRenderRoot() {
return this;
@@ -166,6 +167,18 @@ export class ClawdisApp extends LitElement {
this.connect();
}
protected updated(changed: Map<PropertyKey, unknown>) {
if (
this.tab === "chat" &&
(changed.has("chatMessages") ||
changed.has("chatStream") ||
changed.has("chatLoading") ||
changed.has("tab"))
) {
this.scheduleChatScroll();
}
}
connect() {
this.lastError = null;
this.hello = null;
@@ -199,6 +212,16 @@ export class ClawdisApp extends LitElement {
this.client.start();
}
private scheduleChatScroll() {
if (this.chatScrollFrame) cancelAnimationFrame(this.chatScrollFrame);
this.chatScrollFrame = requestAnimationFrame(() => {
this.chatScrollFrame = null;
const container = this.querySelector(".messages") as HTMLElement | null;
if (!container) return;
container.scrollTop = container.scrollHeight;
});
}
private onEvent(evt: GatewayEventFrame) {
this.eventLog = [
{ ts: Date.now(), event: evt.event, payload: evt.payload },

View File

@@ -1,10 +1,11 @@
export const TAB_GROUPS = [
{ label: "Chat", tabs: ["chat"] },
{
label: "Control",
tabs: ["overview", "connections", "instances", "sessions", "cron"],
},
{ label: "Agent", tabs: ["chat", "skills", "nodes"] },
{ label: "Gateway", tabs: ["config", "debug"] },
{ label: "Agent", tabs: ["skills", "nodes"] },
{ label: "Settings", tabs: ["config", "debug"] },
] as const;
export type Tab =
@@ -72,4 +73,3 @@ export function subtitleForTab(tab: Tab) {
return "";
}
}

View File

@@ -38,6 +38,7 @@ export function renderChat(props: ChatProps) {
</div>
<div class="messages" style="margin-top: 12px;">
${props.loading ? html`<div class="muted">Loading chat…</div>` : nothing}
${props.messages.map((m) => renderMessage(m))}
${props.stream
? html`${renderMessage({
@@ -113,4 +114,3 @@ function extractText(message: unknown): string | null {
if (typeof m.text === "string") return m.text;
return null;
}