summaryrefslogtreecommitdiffhomepage
path: root/packages/frontend/src/lib/components/ChatPanel.svelte
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-03 15:29:45 +0900
committerAdam Malczewski <[email protected]>2026-06-03 15:30:38 +0900
commit5af9bd021c206b9e4330ab6a549dc8d013d91537 (patch)
tree667dca977d6eb78e09006c5553523230daa2b73f /packages/frontend/src/lib/components/ChatPanel.svelte
parentbcc449a5cba183c7358ab48ed4f2140bb1a3238c (diff)
parentbc3ecbe7b72f6da6ed36d0cea5a66de1c440269a (diff)
downloaddispatch-5af9bd021c206b9e4330ab6a549dc8d013d91537.tar.gz
dispatch-5af9bd021c206b9e4330ab6a549dc8d013d91537.zip
Merge branch 'dev' into warm/prompt-cache-warming
# Conflicts: # packages/api/src/agent-manager.ts # packages/api/tests/agent-manager.test.ts # packages/frontend/src/lib/tabs.svelte.ts
Diffstat (limited to 'packages/frontend/src/lib/components/ChatPanel.svelte')
-rw-r--r--packages/frontend/src/lib/components/ChatPanel.svelte27
1 files changed, 23 insertions, 4 deletions
diff --git a/packages/frontend/src/lib/components/ChatPanel.svelte b/packages/frontend/src/lib/components/ChatPanel.svelte
index abdec17..ee1b8ef 100644
--- a/packages/frontend/src/lib/components/ChatPanel.svelte
+++ b/packages/frontend/src/lib/components/ChatPanel.svelte
@@ -10,6 +10,11 @@ let isLoadingMore = $state(false);
const renderGroups = $derived(tabStore.activeTab?.renderGroups ?? []);
const activeTabId = $derived(tabStore.activeTab?.id);
+// Compaction placeholder state for the active tab. `compactingSource` is set on
+// a transient placeholder tab while a conversation is being compacted;
+// `compactionError` is set if it failed.
+const compactingSource = $derived(tabStore.activeTab?.compactingSource ?? null);
+const compactionError = $derived(tabStore.activeTab?.compactionError ?? null);
// Stable, turn-scoped render keys. A bubble's identity is `${turnId}:${role}:${n}`
// (n = its index among same-(turn,role) messages) rather than the underlying
@@ -138,14 +143,28 @@ $effect(() => {
{#if isLoadingMore}
<div class="text-center text-xs text-base-content/40 py-2">Loading earlier messages...</div>
{/if}
- {#if renderGroups.length === 0}
+ {#if compactingSource || compactionError}
+ <div class="flex flex-col items-center justify-center h-full gap-4 px-6 text-center">
+ {#if compactionError}
+ <div class="text-2xl font-semibold text-error">Compaction failed</div>
+ <div class="text-base text-base-content/70 max-w-md">{compactionError}</div>
+ <div class="text-sm text-base-content/50">Close this tab to dismiss — your conversation was not changed.</div>
+ {:else}
+ <span class="loading loading-spinner loading-lg text-primary"></span>
+ <div class="text-2xl font-semibold text-base-content">Please wait, compacting conversation…</div>
+ <div class="text-sm text-base-content/50">You can cancel by closing this tab.</div>
+ {/if}
+ </div>
+ {:else if renderGroups.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 keyedMessages as { m, key } (key)}
- <ChatMessageComponent message={m} tabId={activeTabId} />
- {/each}
+ {#if !compactingSource && !compactionError}
+ {#each keyedMessages as { m, key } (key)}
+ <ChatMessageComponent message={m} tabId={activeTabId} />
+ {/each}
+ {/if}
</div>
<!-- Scroll-to-bottom button -->