UNPKG

mediasfu-reactnative

Version:
291 lines (281 loc) 10.3 kB
// DisplaySettingsModal.tsx import React, { useState } from 'react'; import { Modal, View, Text, Pressable, StyleSheet, Dimensions, } from 'react-native'; import FontAwesome from 'react-native-vector-icons/FontAwesome'; import RNPickerSelect from 'react-native-picker-select'; // Install using: npm install react-native-picker-select import { modifyDisplaySettings, } from '../../methods/displaySettingsMethods/modifyDisplaySettings'; /** * DisplaySettingsModal provides an interface to manage and save various display settings in a modal. * * @param {DisplaySettingsModalOptions} props - The configuration options for the DisplaySettingsModal component. * * @example * ```tsx * import React, { useState } from 'react'; * import { DisplaySettingsModal } from 'mediasfu-reactnative'; * * function App() { * const [isModalVisible, setModalVisible] = useState(false); * * return ( * <View> * <Button title="Open Display Settings" onPress={() => setModalVisible(true)} /> * <DisplaySettingsModal * isDisplaySettingsModalVisible={isModalVisible} * onDisplaySettingsClose={() => setModalVisible(false)} * parameters={{ * meetingDisplayType: 'video', * autoWave: true, * forceFullDisplay: false, * meetingVideoOptimized: false, * getUpdatedAllParams: () => ({}), // Function to fetch the latest parameters * }} * position="topRight" * backgroundColor="#83c0e9" * /> * </View> * ); * } * * export default App; * ``` */ const DisplaySettingsModal = ({ isDisplaySettingsModalVisible, onDisplaySettingsClose, onModifyDisplaySettings = modifyDisplaySettings, parameters, position = 'topRight', backgroundColor = '#83c0e9', }) => { const { meetingDisplayType, autoWave, forceFullDisplay, meetingVideoOptimized, } = parameters; const [meetingDisplayTypeState, setMeetingDisplayTypeState] = useState(meetingDisplayType); const [autoWaveState, setAutoWaveState] = useState(autoWave); const [forceFullDisplayState, setForceFullDisplayState] = useState(forceFullDisplay); const [meetingVideoOptimizedState, setMeetingVideoOptimizedState] = useState(meetingVideoOptimized); const screenWidth = Dimensions.get('window').width; let modalWidth = 0.8 * screenWidth; if (modalWidth > 400) { modalWidth = 400; } /** * Handles saving the modified display settings. */ const handleSaveSettings = async () => { await onModifyDisplaySettings({ parameters: Object.assign(Object.assign({}, parameters), { meetingDisplayType: meetingDisplayTypeState, autoWave: autoWaveState, forceFullDisplay: forceFullDisplayState, meetingVideoOptimized: meetingVideoOptimizedState }), }); onDisplaySettingsClose(); // Close modal after saving }; /** * Determines the alignment style based on the 'position' prop. * * @param {string} pos - The position string ('topRight', 'topLeft', 'bottomRight', 'bottomLeft'). * @returns {StyleProp<ViewStyle>} - The corresponding alignment style. */ const getModalPosition = (pos) => { const styles = { topRight: { justifyContent: 'flex-start', alignItems: 'flex-end', }, topLeft: { justifyContent: 'flex-start', alignItems: 'flex-start', }, bottomRight: { justifyContent: 'flex-end', alignItems: 'flex-end', }, bottomLeft: { justifyContent: 'flex-end', alignItems: 'flex-start', }, }; return styles[pos] || styles.topRight; }; return (<Modal transparent animationType="fade" visible={isDisplaySettingsModalVisible} onRequestClose={onDisplaySettingsClose}> <View style={[styles.modalContainer, getModalPosition(position)]}> <View style={[styles.modalContent, { backgroundColor, width: modalWidth }]}> {/* Header */} <View style={styles.modalHeader}> <Text style={styles.modalTitle}>Display Settings</Text> <Pressable onPress={onDisplaySettingsClose} style={styles.btnCloseSettings} accessibilityRole="button" accessibilityLabel="Close Display Settings"> <FontAwesome name="times" style={styles.icon}/> </Pressable> </View> {/* Divider */} <View style={styles.hr}/> {/* Body */} <View style={styles.modalBody}> {/* Display Option Picker */} <View style={styles.formGroup}> <Text style={styles.label}>Display Option:</Text> <RNPickerSelect onValueChange={(value) => setMeetingDisplayTypeState(value)} items={[ { label: 'Video Participants Only', value: 'video' }, { label: 'Media Participants Only', value: 'media' }, { label: 'Show All Participants', value: 'all' }, ]} value={meetingDisplayTypeState} style={pickerSelectStyles} placeholder={{}} useNativeAndroidPickerStyle={false}/> </View> {/* Separator */} <View style={styles.sep}/> {/* Display Audiographs Toggle */} <View style={styles.formCheck}> <Text style={styles.label}>Display Audiographs</Text> <Pressable onPress={() => setAutoWaveState(!autoWaveState)} accessibilityRole="switch" accessibilityLabel="Toggle Display Audiographs"> <FontAwesome name="check" size={24} color={autoWaveState ? 'green' : 'black'}/> </Pressable> </View> {/* Separator */} <View style={styles.sep}/> {/* Force Full Display Toggle */} <View style={styles.formCheck}> <Text style={styles.label}>Force Full Display</Text> <Pressable onPress={() => setForceFullDisplayState(!forceFullDisplayState)} accessibilityRole="switch" accessibilityLabel="Toggle Force Full Display"> <FontAwesome name="check" size={24} color={forceFullDisplayState ? 'green' : 'black'}/> </Pressable> </View> {/* Separator */} <View style={styles.sep}/> {/* Force Video Participants Toggle */} <View style={styles.formCheck}> <Text style={styles.label}>Force Video Participants</Text> <Pressable onPress={() => setMeetingVideoOptimizedState(!meetingVideoOptimizedState)} accessibilityRole="switch" accessibilityLabel="Toggle Force Video Participants"> <FontAwesome name="check" size={24} color={meetingVideoOptimizedState ? 'green' : 'black'}/> </Pressable> </View> {/* Separator */} <View style={styles.sep}/> </View> {/* Footer */} <View style={styles.modalFooter}> <Pressable onPress={handleSaveSettings} style={styles.btnApplySettings} accessibilityRole="button" accessibilityLabel="Save Display Settings"> <Text style={styles.btnText}>Save</Text> </Pressable> </View> </View> </View> </Modal>); }; export default DisplaySettingsModal; /** * Stylesheet for the DisplaySettingsModal component. */ const styles = StyleSheet.create({ modalContainer: { flex: 1, justifyContent: 'flex-end', alignItems: 'flex-end', zIndex: 9, elevation: 9, }, modalContent: { height: '65%', backgroundColor: '#83c0e9', borderRadius: 0, padding: 20, maxHeight: '65%', maxWidth: '70%', zIndex: 9, elevation: 9, borderWidth: 2, borderColor: 'black', borderStyle: 'solid', }, modalHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 15, }, modalTitle: { fontSize: 18, fontWeight: 'bold', color: 'black', }, btnCloseSettings: { padding: 5, }, icon: { fontSize: 24, color: 'black', }, hr: { height: 1, backgroundColor: 'black', marginVertical: 5, }, modalBody: { flex: 1, }, formGroup: { marginBottom: 10, }, label: { fontSize: 14, color: 'black', marginBottom: 5, fontWeight: 'bold', }, formCheck: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10, }, sep: { height: 1, backgroundColor: '#ffffff', marginVertical: 2, }, modalFooter: { marginTop: 10, flexDirection: 'row', justifyContent: 'flex-end', }, btnApplySettings: { flex: 1, padding: 5, borderRadius: 5, justifyContent: 'center', alignItems: 'center', backgroundColor: 'black', }, btnText: { color: 'white', fontSize: 14, }, }); /** * Stylesheet for the RNPickerSelect component. */ const pickerSelectStyles = StyleSheet.create({ inputIOS: { fontSize: 16, paddingVertical: 4, paddingHorizontal: 10, borderWidth: 1, borderColor: 'gray', borderRadius: 4, color: 'black', paddingRight: 30, // To ensure the text is never behind the icon backgroundColor: 'white', }, inputAndroid: { fontSize: 16, paddingHorizontal: 10, paddingVertical: 4, borderWidth: 0.5, borderColor: 'purple', borderRadius: 8, color: 'black', paddingRight: 30, // To ensure the text is never behind the icon backgroundColor: 'white', }, inputWeb: { fontSize: 14, paddingHorizontal: 5, paddingVertical: 1, borderWidth: 0.5, borderColor: 'purple', borderRadius: 8, color: 'black', paddingRight: 30, // To ensure the text is never behind the icon backgroundColor: 'white', marginBottom: 10, }, }); //# sourceMappingURL=DisplaySettingsModal.js.map