11import { t } from 'i18next' ;
2- import { Audio , InterruptionModeIOS } from 'expo-av' ;
32import { Headphones , Mic , MicOff , PhoneOff , Settings } from 'lucide-react-native' ;
43import { useColorScheme } from 'nativewind' ;
54import React , { useCallback , useEffect , useRef , useState } from 'react' ;
@@ -12,7 +11,7 @@ import { useBluetoothAudioStore } from '@/stores/app/bluetooth-audio-store';
1211
1312import { Card } from '../../components/ui/card' ;
1413import { Text } from '../../components/ui/text' ;
15- import { useLiveKitStore } from '../../stores/app/livekit-store' ;
14+ import { applyAudioRouting , useLiveKitStore } from '../../stores/app/livekit-store' ;
1615import { AudioDeviceSelection } from '../settings/audio-device-selection' ;
1716import { Actionsheet , ActionsheetBackdrop , ActionsheetContent , ActionsheetDragIndicator , ActionsheetDragIndicatorWrapper } from '../ui/actionsheet' ;
1817import { HStack } from '../ui/hstack' ;
@@ -33,6 +32,7 @@ export const LiveKitBottomSheet = () => {
3332 const { trackEvent } = useAnalytics ( ) ;
3433
3534 const [ currentView , setCurrentView ] = useState < BottomSheetView > ( BottomSheetView . ROOM_SELECT ) ;
35+ const [ previousView , setPreviousView ] = useState < BottomSheetView | null > ( null ) ;
3636 const [ isMuted , setIsMuted ] = useState ( true ) ; // Default to muted
3737 const [ permissionsRequested , setPermissionsRequested ] = useState ( false ) ;
3838
@@ -156,28 +156,17 @@ export const LiveKitBottomSheet = () => {
156156 const speaker = selectedAudioDevices . speaker ;
157157 console . log ( 'Updating audio routing for:' , speaker . type ) ;
158158
159+ let targetType : 'bluetooth' | 'speaker' | 'earpiece' | 'default' = 'default' ;
160+
159161 if ( speaker . type === 'speaker' ) {
160- // Force Speakerphone
161- await Audio . setAudioModeAsync ( {
162- allowsRecordingIOS : true ,
163- staysActiveInBackground : true ,
164- playsInSilentModeIOS : true ,
165- shouldDuckAndroid : true ,
166- playThroughEarpieceAndroid : false , // This forces speaker on Android
167- interruptionModeIOS : InterruptionModeIOS . DoNotMix ,
168- } ) ;
162+ targetType = 'speaker' ;
163+ } else if ( speaker . type === 'bluetooth' ) {
164+ targetType = 'bluetooth' ;
169165 } else {
170- // Default (Earpiece) or Bluetooth
171- // For Bluetooth to work, we usually just need to NOT force speaker.
172- await Audio . setAudioModeAsync ( {
173- allowsRecordingIOS : true ,
174- staysActiveInBackground : true ,
175- playsInSilentModeIOS : true ,
176- shouldDuckAndroid : true ,
177- playThroughEarpieceAndroid : true , // This allows earpiece/bluetooth
178- interruptionModeIOS : InterruptionModeIOS . DoNotMix ,
179- } ) ;
166+ targetType = 'earpiece' ;
180167 }
168+
169+ await applyAudioRouting ( targetType ) ;
181170 } catch ( error ) {
182171 console . error ( 'Failed to update audio routing:' , error ) ;
183172 }
@@ -221,12 +210,18 @@ export const LiveKitBottomSheet = () => {
221210 } , [ disconnectFromRoom ] ) ;
222211
223212 const handleShowAudioSettings = useCallback ( ( ) => {
213+ setPreviousView ( currentView ) ;
224214 setCurrentView ( BottomSheetView . AUDIO_SETTINGS ) ;
225- } , [ ] ) ;
215+ } , [ currentView ] ) ;
226216
227217 const handleBackFromAudioSettings = useCallback ( ( ) => {
228- setCurrentView ( BottomSheetView . CONNECTED ) ;
229- } , [ ] ) ;
218+ if ( previousView ) {
219+ setCurrentView ( previousView ) ;
220+ setPreviousView ( null ) ;
221+ } else {
222+ setCurrentView ( isConnected && currentRoomInfo ? BottomSheetView . CONNECTED : BottomSheetView . ROOM_SELECT ) ;
223+ }
224+ } , [ previousView , isConnected , currentRoomInfo ] ) ;
230225
231226 const renderRoomSelect = ( ) => (
232227 < View style = { styles . content } >
0 commit comments