Fix voice command status transitions and UI bugs
Fixed multiple issues with voice command workflow: **Status Transition Fixes:** - Fixed infinite loop in status update useEffect by checking if status actually needs to change - Status now properly transitions: listening → understanding → review/close - Added debug logging to track status changes **UI Bug Fixes:** - Fixed crash in diaper tracker when conditions field is undefined (voice-created activities) - Auto-close dialog when classification returns "unknown" type - Added optional chaining for conditions.join() in getDiaperDetails **Changes:** - VoiceFloatingButton: Prevent setting same status repeatedly - VoiceFloatingButton: Close dialog on unknown classification - Diaper page: Handle missing conditions field gracefully 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -331,9 +331,12 @@ export default function DiaperTrackPage() {
|
|||||||
const getDiaperDetails = (activity: Activity) => {
|
const getDiaperDetails = (activity: Activity) => {
|
||||||
const data = activity.data as DiaperData;
|
const data = activity.data as DiaperData;
|
||||||
const typeLabel = data.diaperType.charAt(0).toUpperCase() + data.diaperType.slice(1);
|
const typeLabel = data.diaperType.charAt(0).toUpperCase() + data.diaperType.slice(1);
|
||||||
const conditionsLabel = data.conditions.join(', ');
|
const conditionsLabel = data.conditions?.join(', ') || '';
|
||||||
|
|
||||||
let details = `${typeLabel} - ${conditionsLabel}`;
|
let details = typeLabel;
|
||||||
|
if (conditionsLabel) {
|
||||||
|
details += ` - ${conditionsLabel}`;
|
||||||
|
}
|
||||||
|
|
||||||
if (data.hasRash) {
|
if (data.hasRash) {
|
||||||
details += ` - Rash (${data.rashSeverity})`;
|
details += ` - Rash (${data.rashSeverity})`;
|
||||||
|
|||||||
@@ -60,13 +60,17 @@ export function VoiceFloatingButton() {
|
|||||||
|
|
||||||
// Set status when listening starts/stops
|
// Set status when listening starts/stops
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isListening) {
|
console.log('[VoiceFloatingButton] isListening changed:', isListening, 'processingStatus:', processingStatus);
|
||||||
|
|
||||||
|
if (isListening && processingStatus !== 'listening') {
|
||||||
|
console.log('[VoiceFloatingButton] Setting status to listening');
|
||||||
setProcessingStatus('listening');
|
setProcessingStatus('listening');
|
||||||
} else if (processingStatus === 'listening' && transcript) {
|
} else if (!isListening && processingStatus === 'listening') {
|
||||||
// Transition from listening to understanding when we have a transcript
|
// When listening stops, transition to understanding
|
||||||
|
console.log('[VoiceFloatingButton] Setting status to understanding');
|
||||||
setProcessingStatus('understanding');
|
setProcessingStatus('understanding');
|
||||||
}
|
}
|
||||||
}, [isListening, transcript]);
|
}, [isListening, processingStatus]);
|
||||||
|
|
||||||
// Auto-use classification from backend when transcription completes
|
// Auto-use classification from backend when transcription completes
|
||||||
// MediaRecorder sends audio to backend, which transcribes + classifies in one call
|
// MediaRecorder sends audio to backend, which transcribes + classifies in one call
|
||||||
@@ -87,8 +91,9 @@ export function VoiceFloatingButton() {
|
|||||||
setProcessingStatus(null);
|
setProcessingStatus(null);
|
||||||
setShowReview(true);
|
setShowReview(true);
|
||||||
} else {
|
} else {
|
||||||
// For unknown or low confidence, show error
|
// For unknown or low confidence, show error and close dialog
|
||||||
setProcessingStatus(null);
|
setProcessingStatus(null);
|
||||||
|
setOpen(false);
|
||||||
setSnackbar({
|
setSnackbar({
|
||||||
open: true,
|
open: true,
|
||||||
message: 'Could not understand the command. Please try again or use manual entry.',
|
message: 'Could not understand the command. Please try again or use manual entry.',
|
||||||
|
|||||||
Reference in New Issue
Block a user