UNPKG

@cometchat/chat-uikit-react-native

Version:

Ready-to-use Chat UI Components for React Native

214 lines 10.3 kB
import { CometChat } from "@cometchat/chat-sdk-react-native"; import React, { useEffect, useMemo, useRef, useState } from "react"; import { TouchableOpacity, View, } from "react-native"; import { CometChatUIKit } from "../../shared/CometChatUiKit/CometChatUIKit"; import { CallTypeConstants, MessageTypeConstants } from "../../shared/constants/UIKitConstants"; import { CometChatUIEventHandler } from "../../shared/events/CometChatUIEventHandler/CometChatUIEventHandler"; import { deepMerge } from "../../shared/helper/helperFunctions"; import { Icon } from "../../shared/icons/Icon"; import { getUnixTimestampInMilliseconds } from "../../shared/utils/CometChatMessageHelper"; import { permissionUtil } from "../../shared/utils/PermissionUtil"; import { useTheme } from "../../theme"; import { useCompTheme } from "../../theme/hook"; import { CallUIEvents } from "../CallEvents"; import { CometChatOutgoingCall } from "../CometChatOutgoingCall"; import { CallingPackage } from "../CallingPackage"; const CometChatCalls = CallingPackage.CometChatCalls; const listenerId = "callEventListener_" + new Date().getTime(); /** * CometChatCallButtons component. * * This component renders call action buttons (voice and video) and handles call initiation, * outgoing call screen, and call events. * * @param {CometChatCallButtonsInterface} props - Component properties. * @returns {JSX.Element} The rendered component. */ export const CometChatCallButtons = (props) => { const { user, group, hideVoiceCallButton = false, hideVideoCallButton = false, onError, callSettingsBuilder, outgoingCallConfiguration, style = {}, } = props; const theme = useTheme(); const compTheme = useCompTheme(); // Merge default and custom styles for call buttons const callButtonStyles = useMemo(() => { return deepMerge(theme.callButtonStyles, compTheme.callButtonStyles ?? {}, style); }, [theme, compTheme, style]); const [disableButton, setDisableButton] = useState(false); const [showOutgoingCallScreen, setShowOutgoingCallScreen] = useState(false); const [callReceived, setCallReceived] = useState(); const outGoingCall = useRef(undefined); const callType = useRef(undefined); const incomingCall = useRef(undefined); const loggedInUser = useRef(undefined); /** * Checks if there is an active call. * If found, opens the outgoing call screen and returns true. * Otherwise, returns false. * * @returns {boolean} Whether an active call exists. */ const checkActiveCallOnly = () => { return false; }; /** * Initiates a call based on the provided call type. * * @param {any} type - The type of call (audio or video). */ const makeCall = (type) => { if (type == CallTypeConstants.audio || type == CallTypeConstants.video) { var receiverID = user ? user.getUid() : group ? group.getGuid() : undefined; var callType = type; // For group calls, send a custom meeting message. if (group) { let customData = { callType: callType, sessionId: receiverID, }; let customMessage = new CometChat.CustomMessage(receiverID, CometChat.RECEIVER_TYPE.GROUP, MessageTypeConstants.meeting, customData); customMessage.setCategory(CometChat.CATEGORY_CUSTOM); customMessage.setMuid(String(getUnixTimestampInMilliseconds())); customMessage.setSender(loggedInUser.current); customMessage.setReceiver(group); customMessage.setMetadata({ ...customMessage.getMetadata(), incrementUnreadCount: true, pushNotification: MessageTypeConstants.meeting, }); customMessage.shouldUpdateConversation(true); customMessage.setMetadata({ incrementUnreadCount: true }); customMessage.setCustomData(customData); CometChatUIKit.sendCustomMessage(customMessage) .then((res) => { outGoingCall.current = res; setShowOutgoingCallScreen(true); CometChatUIEventHandler.emitCallEvent(CallUIEvents.ccOutgoingCall, { call: res }); }) .catch((rej) => { console.log("custom msg error", rej); onError && onError(rej); }); } else { var receiverType = user ? CometChat.RECEIVER_TYPE.USER : group ? CometChat.RECEIVER_TYPE.GROUP : undefined; if (!receiverID || !receiverType) return; var call = new CometChat.Call(receiverID, callType, receiverType, CometChat.CATEGORY_CALL); CometChat.initiateCall(call).then((initiatedCall) => { outGoingCall.current = initiatedCall; setDisableButton(true); setShowOutgoingCallScreen(true); CometChatUIEventHandler.emitCallEvent(CallUIEvents.ccOutgoingCall, { call: outGoingCall.current, }); }, (error) => { console.log("Call initialization failed with exception:", error); CometChatUIEventHandler.emitCallEvent(CallUIEvents.ccCallFailed, { call }); onError && onError(error); }); } } else { console.log("Invalid call type.", type, CallTypeConstants.audio, type != CallTypeConstants.audio || type != CallTypeConstants.video); return; } }; /** * Initiates a voice call. * * Checks for necessary permissions before making the call. */ const makeVoiceCall = async () => { if (disableButton) return; if (!(await permissionUtil.startResourceBasedTask(["mic"]))) { return; } callType.current = CallTypeConstants.audio; makeCall(CallTypeConstants.audio); }; /** * Initiates a video call. * * Checks for necessary permissions (mic and camera) before making the call. */ const makeVideoCall = async () => { if (disableButton) return; if (!(await permissionUtil.startResourceBasedTask(["mic", "camera"]))) { return; } callType.current = CallTypeConstants.video; makeCall(CallTypeConstants.video); }; // Set up event listeners and logged-in user on mount. useEffect(() => { CometChat.getLoggedinUser() .then((user) => (loggedInUser.current = user)) .catch((rej) => { onError && onError(rej); }); CometChat.addCallListener(listenerId, new CometChat.CallListener({ onIncomingCallReceived: (call) => { incomingCall.current = call; setDisableButton(true); setCallReceived(call); }, onOutgoingCallAccepted: (call) => { console.log("call accepted"); }, onOutgoingCallRejected: (call) => { setShowOutgoingCallScreen(false); outGoingCall.current = undefined; setDisableButton(false); }, onIncomingCallCancelled: (call) => { setCallReceived(undefined); incomingCall.current = undefined; setDisableButton(false); }, })); CometChatUIEventHandler.addCallListener(listenerId, { ccCallRejected: (call) => { outGoingCall.current = undefined; setShowOutgoingCallScreen(false); setDisableButton(false); }, ccCallEnded: () => { outGoingCall.current = undefined; setShowOutgoingCallScreen(false); setDisableButton(false); }, }); checkActiveCallOnly(); return () => { CometChat.removeCallListener(listenerId); CometChatUIEventHandler.removeCallListener(listenerId); }; }, []); return (<View style={callButtonStyles.containerStyle}> {!hideVoiceCallButton && (<TouchableOpacity onPress={() => makeVoiceCall()}> <Icon name='call' height={callButtonStyles?.audioCallButtonIconStyle?.height} width={callButtonStyles?.audioCallButtonIconStyle?.width} color={callButtonStyles?.audioCallButtonIconStyle?.tintColor} imageStyle={callButtonStyles?.audioCallButtonIconStyle} icon={callButtonStyles?.audioCallButtonIcon} containerStyle={callButtonStyles?.audioCallButtonIconContainerStyle}/> </TouchableOpacity>)} {!hideVideoCallButton && (<TouchableOpacity onPress={() => makeVideoCall()}> <Icon name='videocam' height={callButtonStyles?.videoCallButtonIconStyle?.height} width={callButtonStyles?.videoCallButtonIconStyle?.width} color={callButtonStyles?.videoCallButtonIconStyle?.tintColor} imageStyle={callButtonStyles?.videoCallButtonIconStyle} icon={callButtonStyles?.videoCallButtonIcon} containerStyle={callButtonStyles?.videoCallButtonIconContainerStyle}/> </TouchableOpacity>)} {showOutgoingCallScreen && (<CometChatOutgoingCall call={outGoingCall.current} onEndCallButtonPressed={(call) => { CometChat.rejectCall(call?.getSessionId(), CometChat.CALL_STATUS.CANCELLED).then((rejectedCall) => { CometChatUIEventHandler.emitCallEvent(CallUIEvents.ccCallRejected, { call: rejectedCall, }); }, (err) => { onError && onError(err); }); }} {...(callSettingsBuilder ? { callSettingsBuilder: callSettingsBuilder(props.user, props.group, callType.current == CallTypeConstants.audio ? true : false), } : {})} {...outgoingCallConfiguration}/>)} </View>); }; //# sourceMappingURL=CometChatCallButtons.js.map