Add small UX improvements to call
- Notification saying you have missed a call if you are already in a call
- Indication about the call in the conversation list item
GitLab: #197
GitLab: #173
Change-Id: Ibe4ff0d9f3ffd95cd0d83afd2041c5fad513a7e0
diff --git a/client/src/components/ConversationListItem.tsx b/client/src/components/ConversationListItem.tsx
index 3f5dad3..e4be263 100644
--- a/client/src/components/ConversationListItem.tsx
+++ b/client/src/components/ConversationListItem.tsx
@@ -24,6 +24,7 @@
import { useAuthContext } from '../contexts/AuthProvider';
import { CallManagerContext } from '../contexts/CallManagerProvider';
+import { CallStatus, useCallContext } from '../contexts/CallProvider';
import { useConversationContext } from '../contexts/ConversationProvider';
import { MessengerContext } from '../contexts/MessengerProvider';
import { Conversation } from '../models/conversation';
@@ -52,6 +53,9 @@
const conversationId = conversationContext?.conversationId;
const contextMenuHandler = useContextMenuHandler();
const { newContactId, setNewContactId } = useContext(MessengerContext);
+ const callContext = useCallContext(true);
+ const { callData } = useContext(CallManagerContext);
+ const { t } = useTranslation();
const pathId = conversationId ?? newContactId;
const isSelected = conversation.getDisplayUri() === pathId;
@@ -68,6 +72,28 @@
}
}, [navigate, conversation, userId, setNewContactId]);
+ const getSecondaryText = () => {
+ const propsConversationId = conversation.id;
+
+ if (!propsConversationId) {
+ return '';
+ }
+
+ if (!callContext || !callData || callData.conversationId !== propsConversationId) {
+ return conversation.getDisplayUri();
+ }
+
+ if (callContext.callStatus === CallStatus.InCall) {
+ return callContext.isAudioOn ? t('ongoing_call_unmuted') : t('ongoing_call_muted');
+ }
+
+ if (callContext.callStatus === CallStatus.Connecting) {
+ return t('connecting_call');
+ }
+
+ return callContext.callRole === 'caller' ? t('outgoing_call') : t('incoming_call');
+ };
+
return (
<Box onContextMenu={contextMenuHandler.handleAnchorPosition}>
<ConversationMenu
@@ -81,7 +107,7 @@
<ListItemAvatar>
<ConversationAvatar displayName={conversation.getDisplayNameNoFallback()} />
</ListItemAvatar>
- <ListItemText primary={conversation.getDisplayName()} secondary={conversation.getDisplayUri()} />
+ <ListItemText primary={conversation.getDisplayName()} secondary={getSecondaryText()} />
</ListItem>
</Box>
);
diff --git a/client/src/contexts/CallManagerProvider.tsx b/client/src/contexts/CallManagerProvider.tsx
index 7d8d843..c04010f 100644
--- a/client/src/contexts/CallManagerProvider.tsx
+++ b/client/src/contexts/CallManagerProvider.tsx
@@ -17,8 +17,10 @@
*/
import { CallBegin, WebSocketMessageType } from 'jami-web-common';
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
+import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
+import { AlertSnackbar } from '../components/AlertSnackbar';
import { RemoteVideoOverlay } from '../components/VideoOverlay';
import { useUrlParams } from '../hooks/useUrlParams';
import { Conversation } from '../models/conversation';
@@ -60,6 +62,8 @@
const navigate = useNavigate();
const { conversation } = useConversationQuery(callData?.conversationId);
const { urlParams } = useUrlParams<ConversationRouteParams>();
+ const [missedCallConversationId, setMissedCallConversationId] = useState<string>();
+ const { t } = useTranslation();
const failStartCall = useCallback(() => {
throw new Error('Cannot start call: Already in a call');
@@ -77,16 +81,18 @@
}, [callData]);
useEffect(() => {
- if (callData) {
- // TODO: Currently, we simply do not bind the CallBegin listener if already in a call.
- // In the future, we should handle receiving a call while already in another.
- return;
- }
if (!webSocket) {
return;
}
const callBeginListener = ({ conversationId, withVideoOn }: CallBegin) => {
+ if (callData) {
+ // TODO: Currently, we display a notification if already in a call.
+ // In the future, we should handle receiving a call while already in another.
+ setMissedCallConversationId(conversationId);
+ return;
+ }
+
startCall({ conversationId: conversationId, role: 'receiver', withVideoOn });
navigate(`/conversation/${conversationId}`);
};
@@ -109,15 +115,24 @@
);
return (
- <CallManagerContext.Provider value={value}>
- <WebRtcProvider>
- <CallProvider>
- {callData && callData.conversationId !== urlParams.conversationId && (
- <RemoteVideoOverlay callConversationId={callData.conversationId} />
- )}
- {children}
- </CallProvider>
- </WebRtcProvider>
- </CallManagerContext.Provider>
+ <>
+ <AlertSnackbar
+ severity={'info'}
+ open={missedCallConversationId !== undefined}
+ onClose={() => setMissedCallConversationId(undefined)}
+ >
+ {t('missed_incoming_call', { conversationId: missedCallConversationId })}
+ </AlertSnackbar>
+ <CallManagerContext.Provider value={value}>
+ <WebRtcProvider>
+ <CallProvider>
+ {callData && callData.conversationId !== urlParams.conversationId && (
+ <RemoteVideoOverlay callConversationId={callData.conversationId} />
+ )}
+ {children}
+ </CallProvider>
+ </WebRtcProvider>
+ </CallManagerContext.Provider>
+ </>
);
};
diff --git a/client/src/contexts/CallProvider.tsx b/client/src/contexts/CallProvider.tsx
index 8be6dff..7517133 100644
--- a/client/src/contexts/CallProvider.tsx
+++ b/client/src/contexts/CallProvider.tsx
@@ -414,13 +414,10 @@
mediaDevices,
currentMediaDeviceIds,
isAudioOn,
- setIsAudioOn,
videoStatus,
updateVideoStatus,
isChatShown,
- setIsChatShown,
isFullscreen,
- setIsFullscreen,
callRole,
callStatus,
callStartTime,
diff --git a/client/src/locale/en/translation.json b/client/src/locale/en/translation.json
index 701998a..21fff51 100644
--- a/client/src/locale/en/translation.json
+++ b/client/src/locale/en/translation.json
@@ -1,9 +1,10 @@
{
"severity": "",
- "share_screen": "Share your screen",
- "share_window": "Share window",
- "share_screen_area": "Share an area of your screen",
- "share_file": "Share a file",
+ "ongoing_call_unmuted": "Ongoing call",
+ "ongoing_call_muted": "Ongoing call (muted)",
+ "connecting_call": "Connecting...",
+ "outgoing_call": "Outgoing call",
+ "incoming_call": "Incoming call",
"conversation_message": "Message",
"conversation_start_audiocall": "Start audio call",
"conversation_start_videocall": "Start video call",
@@ -72,6 +73,7 @@
"message_input_placeholder_three": "Write to {{member0}}, {{member1}} and {{member2}}",
"message_input_placeholder_four": "Write to {{member0}}, {{member1}}, {{member2}}, +1 other member",
"message_input_placeholder_more": "Write to {{member0}}, {{member1}}, {{member2}}, +{{excess}} other members",
+ "missed_incoming_call": "Missed incoming call from conversation {{conversationId}}",
"conversation_add_contact": "Add contact",
"loading": "Loading...",
"calling": "Calling {{member0}}",
@@ -111,8 +113,13 @@
"setup_login_password_placeholder_creation": "New password",
"setup_login_password_placeholder_repeat": "Repeat password",
"admin_creation_submit_button": "Create admin account",
+ "share_screen": "Share your screen",
+ "share_window": "Share window",
+ "share_screen_area": "Share an area of your screen",
+ "share_file": "Share a file",
"incoming_call_audio": "Incoming audio call from {{member0}}",
"incoming_call_video": "Incoming video call from {{member0}}",
"severity_error": "Error",
- "severity_success": "Success"
+ "severity_success": "Success",
+ "severity_info": "Info"
}
diff --git a/client/src/locale/fr/translation.json b/client/src/locale/fr/translation.json
index d91519f..c397c0f 100644
--- a/client/src/locale/fr/translation.json
+++ b/client/src/locale/fr/translation.json
@@ -1,9 +1,10 @@
{
"severity": "",
- "share_screen": "Partager votre écran",
- "share_window": "Partager la fenêtre",
- "share_screen_area": "Partager une partie de l'écran",
- "share_file": "Partager le fichier",
+ "ongoing_call_unmuted": "Appel en cours",
+ "ongoing_call_muted": "Appel en cours (muet)",
+ "connecting_call": "Connexion...",
+ "outgoing_call": "Appel sortant",
+ "incoming_call": "Appel entrant",
"conversation_message": "Envoyer un message",
"conversation_start_audiocall": "Démarrer appel audio",
"conversation_start_videocall": "Démarrer appel vidéo",
@@ -72,6 +73,7 @@
"message_input_placeholder_three": "Écrire à {{member0}}, {{member1}} et {{member2}}",
"message_input_placeholder_four": "Écrire à {{member0}}, {{member1}}, {{member2}}, +1 autre membre",
"message_input_placeholder_more": "Écrire à {{member0}}, {{member1}}, {{member2}}, +{{excess}} autres membres",
+ "missed_incoming_call": "Appel manqué de la conversation {{conversationId}}",
"conversation_add_contact": "Ajouter le contact",
"loading": "Chargement...",
"calling": "Appel vers {{member0}}",
@@ -111,8 +113,13 @@
"setup_login_password_placeholder_creation": "Nouveau mot de passe",
"setup_login_password_placeholder_repeat": "Répéter le mot de passe",
"admin_creation_submit_button": "Créer un compte admin",
+ "share_screen": "Partager votre écran",
+ "share_window": "Partager la fenêtre",
+ "share_screen_area": "Partager une partie de l'écran",
+ "share_file": "Partager le fichier",
"incoming_call_audio": "Appel audio entrant de {{member0}}",
"incoming_call_video": "Appel vidéo entrant de {{member0}}",
"severity_error": "Erreur",
- "severity_success": "Succès"
+ "severity_success": "Succès",
+ "severity_info": "Info"
}