Transform CallProvider into 'CallManager' hook, review WebSocket messages for calls
- These changes allowed to remove more cascading effects. It is now possible to reactivate StrictMode. Downside is we lost the 'optional context' of CallProvider: the call logic will be loaded even if there is no call.
- The WebSocket messages have been changed so the client does not have to know the conversation members before a call. Previously, the client had to fetch the conversation members for a call, which was causing cascading effects.
- Accidentally, moving the handling of conversation members to the server added some logic for calls with more than two participants, but it is still not ready to work.
* CallProvider.tsx will be renamed in next commit in order to make it easier to track its file history
Change-Id: Iae711009adafce065ac3defc1c91c7ca0f37898c
diff --git a/client/src/components/CallButtons.tsx b/client/src/components/CallButtons.tsx
index d853cc1..0ee463e 100644
--- a/client/src/components/CallButtons.tsx
+++ b/client/src/components/CallButtons.tsx
@@ -20,7 +20,8 @@
import { styled } from '@mui/material/styles';
import { ChangeEvent, useMemo } from 'react';
-import { CallStatus, useCallContext, VideoStatus } from '../contexts/CallProvider';
+import { useCallManagerContext } from '../contexts/CallManagerProvider';
+import { CallStatus, VideoStatus } from '../contexts/CallProvider';
import { useUserMediaContext } from '../contexts/UserMediaProvider';
import {
ColoredRoundButton,
@@ -58,7 +59,7 @@
});
export const CallingChatButton = (props: ExpandableButtonProps) => {
- const { setIsChatShown } = useCallContext();
+ const { setIsChatShown } = useCallManagerContext();
return (
<CallButton
aria-label="chat"
@@ -72,7 +73,7 @@
};
export const CallingEndButton = (props: ExpandableButtonProps) => {
- const { endCall } = useCallContext();
+ const { endCall } = useCallManagerContext();
return (
<ColoredRoundButton
paletteColor={(theme) => theme.palette.error}
@@ -91,7 +92,7 @@
};
export const CallingFullScreenButton = (props: ExpandableButtonProps) => {
- const { setIsFullscreen } = useCallContext();
+ const { setIsFullscreen } = useCallManagerContext();
return (
<CallButton
aria-label="full screen"
@@ -123,7 +124,7 @@
};
const ToggleScreenShareIconButton = (props: IconButtonProps) => {
- const { videoStatus, updateVideoStatus } = useCallContext();
+ const { videoStatus, updateVideoStatus } = useCallManagerContext();
return (
<ToggleIconButton
@@ -194,7 +195,7 @@
};
const ToggleAudioCameraIconButton = (props: IconButtonProps) => {
- const { isAudioOn, setIsAudioOn } = useCallContext();
+ const { isAudioOn, setIsAudioOn } = useCallManagerContext();
return (
<ToggleIconButton
IconOn={MicroIcon}
@@ -220,7 +221,7 @@
};
const ToggleVideoCameraIconButton = (props: IconButtonProps) => {
- const { videoStatus, updateVideoStatus } = useCallContext();
+ const { videoStatus, updateVideoStatus } = useCallManagerContext();
return (
<ToggleIconButton
IconOn={VideoCameraIcon}
@@ -236,7 +237,7 @@
// Calling pending/receiving interface
export const CallingCancelButton = (props: IconButtonProps) => {
- const { endCall } = useCallContext();
+ const { endCall } = useCallManagerContext();
return (
<ColoredRoundButton
@@ -252,7 +253,7 @@
};
export const CallingAnswerAudioButton = (props: IconButtonProps) => {
- const { acceptCall, callStatus } = useCallContext();
+ const { acceptCall, callStatus } = useCallManagerContext();
return (
<ColoredRoundButton
@@ -269,7 +270,7 @@
};
export const CallingAnswerVideoButton = (props: IconButtonProps) => {
- const { acceptCall, callStatus } = useCallContext();
+ const { acceptCall, callStatus } = useCallManagerContext();
return (
<ColoredRoundButton
disabled={callStatus === CallStatus.Connecting || callStatus === CallStatus.Loading}
@@ -285,7 +286,7 @@
};
export const CallingRefuseButton = (props: IconButtonProps) => {
- const { endCall } = useCallContext();
+ const { endCall } = useCallManagerContext();
return (
<ColoredRoundButton
aria-label="refuse call"
diff --git a/client/src/components/CallChatDrawer.tsx b/client/src/components/CallChatDrawer.tsx
index d094554..4a58393 100644
--- a/client/src/components/CallChatDrawer.tsx
+++ b/client/src/components/CallChatDrawer.tsx
@@ -17,7 +17,7 @@
*/
import { Divider, Stack, Typography } from '@mui/material';
-import { useCallContext } from '../contexts/CallProvider';
+import { useCallManagerContext } from '../contexts/CallManagerProvider';
import { useConversationContext } from '../contexts/ConversationProvider';
import ChatInterface from '../pages/ChatInterface';
import { CloseButton } from './Button';
@@ -43,7 +43,7 @@
};
const CallChatDrawerHeader = () => {
- const { setIsChatShown } = useCallContext();
+ const { setIsChatShown } = useCallManagerContext();
const { conversationDisplayName } = useConversationContext();
return (
diff --git a/client/src/components/ConversationSummaryList.tsx b/client/src/components/ConversationSummaryList.tsx
index f8e3d22..c50a5f9 100644
--- a/client/src/components/ConversationSummaryList.tsx
+++ b/client/src/components/ConversationSummaryList.tsx
@@ -19,13 +19,13 @@
import dayjs from 'dayjs';
import { IConversationSummary } from 'jami-web-common';
import { QRCodeCanvas } from 'qrcode.react';
-import { useCallback, useContext, useMemo, useState } from 'react';
+import { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { useAuthContext } from '../contexts/AuthProvider';
-import { CallManagerContext } from '../contexts/CallManagerProvider';
-import { CallStatus, useCallContext } from '../contexts/CallProvider';
+import { useCallManagerContext } from '../contexts/CallManagerProvider';
+import { CallStatus } from '../contexts/CallProvider';
import { useConversationDisplayNameShort } from '../hooks/useConversationDisplayName';
import { useUrlParams } from '../hooks/useUrlParams';
import { ConversationRouteParams } from '../router';
@@ -108,8 +108,7 @@
const SecondaryText = ({ conversationSummary, isSelected }: SecondaryTextProps) => {
const { account } = useAuthContext();
- const callContext = useCallContext(true);
- const { callData } = useContext(CallManagerContext);
+ const { callData, callStatus, isAudioOn } = useCallManagerContext();
const { t, i18n } = useTranslation();
const timeIndicator = useMemo(() => {
@@ -123,7 +122,7 @@
}, [conversationSummary, i18n]);
const lastMessageText = useMemo(() => {
- if (!callContext || !callData || callData.conversationId !== conversationSummary.id) {
+ if (!callData || callData.conversationId !== conversationSummary.id) {
const message = conversationSummary.lastMessage;
switch (message.type) {
case 'initial': {
@@ -149,16 +148,16 @@
}
}
- if (callContext.callStatus === CallStatus.InCall) {
- return callContext.isAudioOn ? t('ongoing_call_unmuted') : t('ongoing_call_muted');
+ if (callStatus === CallStatus.InCall) {
+ return isAudioOn ? t('ongoing_call_unmuted') : t('ongoing_call_muted');
}
- if (callContext.callStatus === CallStatus.Connecting) {
+ if (callStatus === CallStatus.Connecting) {
return t('connecting_call');
}
- return callContext.callRole === 'caller' ? t('outgoing_call') : t('incoming_call');
- }, [account, conversationSummary, callContext, callData, t, i18n]);
+ return callData.role === 'caller' ? t('outgoing_call') : t('incoming_call');
+ }, [account, conversationSummary, callData, callStatus, isAudioOn, t, i18n]);
return (
<Stack direction="row" spacing="5px">
@@ -186,7 +185,7 @@
contextMenuProps,
}: ConversationMenuProps) => {
const { t } = useTranslation();
- const { startCall } = useContext(CallManagerContext);
+ const { startCall } = useCallManagerContext();
const [isSwarm] = useState(true);
const detailsDialogHandler = useDialogHandler();
@@ -206,10 +205,7 @@
Icon: AudioCallIcon,
onClick: () => {
if (conversationId) {
- startCall({
- conversationId,
- role: 'caller',
- });
+ startCall(conversationId);
}
},
},
@@ -218,11 +214,7 @@
Icon: VideoCallIcon,
onClick: () => {
if (conversationId) {
- startCall({
- conversationId,
- role: 'caller',
- withVideoOn: true,
- });
+ startCall(conversationId, true);
}
},
},
diff --git a/client/src/components/ConversationView.tsx b/client/src/components/ConversationView.tsx
index 5f76add..b636ec3 100644
--- a/client/src/components/ConversationView.tsx
+++ b/client/src/components/ConversationView.tsx
@@ -16,10 +16,8 @@
* <https://www.gnu.org/licenses/>.
*/
import { Divider, Stack, Typography } from '@mui/material';
-import { useContext } from 'react';
-import { CallManagerContext } from '../contexts/CallManagerProvider';
-import { useCallContext } from '../contexts/CallProvider';
+import { useCallManagerContext } from '../contexts/CallManagerProvider';
import { useConversationContext } from '../contexts/ConversationProvider';
import CallInterface from '../pages/CallInterface';
import ChatInterface from '../pages/ChatInterface';
@@ -27,10 +25,9 @@
const ConversationView = () => {
const { conversationId } = useConversationContext();
- const callContext = useCallContext(true);
- const { callData } = useContext(CallManagerContext);
+ const { callData } = useCallManagerContext();
- if (callContext && callData?.conversationId === conversationId) {
+ if (callData?.conversationId === conversationId) {
return <CallInterface />;
}
@@ -49,7 +46,7 @@
const ConversationHeader = () => {
const { conversationId, conversationDisplayName } = useConversationContext();
- const { startCall } = useContext(CallManagerContext);
+ const { startCall } = useCallManagerContext();
return (
<Stack direction="row" padding="16px" overflow="hidden">
@@ -59,8 +56,8 @@
</Typography>
</Stack>
<Stack direction="row" spacing="20px">
- <StartAudioCallButton onClick={() => startCall({ conversationId, role: 'caller' })} />
- <StartVideoCallButton onClick={() => startCall({ conversationId, role: 'caller', withVideoOn: true })} />
+ <StartAudioCallButton onClick={() => startCall(conversationId)} />
+ <StartVideoCallButton onClick={() => startCall(conversationId, true)} />
<AddParticipantButton />
<ShowOptionsMenuButton />
</Stack>
diff --git a/client/src/components/VideoOverlay.tsx b/client/src/components/VideoOverlay.tsx
index 9307f9b..2093840 100644
--- a/client/src/components/VideoOverlay.tsx
+++ b/client/src/components/VideoOverlay.tsx
@@ -20,7 +20,7 @@
import Draggable, { DraggableEventHandler } from 'react-draggable';
import { useNavigate } from 'react-router-dom';
-import { useCallContext } from '../contexts/CallProvider';
+import { useCallManagerContext } from '../contexts/CallManagerProvider';
import { useUserMediaContext } from '../contexts/UserMediaProvider';
import { VideoElementWithSinkId } from '../utils/utils';
import VideoStream, { VideoStreamProps } from './VideoStream';
@@ -75,7 +75,7 @@
};
export const RemoteVideoOverlay = ({ callConversationId }: { callConversationId: string }) => {
- const { remoteStreams } = useCallContext();
+ const { remoteStreams } = useCallManagerContext();
const {
currentMediaDeviceIds: {
audiooutput: { id: audioOutDeviceId },