feat: Display voice messages in chat in real-time
Voice transcripts from both user and Julia now appear in the chat immediately during the call, not just after it ends. Each voice call shows a "Voice Call" separator, and voice messages display with a microphone icon indicator. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
560722e8af
commit
09fc6ce8ad
@ -387,7 +387,7 @@ const voiceStyles = StyleSheet.create({
|
|||||||
export default function ChatScreen() {
|
export default function ChatScreen() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { currentBeneficiary, setCurrentBeneficiary } = useBeneficiary();
|
const { currentBeneficiary, setCurrentBeneficiary } = useBeneficiary();
|
||||||
const { getTranscriptAsMessages, hasNewTranscript, markTranscriptAsShown, addTranscriptEntry, clearTranscript } = useVoiceTranscript();
|
const { addTranscriptEntry, clearTranscript } = useVoiceTranscript();
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const {
|
const {
|
||||||
callState,
|
callState,
|
||||||
@ -412,30 +412,17 @@ export default function ChatScreen() {
|
|||||||
// Voice call state (local connecting state only)
|
// Voice call state (local connecting state only)
|
||||||
const [isConnectingVoice, setIsConnectingVoice] = useState(false);
|
const [isConnectingVoice, setIsConnectingVoice] = useState(false);
|
||||||
|
|
||||||
// Add voice call transcript to messages when returning from call
|
// Track if we've shown the voice call separator for current call
|
||||||
|
const [hasShownVoiceSeparator, setHasShownVoiceSeparator] = useState(false);
|
||||||
|
|
||||||
|
// Reset separator flag when starting a new call
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hasNewTranscript) {
|
if (isCallActive && !hasShownVoiceSeparator) {
|
||||||
const transcriptMessages = getTranscriptAsMessages();
|
// Will show separator on first voice message
|
||||||
if (transcriptMessages.length > 0) {
|
} else if (!isCallActive) {
|
||||||
// Add a separator message
|
setHasShownVoiceSeparator(false);
|
||||||
const separatorMessage: Message = {
|
|
||||||
id: `voice-separator-${Date.now()}`,
|
|
||||||
role: 'assistant',
|
|
||||||
content: '--- Voice Call Transcript ---',
|
|
||||||
timestamp: new Date(),
|
|
||||||
isSystem: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
setMessages(prev => [...prev, separatorMessage, ...transcriptMessages]);
|
|
||||||
markTranscriptAsShown();
|
|
||||||
|
|
||||||
// Scroll to bottom
|
|
||||||
setTimeout(() => {
|
|
||||||
flatListRef.current?.scrollToEnd({ animated: true });
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
}
|
}, [isCallActive]);
|
||||||
}, [hasNewTranscript, getTranscriptAsMessages, markTranscriptAsShown]);
|
|
||||||
const [input, setInput] = useState('');
|
const [input, setInput] = useState('');
|
||||||
const [isSending, setIsSending] = useState(false);
|
const [isSending, setIsSending] = useState(false);
|
||||||
const flatListRef = useRef<FlatList>(null);
|
const flatListRef = useRef<FlatList>(null);
|
||||||
@ -559,10 +546,42 @@ export default function ChatScreen() {
|
|||||||
endVoiceCallContext();
|
endVoiceCallContext();
|
||||||
}, [endVoiceCallContext]);
|
}, [endVoiceCallContext]);
|
||||||
|
|
||||||
// Handle voice transcript entries
|
// Handle voice transcript entries - add to chat in real-time
|
||||||
const handleVoiceTranscript = useCallback((role: 'user' | 'assistant', text: string) => {
|
const handleVoiceTranscript = useCallback((role: 'user' | 'assistant', text: string) => {
|
||||||
|
if (!text.trim()) return;
|
||||||
|
|
||||||
|
// Add separator before first voice message of this call
|
||||||
|
if (!hasShownVoiceSeparator) {
|
||||||
|
const separatorMessage: Message = {
|
||||||
|
id: `voice-separator-${Date.now()}`,
|
||||||
|
role: 'assistant',
|
||||||
|
content: 'Voice Call',
|
||||||
|
timestamp: new Date(),
|
||||||
|
isSystem: true,
|
||||||
|
};
|
||||||
|
setMessages(prev => [...prev, separatorMessage]);
|
||||||
|
setHasShownVoiceSeparator(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create voice message and add to chat immediately
|
||||||
|
const voiceMessage: Message = {
|
||||||
|
id: `voice-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
||||||
|
role,
|
||||||
|
content: text.trim(),
|
||||||
|
timestamp: new Date(),
|
||||||
|
isVoice: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
setMessages(prev => [...prev, voiceMessage]);
|
||||||
|
|
||||||
|
// Scroll to bottom
|
||||||
|
setTimeout(() => {
|
||||||
|
flatListRef.current?.scrollToEnd({ animated: true });
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
// Also store in transcript context for persistence
|
||||||
addTranscriptEntry(role, text);
|
addTranscriptEntry(role, text);
|
||||||
}, [addTranscriptEntry]);
|
}, [hasShownVoiceSeparator, addTranscriptEntry]);
|
||||||
|
|
||||||
// Cached API token for WellNuo
|
// Cached API token for WellNuo
|
||||||
const apiTokenRef = useRef<string | null>(null);
|
const apiTokenRef = useRef<string | null>(null);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user