@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
JavaScript
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