Add composing notification
Change-Id: I2c052c4395a56ba6acf882cea3be4b82e2fde761
diff --git a/client/src/contexts/ConversationProvider.tsx b/client/src/contexts/ConversationProvider.tsx
index 9e805e3..3c24896 100644
--- a/client/src/contexts/ConversationProvider.tsx
+++ b/client/src/contexts/ConversationProvider.tsx
@@ -15,8 +15,8 @@
* License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
-import { ConversationInfos, ConversationView, WebSocketMessageType } from 'jami-web-common';
-import { useContext, useEffect, useMemo } from 'react';
+import { ComposingStatus, ConversationInfos, ConversationView, WebSocketMessageType } from 'jami-web-common';
+import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import LoadingPage from '../components/Loading';
import { createOptionalContext } from '../hooks/createOptionalContext';
@@ -34,6 +34,7 @@
conversationDisplayName: string;
conversationInfos: ConversationInfos;
members: ConversationMember[];
+ composingMembers: ConversationMember[];
}
const optionalConversationContext = createOptionalContext<IConversationContext>('ConversationContext');
@@ -46,6 +47,7 @@
} = useUrlParams<ConversationRouteParams>();
const { accountId, account } = useAuthContext();
const webSocket = useContext(WebSocketContext);
+ const [composingMembers, setComposingMembers] = useState<ConversationMember[]>([]);
const conversationInfosQuery = useConversationInfosQuery(conversationId!);
const membersQuery = useMembersQuery(conversationId!);
@@ -65,6 +67,34 @@
const conversationDisplayName = useConversationDisplayName(account, conversationInfos, members);
+ const onComposingStatusChanged = useCallback(
+ (data: ComposingStatus) => {
+ // FIXME: data.conversationId is an empty string. Don't know why. Should not be.
+ // Good enough for now, but will be a problem if the user has more than one conversation with the same contact.
+ // if (data.conversationId === conversationId)
+ {
+ setComposingMembers((composingMembers) => {
+ if (!data.isWriting) {
+ return composingMembers.filter(({ contact }) => contact.uri !== data.contactId);
+ }
+
+ const isAlreadyIncluded = composingMembers.find((member) => member.contact.uri === data.contactId);
+ if (isAlreadyIncluded) {
+ return composingMembers;
+ }
+
+ const member = members?.find((member) => member.contact.uri === data.contactId);
+ if (!member) {
+ return composingMembers;
+ }
+
+ return [...composingMembers, member];
+ });
+ }
+ },
+ [/*conversationId,*/ members]
+ );
+
useEffect(() => {
if (!conversationInfos || !conversationId || !webSocket) {
return;
@@ -75,7 +105,10 @@
};
webSocket.send(WebSocketMessageType.ConversationView, conversationView);
- }, [accountId, conversationInfos, conversationId, webSocket]);
+ webSocket.bind(WebSocketMessageType.OnComposingStatusChanged, onComposingStatusChanged);
+
+ return () => webSocket.unbind(WebSocketMessageType.OnComposingStatusChanged, onComposingStatusChanged);
+ }, [accountId, conversationInfos, conversationId, onComposingStatusChanged, webSocket]);
const value = useMemo(() => {
if (!conversationId || !conversationDisplayName || !conversationInfos || !members) {
@@ -87,8 +120,9 @@
conversationDisplayName,
conversationInfos,
members,
+ composingMembers,
};
- }, [conversationId, conversationDisplayName, conversationInfos, members]);
+ }, [conversationId, conversationDisplayName, conversationInfos, members, composingMembers]);
if (isLoading) {
return <LoadingPage />;