diff options
| author | Adam Malczewski <[email protected]> | 2026-05-21 19:52:35 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-05-21 19:52:35 +0900 |
| commit | 4ba2673557c7cfd0bc31b03e2c35ab5e1efe60e7 (patch) | |
| tree | dddae8fc37a12157f4c8e840475e9e5d6203464a /packages/frontend/src/lib/components/ChatPanel.svelte | |
| parent | 55633c90c0d96e62153a4b6655f3f833a3b46ad4 (diff) | |
| download | dispatch-4ba2673557c7cfd0bc31b03e2c35ab5e1efe60e7.tar.gz dispatch-4ba2673557c7cfd0bc31b03e2c35ab5e1efe60e7.zip | |
feat: tab system with per-tab agents, DB persistence, and DaisyUI tabs-lift UI
- Add tabs, messages, and settings tables to SQLite database
- Backend: refactor AgentManager to manage per-tab Agent instances via Map<tabId, TabAgent>
- Backend: WebSocket events tagged with tabId for multiplexing
- Backend: tab CRUD routes (create, list, update, archive, messages)
- Backend: persist user and assistant messages to DB during chat
- Frontend: new tabStore replaces single chatStore with multi-tab reactive state
- Frontend: TabBar component using DaisyUI tabs-lift style with status dots
- Frontend: Settings sidebar panel for title generation model selection
- Frontend: wire ChatPanel, ChatInput, Header to use tabStore
- Fix HMR listener accumulation via wsClient.clearCallbacks()
- Delete old single-chat chatStore (chat.svelte.ts)
Diffstat (limited to 'packages/frontend/src/lib/components/ChatPanel.svelte')
| -rw-r--r-- | packages/frontend/src/lib/components/ChatPanel.svelte | 33 |
1 files changed, 6 insertions, 27 deletions
diff --git a/packages/frontend/src/lib/components/ChatPanel.svelte b/packages/frontend/src/lib/components/ChatPanel.svelte index 11c3b5d..24d8c7f 100644 --- a/packages/frontend/src/lib/components/ChatPanel.svelte +++ b/packages/frontend/src/lib/components/ChatPanel.svelte @@ -1,13 +1,14 @@ <script lang="ts"> import { untrack } from "svelte"; - import { chatStore } from "../chat.svelte.js"; - import { wsClient } from "../ws.svelte.js"; + import { tabStore } from "../tabs.svelte.js"; import ChatMessageComponent from "./ChatMessage.svelte"; let messagesEl: HTMLDivElement | undefined; let userScrolledUp = $state(false); let isAutoScrolling = false; + const messages = $derived(tabStore.activeTab?.messages ?? []); + function isNearBottom(el: HTMLElement): boolean { return el.scrollHeight - el.scrollTop - el.clientHeight < 64; } @@ -32,8 +33,7 @@ } $effect(() => { - // Trigger on any message appended; track length explicitly - const count = chatStore.messages.length; + const count = messages.length; void count; if (messagesEl) { untrack(() => { @@ -44,27 +44,6 @@ </script> <div class="flex flex-col h-full"> - <!-- Status bar --> - <div class="flex items-center gap-3 px-4 py-2 bg-base-200 border-b border-base-300 text-xs"> - <span class="flex items-center gap-1.5"> - <span class="status status-sm {wsClient.connectionStatus === 'connected' ? 'status-success' : wsClient.connectionStatus === 'connecting' ? 'status-warning' : 'status-error'}"></span> - <span class="capitalize text-base-content/70">{wsClient.connectionStatus}</span> - </span> - <span class="text-base-content/50">|</span> - <span class="text-base-content/70"> - Agent: - <span - class="font-semibold {chatStore.agentStatus === 'running' - ? 'text-warning' - : chatStore.agentStatus === 'error' - ? 'text-error' - : 'text-success'}" - > - {chatStore.agentStatus === "running" ? "running..." : chatStore.agentStatus} - </span> - </span> - </div> - <!-- Messages --> <div class="relative flex-1 min-h-0"> <div @@ -75,12 +54,12 @@ isAutoScrolling = false; }} > - {#if chatStore.messages.length === 0} + {#if messages.length === 0} <div class="flex items-center justify-center h-full text-base-content/40 text-sm"> Send a message to start a conversation </div> {/if} - {#each chatStore.messages as message (message.id)} + {#each messages as message (message.id)} <ChatMessageComponent {message} /> {/each} </div> |
