Stop voice session when app goes to background

User feedback: voice session should stop when leaving app or locking screen.

Previously:
- App goes to background → session stays active (broken state)
- STT/TTS cannot work in background anyway
- Wasted battery, confusing UX

Now:
- background/inactive → automatically stops session
- Cleans up all state (STT, refs, pending transcripts)
- User must manually restart via FAB when returning

Behavior:
User locks screen → session stops → FAB becomes gray
User switches app → session stops → clean state
User returns → must press FAB to start new session

app/(tabs)/_layout.tsx:238-256
This commit is contained in:
Sergei 2026-01-28 20:10:23 -08:00
parent 8a6d9fa420
commit 4bcb1f70c5

View File

@ -238,19 +238,27 @@ export default function TabLayout() {
// Handle app state changes (background/foreground)
useEffect(() => {
const handleAppStateChange = (nextAppState: AppStateStatus) => {
if (nextAppState === 'active' && sessionActiveRef.current) {
setTimeout(() => {
if (sessionActiveRef.current && !sttIsListening && status !== 'processing' && status !== 'speaking') {
console.log('[TabLayout] App foregrounded - restarting STT');
safeStartSTT();
}
}, 500);
// When app goes to background/inactive - stop voice session
// STT/TTS cannot work in background, so it's pointless to keep session active
if ((nextAppState === 'background' || nextAppState === 'inactive') && sessionActiveRef.current) {
console.log('[TabLayout] App going to background - stopping voice session');
stopListening();
stopSession();
sessionActiveRef.current = false;
shouldRestartSTTRef.current = false;
pendingInterruptTranscriptRef.current = null;
}
// When app comes back to foreground - do NOT auto-restart session
// User must manually press FAB to start new session
if (nextAppState === 'active') {
console.log('[TabLayout] App foregrounded - session remains stopped (user must restart via FAB)');
}
};
const subscription = AppState.addEventListener('change', handleAppStateChange);
return () => subscription.remove();
}, [sttIsListening, status, safeStartSTT]);
}, [stopListening, stopSession]);
// Handle voice FAB press - toggle listening mode
// Must check ALL active states (listening, processing, speaking), not just isListening