Redirect user from call page when not in call
When a user tries to access a call page while not in a call, redirect the user to the home page.
Misc changes:
- Add route state to the call route that includes the CallStatus.
- CallProvider redirects to home if the callStatus isn't set (meaning
the user isn't in a call).
- Remove `beginCall` function in `ConversationProvider`. Added `useStartCall` hook that redirects the user to the call page. The `CallProvider` automatically sends the `BeginCall` message when the user reaches the page for the first time.
- Reorder functions in CallProvider to have `useEffect` functions at the top
GitLab: #164
Change-Id: I6cec1b9f31cb308d92a69112f5b38d1bdf79e05f
diff --git a/client/src/contexts/CallProvider.tsx b/client/src/contexts/CallProvider.tsx
index a17e738..de2a6d7 100644
--- a/client/src/contexts/CallProvider.tsx
+++ b/client/src/contexts/CallProvider.tsx
@@ -29,6 +29,7 @@
export type CallRole = 'caller' | 'receiver';
export enum CallStatus {
+ Default,
Ringing,
Connecting,
InCall,
@@ -65,7 +66,7 @@
isVideoOn: false,
setVideoStatus: () => {},
callRole: 'caller',
- callStatus: CallStatus.Ringing,
+ callStatus: CallStatus.Default,
acceptCall: () => {},
};
@@ -75,6 +76,7 @@
export default ({ children }: WithChildren) => {
const {
queryParams: { role: callRole },
+ state: routeState,
} = useUrlParams<CallRouteParams>();
const webSocket = useContext(WebSocketContext);
const { webRtcConnection, remoteStreams, sendWebRtcOffer, isConnected } = useContext(WebRtcContext);
@@ -87,9 +89,11 @@
const [isAudioOn, setIsAudioOn] = useState(false);
const [isVideoOn, setIsVideoOn] = useState(false);
- const [callStatus, setCallStatus] = useState(CallStatus.Ringing);
+ const [callStatus, setCallStatus] = useState(routeState?.callStatus);
- // TODO: This logic will have to change to support multiple people in a call
+ // TODO: This logic will have to change to support multiple people in a call. Could we move this logic to the server?
+ // The client could make a single request with the conversationId, and the server would be tasked with sending
+ // all the individual requests to the members of the conversation.
const contactUri = useMemo(() => conversation.getFirstMember().contact.getUri(), [conversation]);
useEffect(() => {
@@ -140,35 +144,22 @@
}
}, [localStream, webRtcConnection]);
- const setAudioStatus = useCallback(
- (isOn: boolean) => {
- if (!localStream) {
- return;
- }
+ useEffect(() => {
+ if (!webSocket) {
+ return;
+ }
- for (const track of localStream.getAudioTracks()) {
- track.enabled = isOn;
- }
+ if (callRole === 'caller' && callStatus === CallStatus.Default) {
+ const callBegin: CallAction = {
+ contactId: contactUri,
+ conversationId,
+ };
- setIsAudioOn(isOn);
- },
- [localStream]
- );
-
- const setVideoStatus = useCallback(
- (isOn: boolean) => {
- if (!localStream) {
- return;
- }
-
- for (const track of localStream.getVideoTracks()) {
- track.enabled = isOn;
- }
-
- setIsVideoOn(isOn);
- },
- [localStream]
- );
+ console.info('Sending CallBegin', callBegin);
+ webSocket.send(WebSocketMessageType.CallBegin, callBegin);
+ setCallStatus(CallStatus.Ringing);
+ }
+ }, [webSocket, callRole, callStatus, contactUri, conversationId]);
useEffect(() => {
if (!webSocket || !webRtcConnection) {
@@ -220,8 +211,38 @@
setCallStatus(CallStatus.Connecting);
}, [webSocket, contactUri, conversationId]);
- if (!callRole) {
- console.error('Call role not defined. Redirecting...');
+ const setAudioStatus = useCallback(
+ (isOn: boolean) => {
+ if (!localStream) {
+ return;
+ }
+
+ for (const track of localStream.getAudioTracks()) {
+ track.enabled = isOn;
+ }
+
+ setIsAudioOn(isOn);
+ },
+ [localStream]
+ );
+
+ const setVideoStatus = useCallback(
+ (isOn: boolean) => {
+ if (!localStream) {
+ return;
+ }
+
+ for (const track of localStream.getVideoTracks()) {
+ track.enabled = isOn;
+ }
+
+ setIsVideoOn(isOn);
+ },
+ [localStream]
+ );
+
+ if (!callRole || callStatus === undefined) {
+ console.error('Invalid route. Redirecting...');
return <Navigate to={'/'} />;
}
diff --git a/client/src/contexts/ConversationProvider.tsx b/client/src/contexts/ConversationProvider.tsx
index a282664..7d09881 100644
--- a/client/src/contexts/ConversationProvider.tsx
+++ b/client/src/contexts/ConversationProvider.tsx
@@ -15,9 +15,8 @@
* License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
-import { CallAction, Conversation, ConversationView, WebSocketMessageType } from 'jami-web-common';
-import { createContext, useCallback, useContext, useEffect, useState } from 'react';
-import { useNavigate } from 'react-router-dom';
+import { Conversation, ConversationView, WebSocketMessageType } from 'jami-web-common';
+import { createContext, useContext, useEffect, useState } from 'react';
import LoadingPage from '../components/Loading';
import { useUrlParams } from '../hooks/useUrlParams';
@@ -30,8 +29,6 @@
interface IConversationProvider {
conversationId: string;
conversation: Conversation;
-
- beginCall: () => void;
}
export const ConversationContext = createContext<IConversationProvider>(undefined!);
@@ -45,9 +42,8 @@
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
const [conversation, setConversation] = useState<Conversation | undefined>();
- const navigate = useNavigate();
- const conversationQuery = useConversationQuery(conversationId);
+ const conversationQuery = useConversationQuery(conversationId!);
useEffect(() => {
if (conversationQuery.isSuccess) {
@@ -64,28 +60,8 @@
setIsError(conversationQuery.isError);
}, [conversationQuery.isError]);
- const beginCall = useCallback(() => {
- if (!webSocket || !conversation) {
- throw new Error('Could not begin call');
- }
-
- // TODO: Could we move this logic to the server? The client could make a single request with the conversationId,
- // and the server is tasked with sending all the individual requests to the members of the conversation
- for (const member of conversation.getMembers()) {
- const callBegin: CallAction = {
- contactId: member.contact.getUri(),
- conversationId,
- };
-
- console.info('Sending CallBegin', callBegin);
- webSocket.send(WebSocketMessageType.CallBegin, callBegin);
- }
-
- navigate(`/conversation/${conversationId}/call?role=caller`);
- }, [conversationId, webSocket, conversation, navigate]);
-
useEffect(() => {
- if (!conversation || !webSocket) {
+ if (!conversation || !conversationId || !webSocket) {
return;
}
@@ -108,7 +84,6 @@
value={{
conversationId,
conversation,
- beginCall,
}}
>
{children}