UNPKG

mediasfu-reactnative

Version:
422 lines (413 loc) 16.8 kB
// AdvancedPanelComponent.tsx import React, { useEffect, useState } from 'react'; import { View, Text, Pressable, StyleSheet, TextInput, Modal, } from 'react-native'; import RNPickerSelect from 'react-native-picker-select'; import ColorPicker, { Panel1, Swatches, Preview, OpacitySlider, HueSlider, } from 'reanimated-color-picker'; /** * AdvancedPanelComponent provides an interface for users to configure advanced recording options such as video type, display settings, background color, custom text, name tags, and video orientation. * * @component * @param {AdvancedPanelOptions} props - The properties object. * @returns {JSX.Element} The rendered AdvancedPanelComponent. * * @example * ```tsx * import React from 'react'; * import { AdvancedPanelComponent } from 'mediasfu-reactnative'; * * const advancedParameters = { * recordingVideoType: 'fullDisplay', * recordingDisplayType: 'video', * recordingBackgroundColor: '#ffffff', * recordingNameTagsColor: '#000000', * recordingOrientationVideo: 'landscape', * recordingNameTags: true, * recordingAddText: false, * recordingCustomText: '', * recordingCustomTextPosition: 'top', * recordingCustomTextColor: '#000000', * updateRecordingVideoType: (value) => { }, * updateRecordingDisplayType: (value) => { }, * updateRecordingBackgroundColor: (value) => { }, * updateRecordingNameTagsColor: (value) => { }, * updateRecordingOrientationVideo: (value) => { }, * updateRecordingNameTags: (value) => { }, * updateRecordingAddText: (value) => { }, * updateRecordingCustomText: (value) => { }, * updateRecordingCustomTextPosition: (value) => { }, * updateRecordingCustomTextColor: (value) => { }, * eventType: 'conference', * }; * * function App() { * return <AdvancedPanelComponent parameters={advancedParameters} />; * } * * export default App; * ``` */ const AdvancedPanelComponent = ({ parameters, }) => { const { recordingVideoType, recordingDisplayType, recordingBackgroundColor, recordingNameTagsColor, recordingOrientationVideo, recordingNameTags, recordingAddText, recordingCustomText, recordingCustomTextPosition, recordingCustomTextColor, updateRecordingVideoType, updateRecordingDisplayType, updateRecordingBackgroundColor, updateRecordingNameTagsColor, updateRecordingOrientationVideo, updateRecordingNameTags, updateRecordingAddText, updateRecordingCustomText, updateRecordingCustomTextPosition, updateRecordingCustomTextColor, eventType, } = parameters; // State for selected orientation video const [selectedOrientationVideo, setSelectedOrientationVideo] = useState(recordingOrientationVideo); // State for color picker modal visibility const [showBackgroundColorModal, setShowBackgroundColorModal] = useState(false); const [showNameTagsColorModal, setShowNameTagsColorModal] = useState(false); const [showCustomTextColorModal, setShowCustomTextColorModal] = useState(false); // State for selected color type (background color or name tags color) const [selectedColorType, setSelectedColorType] = useState(''); // Recording text state const [recordingText, setRecordingText] = useState(recordingAddText); const [customText, setCustomText] = useState(recordingCustomText); /** * Validates the text input against the specified regex. * * @param input - The text input to validate. * @returns {boolean} Whether the input is valid. */ const validateTextInput = (input) => { const regex = /^[a-zA-Z0-9\s]{1,40}$/; return regex.test(input); }; /** * Handles text input changes for custom text. * * @param text - The new text input. */ const onChangeTextHandler = (text) => { if (text.length === 0 || validateTextInput(text)) { updateRecordingCustomText(text); setCustomText(text); } }; useEffect(() => { setSelectedOrientationVideo(recordingOrientationVideo); }, [recordingOrientationVideo]); /** * Handles color selection from the color picker. * * @param {Object} param0 - The selected color object. * @param {string} param0.hex - The hexadecimal color code. */ const onSelectColor = ({ hex }) => { handleColorChange(hex); }; /** * Updates the corresponding color based on the selected color type. * * @param color - The selected hexadecimal color code. */ const handleColorChange = (color) => { switch (selectedColorType) { case 'backgroundColor': updateRecordingBackgroundColor(color); break; case 'customTextColor': updateRecordingCustomTextColor(color); break; case 'nameTagsColor': updateRecordingNameTagsColor(color); break; default: break; } }; /** * Toggles the color picker modal based on the color type. * * @param colorType - The type of color being selected. */ const toggleColorPicker = (colorType) => { setSelectedColorType(colorType); if (colorType === 'backgroundColor') { setShowBackgroundColorModal(true); setShowNameTagsColorModal(false); setShowCustomTextColorModal(false); } else if (colorType === 'customTextColor') { setShowCustomTextColorModal(true); setShowBackgroundColorModal(false); setShowNameTagsColorModal(false); } else if (colorType === 'nameTagsColor') { setShowNameTagsColorModal(true); setShowBackgroundColorModal(false); setShowCustomTextColorModal(false); } }; /** * Handles changes to the "Add Text" option. * * @param value - The new value for the "Add Text" option. */ const handleTextChange = (value) => { setRecordingText(value); updateRecordingAddText(value); }; return (<View> {/* Video Type */} <View style={styles.formGroup}> <Text style={styles.label}>Video Type:</Text> <RNPickerSelect style={pickerSelectStyles} value={recordingVideoType} onValueChange={(value) => updateRecordingVideoType(value)} items={[ { label: 'Full Display (no background)', value: 'fullDisplay' }, { label: 'Full Video', value: 'bestDisplay' }, { label: 'All', value: 'all' }, ]} placeholder={{}} useNativeAndroidPickerStyle={false}/> </View> <View style={styles.separator}/> {/* Display Type */} {eventType !== 'broadcast' && (<View style={styles.formGroup}> <Text style={styles.label}>Display Type:</Text> <RNPickerSelect style={pickerSelectStyles} value={recordingDisplayType} onValueChange={(value) => updateRecordingDisplayType(value)} items={[ { label: 'Only Video Participants', value: 'video' }, { label: 'Only Video Participants (optimized)', value: 'videoOpt', }, { label: 'Participants with media', value: 'media' }, { label: 'All Participants', value: 'all' }, ]} placeholder={{}} useNativeAndroidPickerStyle={false}/> </View>)} <View style={styles.separator}/> {/* Background Color */} <View style={styles.formGroup}> <Text style={styles.label}>Background Color:</Text> <Pressable onPress={() => toggleColorPicker('backgroundColor')} style={[ styles.colorPreview, { backgroundColor: recordingBackgroundColor }, ]}> <Text style={styles.colorText}>{recordingBackgroundColor}</Text> </Pressable> {/* Color Picker Modal for Background Color */} <Modal visible={showBackgroundColorModal} animationType="slide" transparent onRequestClose={() => setShowBackgroundColorModal(false)}> <View style={styles.modalContainer}> <View style={styles.modalContent}> {/* Color Picker Component */} <ColorPicker style={{ width: '100%', height: '70%' }} value={recordingBackgroundColor} onComplete={onSelectColor}> <Preview /> <Panel1 /> <HueSlider /> <OpacitySlider /> <Swatches /> <Pressable onPress={() => setShowBackgroundColorModal(false)} style={styles.closePickerButton}> <Text style={styles.closePickerButtonText}>Done</Text> </Pressable> </ColorPicker> </View> </View> </Modal> </View> <View style={styles.separator}/> {/* Add Text */} <View style={styles.formGroup}> <Text style={styles.label}>Add Text:</Text> <RNPickerSelect style={pickerSelectStyles} value={recordingText} onValueChange={(value) => handleTextChange(value)} items={[ { label: 'True', value: true }, { label: 'False', value: false }, ]} placeholder={{}} useNativeAndroidPickerStyle={false}/> </View> <View style={styles.separator}/> {/* Custom Text */} {recordingText && (<View style={styles.formGroup}> <Text style={styles.label}>Custom Text:</Text> <TextInput style={styles.input} value={customText} onChangeText={onChangeTextHandler} placeholder="Enter custom text" maxLength={40}/> </View>)} {recordingText && <View style={styles.separator}/>} {/* Custom Text Position */} {recordingText && (<View style={styles.formGroup}> <Text style={styles.label}>Custom Text Position:</Text> <RNPickerSelect style={pickerSelectStyles} value={recordingCustomTextPosition} onValueChange={(value) => updateRecordingCustomTextPosition(value)} items={[ { label: 'Top', value: 'top' }, { label: 'Middle', value: 'middle' }, { label: 'Bottom', value: 'bottom' }, ]} placeholder={{}} useNativeAndroidPickerStyle={false}/> </View>)} {recordingText && <View style={styles.separator}/>} {/* Custom Text Color */} {recordingText && (<View style={styles.formGroup}> <Text style={styles.label}>Custom Text Color:</Text> <Pressable onPress={() => toggleColorPicker('customTextColor')} style={[ styles.colorPreview, { backgroundColor: recordingCustomTextColor }, ]}> <Text style={styles.colorText}>{recordingCustomTextColor}</Text> </Pressable> {/* Color Picker Modal for Custom Text Color */} <Modal visible={showCustomTextColorModal} animationType="slide" transparent onRequestClose={() => setShowCustomTextColorModal(false)}> <View style={styles.modalContainer}> <View style={styles.modalContent}> {/* Color Picker Component */} <ColorPicker style={{ width: '100%', height: '70%' }} value={recordingCustomTextColor} onComplete={onSelectColor}> <Preview /> <Panel1 /> <HueSlider /> <OpacitySlider /> <Swatches /> </ColorPicker> <Pressable onPress={() => setShowCustomTextColorModal(false)} style={styles.closePickerButton}> <Text style={styles.closePickerButtonText}>Done</Text> </Pressable> </View> </View> </Modal> </View>)} {recordingText && <View style={styles.separator}/>} {/* Add Name Tags */} <View style={styles.formGroup}> <Text style={styles.label}>Add Name Tags:</Text> <RNPickerSelect style={pickerSelectStyles} value={recordingNameTags} onValueChange={(value) => updateRecordingNameTags(value)} items={[ { label: 'True', value: true }, { label: 'False', value: false }, ]} placeholder={{}} useNativeAndroidPickerStyle={false}/> </View> <View style={styles.separator}/> {/* Name Tags Color */} <View style={styles.formGroup}> <Text style={styles.label}>Name Tags Color:</Text> <Pressable onPress={() => toggleColorPicker('nameTagsColor')} style={[ styles.colorPreview, { backgroundColor: recordingNameTagsColor }, ]}> <Text style={styles.colorText}>{recordingNameTagsColor}</Text> </Pressable> {/* Color Picker Modal for Name Tags Color */} <Modal visible={showNameTagsColorModal} animationType="slide" transparent onRequestClose={() => setShowNameTagsColorModal(false)}> <View style={styles.modalContainer}> <View style={styles.modalContent}> {/* Color Picker Component */} <ColorPicker style={{ width: '100%', height: '70%' }} value={recordingNameTagsColor} onComplete={onSelectColor}> <Preview /> <Panel1 /> <HueSlider /> <OpacitySlider /> <Swatches /> </ColorPicker> <Pressable onPress={() => setShowNameTagsColorModal(false)} style={styles.closePickerButton}> <Text style={styles.closePickerButtonText}>Done</Text> </Pressable> </View> </View> </Modal> </View> <View style={styles.separator}/> {/* Orientation (Video) */} <View style={styles.formGroup}> <Text style={styles.label}>Orientation (Video):</Text> <RNPickerSelect style={pickerSelectStyles} value={selectedOrientationVideo} onValueChange={(value) => { updateRecordingOrientationVideo(value); setSelectedOrientationVideo(value); }} items={[ { label: 'Landscape', value: 'landscape' }, { label: 'Portrait', value: 'portrait' }, { label: 'All', value: 'all' }, ]} placeholder={{}} useNativeAndroidPickerStyle={false}/> </View> </View>); }; export default AdvancedPanelComponent; /** * Stylesheet for the AdvancedPanelComponent. */ const styles = StyleSheet.create({ formGroup: { marginBottom: 10, }, label: { color: 'black', marginBottom: 5, fontWeight: 'bold', }, input: { height: 30, borderColor: 'black', borderWidth: 1, borderRadius: 5, padding: 5, fontSize: 16, marginBottom: 10, width: '100%', }, colorPreview: { width: '100%', height: 30, borderRadius: 5, justifyContent: 'center', alignItems: 'center', borderColor: 'black', borderWidth: 1, position: 'relative', }, colorText: { color: 'white', fontWeight: 'bold', }, separator: { height: 1, backgroundColor: 'black', marginVertical: 10, }, modalContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, backgroundColor: 'rgba(0,0,0,0.5)', // Semi-transparent background }, modalContent: { width: '80%', padding: 20, backgroundColor: 'white', borderRadius: 10, alignItems: 'center', }, closePickerButton: { marginTop: 5, backgroundColor: '#4CAF50', paddingVertical: 10, paddingHorizontal: 10, borderRadius: 5, }, closePickerButtonText: { color: 'white', fontWeight: 'bold', textAlign: 'center', }, }); /** * Styles for the RNPickerSelect component. */ const pickerSelectStyles = StyleSheet.create({ inputIOS: { fontSize: 16, paddingVertical: 4, paddingHorizontal: 10, borderWidth: 1, borderColor: 'gray', borderRadius: 5, color: 'black', paddingRight: 30, // To ensure the text is never behind the icon }, inputAndroid: { fontSize: 16, paddingHorizontal: 10, paddingVertical: 4, borderWidth: 0.5, borderColor: 'gray', borderRadius: 5, color: 'black', paddingRight: 30, // To ensure the text is never behind the icon }, inputWeb: { fontSize: 14, paddingHorizontal: 10, 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=AdvancedPanelComponent.js.map