UNPKG

mediasfu-reactnative-expo

Version:

mediasfu-reactnative-expo – Expo-managed React Native WebRTC SDK for video conferencing, webinars, live streaming, broadcast, screen sharing, whiteboard, chat, recording, live subtitles, translation, and AI agent rooms on iOS, Android, and web. Prebuilt r

283 lines (278 loc) 9.96 kB
// WaitingRoomModal.tsx import React, { useEffect, useState } from "react"; import { Modal, View, Text, Pressable, StyleSheet, ScrollView, TextInput, Dimensions, } from "react-native"; import { FontAwesome } from "@expo/vector-icons"; import { getModalBodyTheme } from "../../components_modern/core/modalBodyTheme"; import { getModalPosition } from "../../methods/utils/getModalPosition"; import { respondToWaiting, } from "../../methods/waitingMethods/respondToWaiting"; /** * WaitingRoomModal is a React Native functional component that displays a modal containing a list of participants who are waiting to join a room. Users can filter, accept, or reject participants from the waiting list. * * @component * @param {WaitingRoomModalOptions} props - The properties for the WaitingRoomModal component. * @returns {JSX.Element} The rendered WaitingRoomModal component. * * @example * ```tsx * import React from 'react'; * import { WaitingRoomModal } from 'mediasfu-reactnative-expo'; * * function App() { * const waitingRoomList = [ * { id: 1, name: 'John Doe' }, * { id: 2, name: 'Jane Smith' }, * ]; * * const handleWaitingRoomItemPress = ({ participantId, type }) => { * console.log(`Participant ID ${participantId} was ${type ? 'accepted' : 'rejected'}`); * }; * * return ( * <WaitingRoomModal * isWaitingModalVisible={true} * onWaitingRoomClose={() => console.log('Modal closed')} * waitingRoomCounter={waitingRoomList.length} * onWaitingRoomFilterChange={(filter) => console.log('Filter applied:', filter)} * waitingRoomList={waitingRoomList} * updateWaitingList={(updatedList) => console.log('Updated list:', updatedList)} * roomName="Main Room" * socket={socketInstance} * onWaitingRoomItemPress={handleWaitingRoomItemPress} * backgroundColor="#83c0e9" * position="topRight" * parameters={{ * getUpdatedAllParams: () => ({ filteredWaitingRoomList: waitingRoomList }), * }} * /> * ); * } * export default App; * ``` */ const WaitingRoomModal = ({ isWaitingModalVisible, onWaitingRoomClose, waitingRoomCounter, onWaitingRoomFilterChange, waitingRoomList, updateWaitingList, roomName, socket, onWaitingRoomItemPress = respondToWaiting, position = "topRight", backgroundColor = "#83c0e9", isDarkMode, parameters, style, renderContent, renderContainer, }) => { const screenWidth = Dimensions.get("window").width; let modalWidth = 0.8 * screenWidth; if (modalWidth > 400) { modalWidth = 400; } const [filteredWaitingRoomList, setFilteredWaitingRoomList] = useState(waitingRoomList); const [waitingRoomCounter_s, setWaitingRoomCounter_s] = useState(waitingRoomCounter); const [filterText, setFilterText] = useState(""); useEffect(() => { if (!isWaitingModalVisible) { return; } const { getUpdatedAllParams } = parameters; const updatedParams = getUpdatedAllParams(); setFilteredWaitingRoomList(updatedParams.filteredWaitingRoomList); setWaitingRoomCounter_s(updatedParams.filteredWaitingRoomList.length); }, [isWaitingModalVisible, waitingRoomList, parameters]); if (!isWaitingModalVisible) { return null; } const dimensions = { width: modalWidth, height: 0 }; const theme = getModalBodyTheme(isDarkMode); const shouldUseModernTheme = typeof isDarkMode === "boolean"; const defaultContent = (<> {/* Header */} <View style={styles.modalHeader}> <Text style={[styles.modalTitle, { color: theme.textColor }]}> Waiting <Text style={[styles.badge, { backgroundColor: theme.badgeBackgroundColor, color: theme.badgeTextColor }]}>{waitingRoomCounter_s}</Text> </Text> <Pressable onPress={onWaitingRoomClose} style={styles.closeButton}> <FontAwesome name="times" size={24} color={theme.iconColor}/> </Pressable> </View> <View style={[styles.separator, { backgroundColor: theme.dividerColor }]}/> {/* Search Input */} <View style={styles.modalBody}> <View style={styles.formGroup}> <TextInput style={[ styles.input, { backgroundColor: theme.inputBackgroundColor, borderColor: theme.borderColor, color: theme.inputTextColor, }, ]} placeholder="Search ..." placeholderTextColor={theme.placeholderTextColor} value={filterText} onChangeText={(text) => { setFilterText(text); onWaitingRoomFilterChange(text); }}/> </View> {/* Waiting List */} <ScrollView style={styles.scrollView}> <View> {filteredWaitingRoomList && filteredWaitingRoomList.length > 0 ? (filteredWaitingRoomList.map((participant, index) => (<View key={index} style={[styles.waitingItem, { borderBottomColor: theme.dividerColor }]}> <View style={styles.participantName}> <Text style={[styles.participantText, { color: theme.textColor }]}> {participant.name} </Text> </View> <View style={styles.actionButtons}> {/* Accept Button */} <Pressable style={styles.acceptButton} onPress={() => onWaitingRoomItemPress({ participantId: participant.id, participantName: participant.name, updateWaitingList, waitingList: waitingRoomList, roomName, type: true, // accepted socket, })}> <FontAwesome name="check" size={24} color={theme.successColor}/> </Pressable> {/* Reject Button */} <Pressable style={styles.rejectButton} onPress={() => onWaitingRoomItemPress({ participantId: participant.id, participantName: participant.name, updateWaitingList, waitingList: waitingRoomList, roomName, type: false, // rejected socket, })}> <FontAwesome name="times" size={24} color={theme.dangerColor}/> </Pressable> </View> </View>))) : (<Text style={[styles.noParticipantsText, { color: theme.mutedTextColor }]}> No participants found. </Text>)} </View> </ScrollView> </View> </>); const content = renderContent ? renderContent({ defaultContent, dimensions }) : defaultContent; const defaultContainer = (<Modal transparent animationType="fade" visible={isWaitingModalVisible} onRequestClose={onWaitingRoomClose}> <View style={[styles.modalContainer, getModalPosition({ position }), shouldUseModernTheme ? { borderColor: theme.borderColor } : null]}> <View style={[ styles.modalContent, { backgroundColor, width: modalWidth }, shouldUseModernTheme ? { borderColor: theme.borderColor } : null, style, ]}> {content} </View> </View> </Modal>); return renderContainer ? renderContainer({ defaultContainer, dimensions }) : defaultContainer; }; export default WaitingRoomModal; /** * Stylesheet for the WaitingRoomModal component. */ const styles = StyleSheet.create({ modalContainer: { flex: 1, justifyContent: "flex-end", alignItems: "flex-end", zIndex: 9, elevation: 9, borderWidth: 2, borderColor: "black", }, modalContent: { height: "65%", backgroundColor: "#83c0e9", borderRadius: 10, padding: 15, maxHeight: "80%", shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 4, zIndex: 9, elevation: 9, borderWidth: 2, borderColor: "black", }, modalHeader: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", marginBottom: 15, }, modalTitle: { fontSize: 18, fontWeight: "bold", color: "black", flexDirection: "row", alignItems: "center", }, badge: { backgroundColor: "#fff", color: "#000", borderRadius: 12, paddingHorizontal: 5, paddingVertical: 2, marginLeft: 5, fontSize: 14, }, modalBody: { flex: 1, }, closeButton: { padding: 5, marginRight: 10, }, separator: { height: 1, backgroundColor: "#000000", marginVertical: 10, }, formGroup: { marginBottom: 15, }, input: { height: 40, borderColor: "gray", borderWidth: 1, borderRadius: 5, paddingLeft: 10, fontSize: 16, color: "black", }, scrollView: { flexGrow: 1, maxHeight: "100%", maxWidth: "100%", }, waitingItem: { flexDirection: "row", alignItems: "center", marginVertical: 5, paddingVertical: 10, borderBottomWidth: 1, borderBottomColor: "#ddd", }, participantName: { flex: 5, }, participantText: { fontSize: 16, color: "black", }, actionButtons: { flex: 2, flexDirection: "row", justifyContent: "space-around", alignItems: "center", }, acceptButton: { padding: 5, }, rejectButton: { padding: 5, }, noParticipantsText: { textAlign: "center", color: "gray", fontSize: 16, marginTop: 20, }, }); //# sourceMappingURL=WaitingModal.js.map