@cometchat/chat-uikit-react-native
Version:
Ready-to-use Chat UI Components for React Native
214 lines • 10.3 kB
JavaScript
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