Skip to content

Instantly share code, notes, and snippets.

@hieptl
Created October 18, 2021 15:50
Show Gist options
  • Save hieptl/2dd7c0836d152bd7020784c7f0b3f401 to your computer and use it in GitHub Desktop.
Save hieptl/2dd7c0836d152bd7020784c7f0b3f401 to your computer and use it in GitHub Desktop.
App.tsx - Calling Feature - Ionic Chat App
...
const App: React.FC<any> = () => {
const callListenerId = useRef(uuidv4());
const [isLoading, setIsLoading] = useState(false);
const [cometChat, setCometChat] = useState<any>(null);
const [user, setUser] = useState<any>(null);
const [selectedConversation, setSelectedConversation] = useState<any>(null);
const [callType, setCallType] = useState<any>(null);
const [callSettings, setCallSettings] = useState<any>(null);
const [call, setCall] = useState<any>(null);
const [isSomeoneCalling, setIsSomeoneCalling] = useState<any>(false);
useEffect(() => {
initCometChat();
...
return () => {
setCallType(null);
setCall(null);
setCallSettings(null);
setIsSomeoneCalling(false);
cometChat.removeCallListener(callListenerId);
}
}, []);
useEffect(() => {
if (cometChat) {
listenForCall();
}
}, [cometChat]);
useEffect(() => {
if (callType && selectedConversation) {
initialCall();
}
}, [callType]);
useEffect(() => {
if (callSettings) {
console.log('call settings: ');
console.log(callSettings);
cometChat.startCall(callSettings);
}
}, [callSettings]);
const rejectCall = (status: any, call: any) => {
if (status && call) {
cometChat.rejectCall(call.sessionId, status).then(
(call: any) => {
console.log("Call rejected successfully", call);
setCallSettings(null);
setCallType(null);
setCall(null);
setIsSomeoneCalling(false);
},
(error: any) => {
console.log("Call rejection failed with error:", error);
}
);
}
};
const startCall = (call: any) => {
const sessionId = call.sessionId;
const callType = call.type;
const callListener = new cometChat.OngoingCallListener({
onUserJoined: (user: any) => {
/* Notification received here if another user joins the call. */
console.log("User joined call:", user);
/* this method can be use to display message or perform any actions if someone joining the call */
},
onUserLeft: (user: any) => {
/* Notification received here if another user left the call. */
console.log("User left call:", user);
/* this method can be use to display message or perform any actions if someone leaving the call */
},
onUserListUpdated: (userList: any) => {
console.log("user list:", userList);
},
onCallEnded: (call: any) => {
/* Notification received here if current ongoing call is ended. */
console.log("Call ended:", call);
/* hiding/closing the call screen can be done here. */
const status = cometChat.CALL_STATUS.CANCELLED;
rejectCall(status, call.sessionId);
setCallSettings(null);
setCallType(null);
setCall(null);
setIsSomeoneCalling(false);
},
onError: (error: any) => {
console.log("Error :", error);
/* hiding/closing the call screen can be done here. */
setCallSettings(null);
setCallType(null);
setCall(null);
setIsSomeoneCalling(false);
},
onAudioModesUpdated: (audioModes: any) => {
console.log("audio modes:", audioModes);
},
});
const callSettings = new cometChat.CallSettingsBuilder()
.setSessionID(sessionId)
.enableDefaultLayout(true)
.setIsAudioOnlyCall(callType == cometChat.CALL_TYPE.AUDIO ? true : false)
.setCallEventListener(callListener)
.build();
setCallSettings(() => callSettings);
};
const acceptCall = (call: any) => {
if (call) {
cometChat.acceptCall(call.sessionId).then(
(call: any) => {
console.log("Call accepted successfully:", call);
// start the call using the startCall() method
startCall(call);
setIsSomeoneCalling(false);
},
(error: any) => {
console.log("Call acceptance failed with error", error);
// handle exception
}
);
}
};
const confirmCall = (call: any) => {
if (call) {
setIsSomeoneCalling(true);
}
};
const listenForCall = () => {
cometChat.addCallListener(
callListenerId,
new cometChat.CallListener({
onIncomingCallReceived(call: any) {
console.log("Incoming call:", call);
const callInitiatorUid = call.callInitiator.uid;
const authenticatedUser: any = localStorage.getItem('auth');
const parsedAuthenticatedUser = JSON.parse(authenticatedUser);
if (callInitiatorUid && callInitiatorUid !== parsedAuthenticatedUser.uid) {
setCall(call);
confirmCall(call);
}
},
onOutgoingCallAccepted(call: any) {
console.log("Outgoing call accepted:", call);
startCall(call);
},
onOutgoingCallRejected(call: any) {
console.log("Outgoing call rejected:", call);
setCallSettings(null);
setCallType(null);
setCall(null);
setIsSomeoneCalling(null);
},
onIncomingCallCancelled(call: any) {
console.log("Incoming call calcelled:", call);
setCallSettings(null);
setCallType(null);
setCall(null);
setIsSomeoneCalling(null);
}
})
);
};
const isGroup = () => {
return selectedConversation && selectedConversation.guid;
};
const initialCall = () => {
const receiverID = isGroup() ? selectedConversation.guid : selectedConversation.uid;
const receiverType = isGroup() ? cometChat.RECEIVER_TYPE.GROUP : cometChat.RECEIVER_TYPE.USER;
const call = new cometChat.Call(receiverID, callType, receiverType);
cometChat.initiateCall(call).then(
(outGoingCall: any) => {
console.log("Call initiated successfully:", outGoingCall);
setCall(outGoingCall);
// perform action on success. Like show your calling screen.
},
(error: any) => {
console.log("Call initialization failed with exception:", error);
}
);
};
const cancelCall = () => {
console.log('cancelCall was called');
const status = cometChat.CALL_STATUS.CANCELLED;
rejectCall(status, call);
};
const handleRejectCall = () => {
const status = cometChat.CALL_STATUS.REJECTED;
rejectCall(status, call);
};
const handleAcceptCall = () => {
acceptCall(call);
};
...
if (callType && selectedConversation && !callSettings) {
return (
<div className='calling__container'>
<p>Calling {selectedConversation?.name}...</p>
<div>
<img src={selectedConversation?.avatar} />
</div>
<div className='calling__cancel-btn' onClick={cancelCall}>Cancel Call</div>
</div>
);
}
if (isSomeoneCalling) {
return (
<div className='calling__container'>
<p>You are having a call from {call?.sender.name}</p>
<div>
<img src={call?.sender.avatar} />
</div>
<div className='calling__accept-btn' onClick={handleAcceptCall}>Accept Call</div>
<div className='calling__cancel-btn' onClick={handleRejectCall}>Reject Call</div>
</div>
);
}
return (
<Context.Provider value={{ cometChat, user, setUser, isLoading, setIsLoading, selectedConversation, setSelectedConversation, setCallType }}>
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<PrivateRoute exact path="/" component={Home} />
<PrivateRoute exact path="/chat" component={Chat} />
<PrivateRoute exact path="/create-group" component={CreateGroup} />
<PrivateRoute exact path="/manage-group" component={ManageGroup} />
<PrivateRoute exact path="/add-group-members" component={AddGroupMembers} />
<PrivateRoute exact path="/remove-group-members" component={RemoveGroupMembers} />
{/* Login Route */}
<Route exact path="/login" component={Login} />
{/* End Login Route */}
{/* Sign Up Route */}
<Route exact path="/signup" component={SignUp} />
{/* End Sign Up Route */}
</IonRouterOutlet>
</IonReactRouter>
<IonLoading
isOpen={isLoading}
message={'Please wait...'}
/>
</IonApp>
</Context.Provider>
);
};
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment