feat: track sprite state per tab

This commit is contained in:
2026-01-20 10:56:53 -08:00
parent 861b44797e
commit 51ecf47508
3 changed files with 47 additions and 11 deletions
+1
View File
@@ -33,6 +33,7 @@ export const claudeStore = {
// Methods
setConnectionStatus: conversationsStore.setConnectionStatus,
setConnectionStatusForConversation: conversationsStore.setConnectionStatusForConversation,
setCharacterStateForConversation: conversationsStore.setCharacterStateForConversation,
setSessionId: conversationsStore.setSessionId,
setSessionIdForConversation: conversationsStore.setSessionIdForConversation,
setWorkingDirectory: conversationsStore.setWorkingDirectory,
+22
View File
@@ -1,6 +1,8 @@
import { writable, derived, get } from "svelte/store";
import type { TerminalLine, ConnectionStatus, PermissionRequest } from "$lib/types/messages";
import type { CharacterState } from "$lib/types/states";
import { cleanupConversationTracking } from "$lib/tauri";
import { characterState } from "$lib/stores/character";
export interface Conversation {
id: string;
@@ -9,6 +11,7 @@ export interface Conversation {
sessionId: string | null;
connectionStatus: ConnectionStatus;
workingDirectory: string;
characterState: CharacterState;
isProcessing: boolean;
grantedTools: Set<string>;
createdAt: Date;
@@ -41,6 +44,7 @@ function createConversationsStore() {
sessionId: null,
connectionStatus: "disconnected",
workingDirectory: "",
characterState: "idle",
isProcessing: false,
grantedTools: new Set(),
createdAt: new Date(),
@@ -122,6 +126,19 @@ function createConversationsStore() {
return convs;
});
},
setCharacterStateForConversation: (conversationId: string, state: CharacterState) => {
conversations.update((convs) => {
const conv = convs.get(conversationId);
if (conv) {
conv.characterState = state;
// If this is the active conversation, update the global character state
if (conversationId === get(activeConversationId)) {
characterState.setState(state);
}
}
return convs;
});
},
requestPermission: (request: PermissionRequest) => pendingPermission.set(request),
clearPermission: () => pendingPermission.set(null),
setPendingRetryMessage: (message: string | null) => pendingRetryMessage.set(message),
@@ -177,6 +194,11 @@ function createConversationsStore() {
if (currentId !== id) {
activeConversationId.set(id);
// Update the global character state to match the conversation's state
if (targetConv) {
characterState.setState(targetConv.characterState);
}
// Auto-reconnect logic
if (targetConv && targetConv.connectionStatus === "disconnected") {
// Check if another conversation is connected
+24 -11
View File
@@ -142,7 +142,8 @@ export async function initializeTauriListeners() {
// Add system message to the correct conversation
claudeStore.addLineToConversation(targetConversationId, "system", "Connected to Claude Code");
characterState.setState("idle");
// Update character state for this conversation
claudeStore.setCharacterStateForConversation(targetConversationId, "idle");
// Check if this specific conversation has connected before
if (!connectedConversations.has(targetConversationId)) {
@@ -164,7 +165,10 @@ export async function initializeTauriListeners() {
claudeStore.addLineToConversation(targetConversationId, "system", "Disconnected from Claude Code");
}
characterState.setState("idle");
// Update character state for this conversation
if (targetConversationId) {
claudeStore.setCharacterStateForConversation(targetConversationId, "idle");
}
} else if (status === "error") {
const targetConversationId = conversation_id || get(claudeStore.activeConversationId);
@@ -181,12 +185,6 @@ export async function initializeTauriListeners() {
const stateUnlisten = await listen<StateChangePayload>("claude:state", (event) => {
const { state, conversation_id } = event.payload;
// Only process events for the active conversation
const activeConversationId = get(claudeStore.activeConversationId);
if (conversation_id && activeConversationId && conversation_id !== activeConversationId) {
return;
}
const stateMap: Record<string, CharacterState> = {
idle: "idle",
thinking: "thinking",
@@ -201,10 +199,25 @@ export async function initializeTauriListeners() {
const mappedState = stateMap[state.toLowerCase()] || "idle";
if (mappedState === "success" || mappedState === "error") {
characterState.setTemporaryState(mappedState, 3000);
// Always update the conversation's state
if (conversation_id) {
claudeStore.setCharacterStateForConversation(conversation_id, mappedState);
} else {
characterState.setState(mappedState);
// Fallback to active conversation if no conversation_id
const activeConversationId = get(claudeStore.activeConversationId);
if (activeConversationId) {
claudeStore.setCharacterStateForConversation(activeConversationId, mappedState);
}
}
// Only update global character state for active conversation
const activeConversationId = get(claudeStore.activeConversationId);
if (!conversation_id || conversation_id === activeConversationId) {
if (mappedState === "success" || mappedState === "error") {
characterState.setTemporaryState(mappedState, 3000);
} else {
characterState.setState(mappedState);
}
}
});
unlisteners.push(stateUnlisten);