Bug 1348038 - Handle Topic Events in Matrix. r=clokep DONTBUILD
authorKhushil Mistry <khushil324@gmail.com>
Wed, 15 Apr 2020 13:59:02 +0300
changeset 38829 7e6998a6a0e75a0f39c8c887618c16ff89f2e001
parent 38828 6adb081c56771f0d1053eb1b350e389aa48fd415
child 38830 08e3a73b641407b963f401dc26c1c98f23f49eee
push id401
push userclokep@gmail.com
push dateMon, 01 Jun 2020 20:41:59 +0000
reviewersclokep
bugs1348038
Bug 1348038 - Handle Topic Events in Matrix. r=clokep DONTBUILD
chat/protocols/matrix/matrix.jsm
--- a/chat/protocols/matrix/matrix.jsm
+++ b/chat/protocols/matrix/matrix.jsm
@@ -134,16 +134,49 @@ MatrixConversation.prototype = {
       }
     });
     if (participants.length) {
       this.notifyObservers(
         new nsSimpleEnumerator(participants),
         "chat-buddy-add"
       );
     }
+
+    if (aRoom.currentState.getStateEvents("m.room.topic").length) {
+      let event = aRoom.currentState.getStateEvents("m.room.topic")[0];
+      this.setTopic(event.getContent().topic, event.getSender().name, true);
+    }
+
+    if (
+      aRoom.summary &&
+      aRoom.summary.info &&
+      aRoom.summary.info.title &&
+      this._name != aRoom.summary.info.title
+    ) {
+      this._name = aRoom.summary.info.title;
+      this.notifyObservers(null, "update-conv-title");
+    }
+  },
+
+  get topic() {
+    return this._topic;
+  },
+
+  set topic(aTopic) {
+    // Check if our user has the permissions to set the topic.
+    if (this.topicSettable) {
+      this._account._client.setRoomTopic(this._roomId, aTopic);
+    }
+  },
+
+  get topicSettable() {
+    return (
+      this.room &&
+      this.room.currentState.maySendEvent("m.room.topic", this._account.userId)
+    );
   },
 };
 
 /*
  * TODO Other random functionality from MatrixClient that will be useful:
  *  getRooms / getUsers / publicRooms
  *  invite
  *  ban / kick
@@ -226,26 +259,41 @@ MatrixAccount.prototype = {
     this._client.on(
       "Room.timeline",
       (event, room, toStartOfTimeline, removed, data) => {
         // TODO: Better handle messages!
         if (toStartOfTimeline) {
           return;
         }
         if (room.roomId in this._roomList) {
-          let body;
+          let conv = this._roomList[room.roomId];
+          // If this room was never initialized, do it now.
+          if (conv && !conv._roomId) {
+            conv.initRoom(room);
+          }
           if (event.getType() === "m.room.message") {
-            body = event.getContent().body;
+            conv.writeMessage(event.sender.name, event.getContent().body, {
+              incoming: true,
+            });
+          } else if (event.getType() == "m.room.topic") {
+            conv.setTopic(event.getContent().topic, event.sender.name);
+          } else if (conv && event.getType() == "m.room.power_levels") {
+            conv.notifyObservers(null, "chat-update-topic");
           } else {
-            // TODO Any event that is not understood gets the raw content added to the conversation.
-            body = JSON.stringify(event.getContent());
+            // This is an unhandled event type, for now just put it in the room as
+            // the JSON body. This will need to be updated once (most) events are
+            // handled.
+            conv.writeMessage(
+              event.sender.name,
+              event.getType() + ": " + JSON.stringify(event.getContent()),
+              {
+                system: true,
+              }
+            );
           }
-          this._roomList[room.roomId].writeMessage(event.getSender(), body, {
-            incoming: true,
-          });
         }
       }
     );
     // Update the chat participant information.
     this._client.on("RoomMember.name", this.updateRoomMember);
     this._client.on("RoomMember.powerLevel", this.updateRoomMember);
 
     // TODO Other events to handle:
@@ -278,29 +326,34 @@ MatrixAccount.prototype = {
       }
     });
 
     // Get the list of joined rooms on the server and create those conversations.
     this._client.getJoinedRooms().then(response => {
       for (let roomId of response.joined_rooms) {
         let conv = new MatrixConversation(this, roomId, this.userId);
         this._roomList[roomId] = conv;
+        let room = this._client.getRoom(roomId);
+        if (room && !conv._roomId) {
+          conv.initRoom(room);
+        }
       }
     });
   },
 
   updateRoomMember(event, member) {
     if (member.roomId in this._roomList) {
       let conv = this._roomList[member.roomId];
       let participant = conv._participants.get(member.userId);
       // A participant might not exist (for example, this happens if the user
       // has only been invited, but has not yet joined).
       if (participant) {
         participant._roomMember = member;
         conv.notifyObservers(participant, "chat-buddy-update");
+        conv.notifyObservers(null, "chat-update-topic");
       }
     }
   },
 
   disconnect() {
     if (this._client) {
       this._client.stopClient();
     }
@@ -342,16 +395,20 @@ MatrixAccount.prototype = {
     let conv = new MatrixConversation(this, roomIdOrAlias, this.userId);
     conv.joining = true;
     this._client
       .joinRoom(roomIdOrAlias)
       .then(room => {
         this._roomList[room.roomId] = conv;
         conv.initRoom(room);
         conv.joining = false;
+        conv.setTopic(
+          room.currentState.getStateEvents("m.room.topic", "").getContent()
+            .topic
+        );
       })
       .catch(error => {
         // TODO: Handle errors?
         // XXX We probably want to display an error in the open conversation
         //     window.
         this.ERROR(error);
         conv.joining = false;
         conv.left = true;