Add composing notification

Change-Id: I2c052c4395a56ba6acf882cea3be4b82e2fde761
diff --git a/server/src/jamid/jami-signal-interfaces.ts b/server/src/jamid/jami-signal-interfaces.ts
index 851239b..188dfaf 100644
--- a/server/src/jamid/jami-signal-interfaces.ts
+++ b/server/src/jamid/jami-signal-interfaces.ts
@@ -133,3 +133,10 @@
   conversationId: string;
   message: Message;
 }
+
+export interface ComposingStatusChanged {
+  accountId: string;
+  conversationId: string;
+  from: string;
+  status: number;
+}
diff --git a/server/src/jamid/jami-signal.ts b/server/src/jamid/jami-signal.ts
index 6a9b15b..15bef48 100644
--- a/server/src/jamid/jami-signal.ts
+++ b/server/src/jamid/jami-signal.ts
@@ -25,6 +25,7 @@
   AccountsChanged = 'AccountsChanged',
   AccountDetailsChanged = 'AccountDetailsChanged',
   RegistrationStateChanged = 'RegistrationStateChanged',
+  ComposingStatusChanged = 'ComposingStatusChanged',
   IncomingTrustRequest = 'IncomingTrustRequest',
   ContactAdded = 'ContactAdded',
   ContactRemoved = 'ContactRemoved',
diff --git a/server/src/jamid/jami-swig.ts b/server/src/jamid/jami-swig.ts
index cd6a95c..07fa2dd 100644
--- a/server/src/jamid/jami-swig.ts
+++ b/server/src/jamid/jami-swig.ts
@@ -123,6 +123,7 @@
 
   sendMessage(accountId: string, conversationId: string, message: string, replyTo: string, flag: number): void;
   loadConversationMessages(accountId: string, conversationId: string, fromMessage: string, n: number): number;
+  setIsComposing(accountId: string, conversationId: string, isWriting: boolean): void;
 
   getCallList(accountId: string): StringVect;
   getCallDetails(accountId: string, callId: string): StringMap;
diff --git a/server/src/jamid/jamid.ts b/server/src/jamid/jamid.ts
index a868afe..ab4d8a8 100644
--- a/server/src/jamid/jamid.ts
+++ b/server/src/jamid/jamid.ts
@@ -19,6 +19,7 @@
 
 import {
   AccountDetails,
+  ComposingStatus,
   ContactDetails,
   ConversationInfos,
   ConversationMessage,
@@ -41,6 +42,7 @@
 import {
   AccountDetailsChanged,
   AccountMessageStatusChanged,
+  ComposingStatusChanged,
   ContactAdded,
   ContactRemoved,
   ConversationLoaded,
@@ -167,6 +169,10 @@
     handlers.MessageReceived = (accountId: string, conversationId: string, message: Message) =>
       onMessageReceived.next({ accountId, conversationId, message });
 
+    const onComposingStatusChanged = new Subject<ComposingStatusChanged>();
+    handlers.ComposingStatusChanged = (accountId: string, conversationId: string, from: string, status: number) =>
+      onComposingStatusChanged.next({ accountId, conversationId, from, status });
+
     // Expose all signals in an events object to allow other handlers to subscribe after jamiSwig.init()
     this.events = {
       onAccountsChanged: onAccountsChanged.asObservable(),
@@ -186,6 +192,7 @@
       onConversationLoaded: onConversationLoaded.asObservable(),
       onConversationMemberEvent: onConversationMemberEvent.asObservable(),
       onMessageReceived: onMessageReceived.asObservable(),
+      onComposingStatusChanged: onComposingStatusChanged.asObservable(),
     };
 
     this.setupSignalHandlers();
@@ -378,6 +385,10 @@
     this.jamiSwig.sendMessage(accountId, conversationId, message, replyTo ?? '', flag ?? 0);
   }
 
+  setIsComposing(accountId: string, conversationId: string, isWriting: boolean) {
+    this.jamiSwig.setIsComposing(accountId, conversationId, isWriting);
+  }
+
   getCallIds(accountId: string): string[] {
     return stringVectToArray(this.jamiSwig.getCallList(accountId));
   }
@@ -503,5 +514,16 @@
       };
       this.webSocketServer.send(signal.accountId, WebSocketMessageType.ConversationMessage, data);
     });
+
+    this.events.onComposingStatusChanged.subscribe((signal) => {
+      log.debug('Received ComposingStatusChanged:', JSON.stringify(signal));
+
+      const data: ComposingStatus = {
+        contactId: signal.from,
+        conversationId: signal.conversationId,
+        isWriting: signal.status === 1,
+      };
+      this.webSocketServer.send(signal.accountId, WebSocketMessageType.OnComposingStatusChanged, data);
+    });
   }
 }