- FAB button now correctly stops session during speaking/processing states - Echo prevention: STT stopped during TTS playback, results ignored during speaking - Chat TTS only speaks when voice session is active (no auto-speak for text chat) - Session stop now aborts in-flight API requests and prevents race conditions - STT restarts after TTS with 800ms delay for audio focus release - Pending interrupt transcript processed after TTS completion - ChatContext added for message persistence across tab navigation - VoiceFAB redesigned with state-based animations - console.error replaced with console.warn across voice pipeline - no-speech STT errors silenced (normal silence behavior)
52 lines
1.5 KiB
TypeScript
52 lines
1.5 KiB
TypeScript
/**
|
|
* Chat Context - Persists chat messages across tab navigation
|
|
*
|
|
* Without this context, messages are lost when switching tabs
|
|
* because ChatScreen component unmounts and remounts.
|
|
*/
|
|
|
|
import React, { createContext, useContext, useState, useCallback, ReactNode } from 'react';
|
|
import type { Message } from '@/types';
|
|
|
|
interface ChatContextValue {
|
|
messages: Message[];
|
|
setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
|
|
addMessage: (message: Message) => void;
|
|
clearMessages: (initialMessage: Message) => void;
|
|
}
|
|
|
|
const ChatContext = createContext<ChatContextValue | undefined>(undefined);
|
|
|
|
export function ChatProvider({ children }: { children: ReactNode }) {
|
|
const [messages, setMessages] = useState<Message[]>([
|
|
{
|
|
id: '1',
|
|
role: 'assistant',
|
|
content: "Hello! I'm Julia, your AI wellness companion.\n\nType a message below to chat with me.",
|
|
timestamp: new Date(),
|
|
},
|
|
]);
|
|
|
|
const addMessage = useCallback((message: Message) => {
|
|
setMessages(prev => [...prev, message]);
|
|
}, []);
|
|
|
|
const clearMessages = useCallback((initialMessage: Message) => {
|
|
setMessages([initialMessage]);
|
|
}, []);
|
|
|
|
return (
|
|
<ChatContext.Provider value={{ messages, setMessages, addMessage, clearMessages }}>
|
|
{children}
|
|
</ChatContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useChat() {
|
|
const context = useContext(ChatContext);
|
|
if (!context) {
|
|
throw new Error('useChat must be used within ChatProvider');
|
|
}
|
|
return context;
|
|
}
|