UNPKG

@100mslive/react-native-room-kit

Version:

100ms Room Kit provides simple & easy to use UI components to build Live Streaming & Video Conferencing experiences in your apps.

314 lines (309 loc) 11.9 kB
import * as React from 'react'; import { Platform, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import Toast from 'react-native-simple-toast'; import { useSelector } from 'react-redux'; import { HMSUpdateListenerActions, HMSAudioDevice } from '@100mslive/react-native-hms'; import { AnswerPhoneIcon, BluetoothIcon, CheckIcon, HeadphonesIcon, SpeakerIcon, WaveIcon } from '../Icons'; import { PressableIcon } from './PressableIcon'; import { useHMSInstance, useHMSRoomStyleSheet, useIsHLSViewer } from '../hooks-util'; import { BottomSheet } from './BottomSheet'; import { TestIds } from '../utils/constants'; import { useHMSActions } from '../hooks-sdk'; export const HMSManageAudioOutput = () => { const hmsInstance = useHMSInstance(); const isHLSViewer = useIsHLSViewer(); const [settingsModalVisible, setSettingsModalVisible] = React.useState(false); const { setRoomMuteLocally } = useHMSActions(); const [currentAudioOutputDevice, setCurrentAudioOutputDevice] = React.useState(null); const [availableAudioOutputDevices, setAvailableAudioOutputDevices] = React.useState([]); const debugMode = useSelector(state => state.user.debugMode); const roomLocallyMuted = useSelector(state => state.hmsStates.roomLocallyMuted); // Fetch current selected audio device and audio devices list on Android React.useEffect(() => { if (Platform.OS === 'android') { let ignore = false; const getCurrentAudioOutputDevice = async () => { const device = await hmsInstance.getAudioOutputRouteType(); if (!ignore) { setCurrentAudioOutputDevice(device); } }; const getAvailableAudioOutputDevices = async () => { const devices = await hmsInstance.getAudioDevicesList(); if (!ignore) { setAvailableAudioOutputDevices(devices); } }; getCurrentAudioOutputDevice(); getAvailableAudioOutputDevices(); return () => { ignore = true; }; } }, [hmsInstance]); // closes modal and no action will be taken after modal has been closed const dismissModal = () => { setSettingsModalVisible(false); }; // Handles showing Modal for changing Audio device const handleSpeakerChange = () => { if (Platform.OS === 'android' && availableAudioOutputDevices.length === 0) { hmsInstance.getAudioDevicesList().then(devices => setAvailableAudioOutputDevices(devices)); // TODO(set-state-after-unmount): setting state irrespective of component unmount check } setSettingsModalVisible(true); }; // Add audio device change listeners React.useEffect(() => { if (Platform.OS === 'android') { let ignore = false; hmsInstance.setAudioDeviceChangeListener(data => { if (!ignore && data) { setCurrentAudioOutputDevice(data.device); } if (debugMode) { Toast.showWithGravity(`Audio Device Output changed to: ${data === null || data === void 0 ? void 0 : data.device}`, Toast.LONG, Toast.TOP); } }); return () => { ignore = true; hmsInstance.removeEventListener(HMSUpdateListenerActions.ON_AUDIO_DEVICE_CHANGED); }; } }, [hmsInstance, debugMode]); // Handle changing selected audio device const handleSelectAudioDevice = device => { if (device === 'mute-audio') { setRoomMuteLocally(true); } else { if (roomLocallyMuted) { setRoomMuteLocally(false); } if (device === 'ios-audio-device') { hmsInstance.switchAudioOutputUsingIOSUI(); } else { hmsInstance.switchAudioOutput(device); } } setSettingsModalVisible(false); }; const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ text: { color: theme.palette.on_surface_high, fontFamily: `${typography.font_family}-SemiBold` } })); return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(PressableIcon, { testID: TestIds.manage_audio_output, onPress: handleSpeakerChange, style: isHLSViewer ? styles.button : null }, roomLocallyMuted ? /*#__PURE__*/React.createElement(SpeakerIcon, { muted: true }) : Platform.OS === 'ios' ? /*#__PURE__*/React.createElement(SpeakerIcon, { muted: false }) : getIcon(currentAudioOutputDevice || HMSAudioDevice.AUTOMATIC)), /*#__PURE__*/React.createElement(BottomSheet, { isVisible: settingsModalVisible, dismissModal: dismissModal }, /*#__PURE__*/React.createElement(BottomSheet.Header, { dismissModal: dismissModal, heading: "Audio Output", headingTestID: TestIds.audio_modal_heading, closeIconTestID: TestIds.audio_modal_close_btn }), /*#__PURE__*/React.createElement(BottomSheet.Divider, null), /*#__PURE__*/React.createElement(View, { style: styles.contentContainer }, Platform.OS === 'ios' ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(AudioOutputDevice, { id: 'ios-audio-device', hideDivider: true, selected: false, text: 'Auto', icon: /*#__PURE__*/React.createElement(SpeakerIcon, { muted: false }), onPress: handleSelectAudioDevice, checkTestID: TestIds.automatic_audio_device_active, textTestID: TestIds.automatic_audio_device_text, buttonTestID: TestIds.automatic_audio_device_btn }), /*#__PURE__*/React.createElement(AudioOutputDevice, { id: 'mute-audio', hideDivider: false, selected: roomLocallyMuted, text: 'Mute Audio', icon: /*#__PURE__*/React.createElement(SpeakerIcon, { muted: true }), onPress: handleSelectAudioDevice, checkTestID: TestIds.mute_audio_active, textTestID: TestIds.mute_audio_text, buttonTestID: TestIds.mute_audio_btn })) : availableAudioOutputDevices.length === 0 ? /*#__PURE__*/React.createElement(View, { style: styles.emptyView }, /*#__PURE__*/React.createElement(Text, { testID: TestIds.audio_modal_empty_text, style: [styles.itemText, hmsRoomStyles.text] }, "No other devices available!")) : /*#__PURE__*/React.createElement(ScrollView, { showsVerticalScrollIndicator: true }, availableAudioOutputDevices.sort((a, b) => audioDeviceSortOrder[a] - audioDeviceSortOrder[b]).map((device, index) => { const isFirst = index === 0; return /*#__PURE__*/React.createElement(AudioOutputDevice, { key: device, id: device, hideDivider: isFirst, selected: device === currentAudioOutputDevice && !roomLocallyMuted, checkTestID: activeAudioDeviceTestIds[device], text: getDescription(device, currentAudioOutputDevice), textTestID: audioDeviceTextTestIds[device], icon: getIcon(device === HMSAudioDevice.AUTOMATIC && currentAudioOutputDevice ? currentAudioOutputDevice : device), buttonTestID: audioDeviceTestIds[device], onPress: handleSelectAudioDevice }); }), /*#__PURE__*/React.createElement(AudioOutputDevice, { id: 'mute-audio', hideDivider: false, selected: roomLocallyMuted, text: 'Mute Audio', icon: /*#__PURE__*/React.createElement(SpeakerIcon, { muted: true }), onPress: handleSelectAudioDevice, checkTestID: TestIds.mute_audio_active, textTestID: TestIds.mute_audio_text, buttonTestID: TestIds.mute_audio_btn }))))); }; const AudioOutputDevice = props => { const { id, hideDivider, selected, checkTestID, text, textTestID, icon, buttonTestID, onPress } = props; const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ text: { color: selected ? theme.palette.primary_bright : theme.palette.on_surface_high, fontFamily: `${typography.font_family}-SemiBold` }, divider: { backgroundColor: theme.palette.border_default }, checkIcon: { tintColor: theme.palette.primary_bright } }), [selected]); return /*#__PURE__*/React.createElement(React.Fragment, null, hideDivider ? null : /*#__PURE__*/React.createElement(View, { style: [styles.divider, hmsRoomStyles.divider] }), /*#__PURE__*/React.createElement(TouchableOpacity, { testID: buttonTestID, disabled: selected, style: styles.audioDeviceItem, onPress: () => onPress(id) }, /*#__PURE__*/React.createElement(View, { style: styles.itemTextWrapper }, icon ? /*#__PURE__*/React.cloneElement(icon, { style: selected ? hmsRoomStyles.checkIcon : null }) : null, /*#__PURE__*/React.createElement(Text, { testID: textTestID, style: [styles.itemText, hmsRoomStyles.text] }, text)), selected ? /*#__PURE__*/React.createElement(CheckIcon, { testID: checkTestID, style: hmsRoomStyles.checkIcon }) : null)); }; const styles = StyleSheet.create({ button: { backgroundColor: 'transparent', borderWidth: 1 }, contentContainer: { marginHorizontal: 24 }, itemTextWrapper: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }, itemText: { marginHorizontal: 16, fontSize: 14, lineHeight: 20, letterSpacing: 0.1 }, emptyView: { height: 160, alignItems: 'center', justifyContent: 'center' }, audioDeviceItem: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingVertical: 20 }, divider: { height: 1 } }); const getIcon = ofDevice => { switch (ofDevice) { case HMSAudioDevice.AUTOMATIC: return /*#__PURE__*/React.createElement(WaveIcon, null); case HMSAudioDevice.BLUETOOTH: return /*#__PURE__*/React.createElement(BluetoothIcon, null); case HMSAudioDevice.EARPIECE: return /*#__PURE__*/React.createElement(AnswerPhoneIcon, null); case HMSAudioDevice.SPEAKER_PHONE: return /*#__PURE__*/React.createElement(SpeakerIcon, { muted: false }); case HMSAudioDevice.WIRED_HEADSET: return /*#__PURE__*/React.createElement(HeadphonesIcon, null); } }; const getDescription = (ofDevice, currentDevice) => { switch (ofDevice) { case HMSAudioDevice.AUTOMATIC: return currentDevice && currentDevice !== HMSAudioDevice.AUTOMATIC ? `Default (${getDescription(currentDevice, currentDevice)})` : 'Automatic'; case HMSAudioDevice.BLUETOOTH: return 'Bluetooth Device'; case HMSAudioDevice.EARPIECE: return 'Phone'; case HMSAudioDevice.SPEAKER_PHONE: return 'Speaker'; case HMSAudioDevice.WIRED_HEADSET: return 'Earphone'; } }; const audioDeviceSortOrder = { [HMSAudioDevice.AUTOMATIC]: 0, [HMSAudioDevice.SPEAKER_PHONE]: 1, [HMSAudioDevice.WIRED_HEADSET]: 2, [HMSAudioDevice.EARPIECE]: 3, [HMSAudioDevice.BLUETOOTH]: 4 }; const audioDeviceTestIds = { [HMSAudioDevice.AUTOMATIC]: TestIds.automatic_audio_device_btn, [HMSAudioDevice.SPEAKER_PHONE]: TestIds.phone_speaker_audio_device_btn, [HMSAudioDevice.WIRED_HEADSET]: TestIds.wired_headset_audio_device_btn, [HMSAudioDevice.EARPIECE]: TestIds.earpiece_audio_device_btn, [HMSAudioDevice.BLUETOOTH]: TestIds.bluetooth_audio_device_btn }; const audioDeviceTextTestIds = { [HMSAudioDevice.AUTOMATIC]: TestIds.automatic_audio_device_text, [HMSAudioDevice.SPEAKER_PHONE]: TestIds.phone_speaker_audio_device_text, [HMSAudioDevice.WIRED_HEADSET]: TestIds.wired_headset_audio_device_text, [HMSAudioDevice.EARPIECE]: TestIds.earpiece_audio_device_text, [HMSAudioDevice.BLUETOOTH]: TestIds.bluetooth_audio_device_text }; const activeAudioDeviceTestIds = { [HMSAudioDevice.AUTOMATIC]: TestIds.automatic_audio_device_active, [HMSAudioDevice.SPEAKER_PHONE]: TestIds.phone_speaker_audio_device_active, [HMSAudioDevice.WIRED_HEADSET]: TestIds.wired_headset_audio_device_active, [HMSAudioDevice.EARPIECE]: TestIds.earpiece_audio_device_active, [HMSAudioDevice.BLUETOOTH]: TestIds.bluetooth_audio_device_active }; //# sourceMappingURL=HMSManageAudioOutput.js.map