summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--webclient/components/matrix/event-handler-service.js83
-rw-r--r--webclient/recents/recents-controller.js130
-rw-r--r--webclient/recents/recents-filter.js33
-rw-r--r--webclient/recents/recents.html66
4 files changed, 141 insertions, 171 deletions
diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js
index 4604ff6192..4b0566fe33 100644
--- a/webclient/components/matrix/event-handler-service.js
+++ b/webclient/components/matrix/event-handler-service.js
@@ -63,13 +63,14 @@ angular.module('eventHandlerService', [])
     var initRoom = function(room_id) {
         if (!(room_id in $rootScope.events.rooms)) {
             console.log("Creating new handler entry for " + room_id);
-            $rootScope.events.rooms[room_id] = {};
-            $rootScope.events.rooms[room_id].messages = [];
-            $rootScope.events.rooms[room_id].members = {};
-
-            // Pagination information
-            $rootScope.events.rooms[room_id].pagination = {
-                earliest_token: "END"   // how far back we've paginated
+            $rootScope.events.rooms[room_id] = {
+                room_id: room_id,
+                messages: [],
+                members: {},
+                // Pagination information
+                pagination: {
+                    earliest_token: "END"   // how far back we've paginated
+                }
             };
         }
     };
@@ -257,7 +258,9 @@ angular.module('eventHandlerService', [])
 
             // FIXME: /initialSync on a particular room is not yet available
             // So initRoom on a new room is not called. Make sure the room data is initialised here
-            initRoom(event.room_id);
+            if (event.room_id) {
+                initRoom(event.room_id);
+            }
 
             // Avoid duplicated events
             // Needed for rooms where initialSync has not been done. 
@@ -347,6 +350,70 @@ angular.module('eventHandlerService', [])
 
         resetRoomMessages: function(room_id) {
             resetRoomMessages(room_id);
+        },
+        
+        /**
+         * Return the last message event of a room
+         * @param {String} room_id the room id
+         * @param {Boolean} filterFake true to not take into account fake messages
+         * @returns {undefined | Event} the last message event if available
+         */
+        getLastMessage: function(room_id, filterEcho) {
+            var lastMessage;
+
+            var room = $rootScope.events.rooms[room_id];
+            if (room) {
+                for (var i = room.messages.length - 1; i >= 0; i--) {
+                    var message = room.messages[i];
+
+                    if (!filterEcho || undefined === message.echo_msg_state) {
+                        lastMessage = message;
+                        break;
+                    }
+                }
+            }
+
+            return lastMessage;
+        },
+        
+        /**
+         * Compute the room users number, ie the number of members who has joined the room.
+         * @param {String} room_id the room id
+         * @returns {undefined | Number} the room users number if available
+         */
+        getUsersCountInRoom: function(room_id) {
+            var memberCount;
+
+            var room = $rootScope.events.rooms[room_id];
+            if (room) {
+                memberCount = 0;
+
+                for (var i in room.members) {
+                    var member = room.members[i];
+
+                    if ("join" === member.membership) {
+                        memberCount = memberCount + 1;
+                    }
+                }
+            }
+
+            return memberCount;
+        },
+        
+        /**
+         * Get the member object of a room member
+         * @param {String} room_id the room id
+         * @param {String} user_id the id of the user
+         * @returns {undefined | Object} the member object of this user in this room if he is part of the room
+         */
+        getMember: function(room_id, user_id) {
+            var member;
+            
+            var room = $rootScope.events.rooms[room_id];
+            if (room) {
+                member = room.members[user_id];
+            }
+            return member;
         }
     };
 }]);
diff --git a/webclient/recents/recents-controller.js b/webclient/recents/recents-controller.js
index a0db0538f3..ee8a41c366 100644
--- a/webclient/recents/recents-controller.js
+++ b/webclient/recents/recents-controller.js
@@ -16,134 +16,16 @@
 
 'use strict';
 
-angular.module('RecentsController', ['matrixService', 'matrixFilter', 'eventHandlerService'])
-.controller('RecentsController', ['$rootScope', '$scope', 'matrixService', 'eventHandlerService', 
-                               function($rootScope, $scope, matrixService, eventHandlerService) {
-                                   
-    // FIXME: Angularjs reloads the controller (and resets its $scope) each time
-    // the page URL changes, use $rootScope to avoid to have to reload data
-    $rootScope.rooms;
+angular.module('RecentsController', ['matrixService', 'matrixFilter'])
+.controller('RecentsController', ['$rootScope', '$scope', 'eventHandlerService', 
+                               function($rootScope, $scope, eventHandlerService) {
+
+    // Expose the service to the view
+    $scope.eventHandlerService = eventHandlerService;
 
     // $rootScope of the parent where the recents component is included can override this value
     // in order to highlight a specific room in the list
     $rootScope.recentsSelectedRoomID;
-    
-    var listenToEventStream = function() {
-        // Refresh the list on matrix invitation and message event
-        $rootScope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) {
-            if (isLive) {
-                if (!$rootScope.rooms[event.room_id]) {
-                    // The user has joined a new room, which we do not have data yet. The reason is that
-                    // the room has appeared in the scope of the user rooms after the global initialSync
-                    // FIXME: an initialSync on this specific room should be done
-                    $rootScope.rooms[event.room_id] = {
-                        room_id:event.room_id
-                    };
-                }
-                else if (event.state_key === matrixService.config().user_id && "invite" !== event.membership && "join" !== event.membership) {
-                    // The user has been kicked or banned from the room, remove this room from the recents
-                    delete $rootScope.rooms[event.room_id];
-                }
-                
-                if ($rootScope.rooms[event.room_id]) {
-                    $rootScope.rooms[event.room_id].lastMsg = event;
-                }
-                
-                // Update room users count
-                $rootScope.rooms[event.room_id].numUsersInRoom = getUsersCountInRoom(event.room_id);
-            }
-        });
-        $rootScope.$on(eventHandlerService.MSG_EVENT, function(ngEvent, event, isLive) {
-            if (isLive) {
-                $rootScope.rooms[event.room_id].lastMsg = event;              
-            }
-        });
-        $rootScope.$on(eventHandlerService.CALL_EVENT, function(ngEvent, event, isLive) {
-            if (isLive) {
-                $rootScope.rooms[event.room_id].lastMsg = event;
-            }
-        });
-        $rootScope.$on(eventHandlerService.ROOM_CREATE_EVENT, function(ngEvent, event, isLive) {
-            if (isLive) {
-                $rootScope.rooms[event.room_id] = event;
-            }
-        });
-        $rootScope.$on(eventHandlerService.NAME_EVENT, function(ngEvent, event, isLive) {
-            if (isLive) {
-                $rootScope.rooms[event.room_id].lastMsg = event;
-            }
-        });
-        $rootScope.$on(eventHandlerService.TOPIC_EVENT, function(ngEvent, event, isLive) {
-            if (isLive) {
-                $rootScope.rooms[event.room_id].lastMsg = event;
-            }
-        });
-    };
-    
-    /**
-     * Compute the room users number, ie the number of members who has joined the room.
-     * @param {String} room_id the room id
-     * @returns {undefined | Number} the room users number if available
-     */
-    var getUsersCountInRoom = function(room_id) {
-        var memberCount;
-        
-        var room = $rootScope.events.rooms[room_id];
-        if (room) {
-            memberCount = 0;
-            
-            for (var i in room.members) {
-                var member = room.members[i];
-                
-                if ("join" === member.membership) {
-                    memberCount = memberCount + 1;
-                }
-            }
-        }
-        
-        return memberCount;
-    };
-
-    $scope.onInit = function() {
-        // Init recents list only once
-        if ($rootScope.rooms) {
-            return;
-        }
-        
-        $rootScope.rooms = {};
-        
-        // Use initialSync data to init the recents list
-        eventHandlerService.waitForInitialSyncCompletion().then(
-            function(initialSyncData) {
-            
-                var rooms = initialSyncData.data.rooms;
-                for (var i=0; i<rooms.length; i++) {
-                    var room = rooms[i];
-                    
-                    // Add room_alias & room_display_name members
-                    $rootScope.rooms[room.room_id] = angular.extend(room, matrixService.getRoomAliasAndDisplayName(room));
-
-                    // Create a shortcut for the last message of this room
-                    if (room.messages && room.messages.chunk && room.messages.chunk[0]) {
-                        $rootScope.rooms[room.room_id].lastMsg = room.messages.chunk[0];
-                    }
-                    
-                    $rootScope.rooms[room.room_id].numUsersInRoom = getUsersCountInRoom(room.room_id);
-                }
-
-                // From now, update recents from the stream
-                listenToEventStream();
-            },
-            function(error) {
-                $rootScope.feedback = "Failure: " + error.data;
-            }
-        );
-    };
-
-    // Clean data when user logs out
-    $scope.$on(eventHandlerService.RESET_EVENT, function() {
 
-        delete $rootScope.rooms;
-    });
 }]);
 
diff --git a/webclient/recents/recents-filter.js b/webclient/recents/recents-filter.js
index d80de6fbeb..2fd4dbe98b 100644
--- a/webclient/recents/recents-filter.js
+++ b/webclient/recents/recents-filter.js
@@ -17,31 +17,48 @@
 'use strict';
 
 angular.module('RecentsController')
-.filter('orderRecents', function() {
+.filter('orderRecents', ["matrixService", "eventHandlerService", function(matrixService, eventHandlerService) {
     return function(rooms) {
 
+        var user_id = matrixService.config().user_id;
+
         // Transform the dict into an array
         // The key, room_id, is already in value objects
         var filtered = [];
-        angular.forEach(rooms, function(value, key) {
-            filtered.push( value );
+        angular.forEach(rooms, function(room, room_id) {
+
+            // Show the room only if the user has joined it or has been invited
+            // (ie, do not show it if he has been banned)
+            var member = eventHandlerService.getMember(room_id, user_id);
+            if (member && ("invite" === member.membership || "join" === member.membership)) {
+            
+                // Count users here
+                // TODO: Compute it directly in eventHandlerService
+                room.numUsersInRoom = eventHandlerService.getUsersCountInRoom(room_id);
+
+                filtered.push(room);
+            }
         });
 
         // And time sort them
         // The room with the lastest message at first
-        filtered.sort(function (a, b) {
+        filtered.sort(function (roomA, roomB) {
+
+            var lastMsgRoomA = eventHandlerService.getLastMessage(roomA.room_id, true);
+            var lastMsgRoomB = eventHandlerService.getLastMessage(roomB.room_id, true);
+
             // Invite message does not have a body message nor ts
             // Puth them at the top of the list
-            if (undefined === a.lastMsg) {
+            if (undefined === lastMsgRoomA) {
                 return -1;
             }
-            else if (undefined === b.lastMsg) {
+            else if (undefined === lastMsgRoomB) {
                 return 1;
             }
             else {
-                return b.lastMsg.ts - a.lastMsg.ts;
+                return lastMsgRoomB.ts - lastMsgRoomA.ts;
             }
         });
         return filtered;
     };
-});
\ No newline at end of file
+}]);
\ No newline at end of file
diff --git a/webclient/recents/recents.html b/webclient/recents/recents.html
index ca7636e36a..789ffc9d20 100644
--- a/webclient/recents/recents.html
+++ b/webclient/recents/recents.html
@@ -1,9 +1,9 @@
-<div ng-controller="RecentsController" data-ng-init="onInit()">
+<div ng-controller="RecentsController">
     <table class="recentsTable">
-        <tbody ng-repeat="(rm_id, room) in rooms | orderRecents" 
+        <tbody ng-repeat="(index, room) in events.rooms | orderRecents" 
                ng-click="goToPage('room/' + (room.room_alias ? room.room_alias : room.room_id) )" 
                class ="recentsRoom" 
-               ng-class="{'recentsRoomSelected': (room.room_id === recentsSelectedRoomID)}">
+               ng-class="{'recentsRoomSelected': (room.room_id === recentsSelectedRoomID)}">                                           
             <tr>
                 <td class="recentsRoomName">
                     {{ room.room_id | mRoomName }}
@@ -14,7 +14,11 @@
                     </span>
                 </td>
                 <td class="recentsRoomSummaryTS">
-                    {{ (room.lastMsg.ts) | date:'MMM d HH:mm' }}
+                    <!-- Use a temp var as alias to the last room message.
+                         Declaring it in this way ensures the data-binding -->
+                    {{ lastMsg = eventHandlerService.getLastMessage(room.room_id, true);"" }}
+
+                    {{ (lastMsg.ts) | date:'MMM d HH:mm' }}
                 </td>
             </tr>
 
@@ -25,67 +29,67 @@
                         {{ room.inviter | mUserDisplayName: room.room_id }} invited you
                     </div>
                     
-                    <div ng-hide="room.membership === 'invite'" ng-switch="room.lastMsg.type">
+                    <div ng-hide="room.membership === 'invite'" ng-switch="lastMsg.type">
                         <div ng-switch-when="m.room.member">
-                            <span ng-if="'join' === room.lastMsg.content.membership">
-                                {{ room.lastMsg.state_key | mUserDisplayName: room.room_id}} joined
+                            <span ng-if="'join' === lastMsg.content.membership">
+                                {{ lastMsg.state_key | mUserDisplayName: room.room_id}} joined
                             </span>
-                            <span ng-if="'leave' === room.lastMsg.content.membership">
-                                <span ng-if="room.lastMsg.user_id === room.lastMsg.state_key">
-                                    {{room.lastMsg.state_key | mUserDisplayName: room.room_id }} left
+                            <span ng-if="'leave' === lastMsg.content.membership">
+                                <span ng-if="lastMsg.user_id === lastMsg.state_key">
+                                    {{lastMsg.state_key | mUserDisplayName: room.room_id }} left
                                 </span>
-                                <span ng-if="room.lastMsg.user_id !== room.lastMsg.state_key">
-                                    {{ room.lastMsg.user_id | mUserDisplayName: room.room_id }}
-                                    {{ {"join": "kicked", "ban": "unbanned"}[room.lastMsg.content.prev] }}
-                                    {{ room.lastMsg.state_key | mUserDisplayName: room.room_id }}
+                                <span ng-if="lastMsg.user_id !== lastMsg.state_key">
+                                    {{ lastMsg.user_id | mUserDisplayName: room.room_id }}
+                                    {{ {"join": "kicked", "ban": "unbanned"}[lastMsg.content.prev] }}
+                                    {{ lastMsg.state_key | mUserDisplayName: room.room_id }}
                                 </span>
-                                <span ng-if="'join' === room.lastMsg.content.prev && room.lastMsg.content.reason">
-                                    : {{ room.lastMsg.content.reason }}
+                                <span ng-if="'join' === lastMsg.content.prev && lastMsg.content.reason">
+                                    : {{ lastMsg.content.reason }}
                                 </span>
                             </span>
-                            <span ng-if="'invite' === room.lastMsg.content.membership || 'ban' === room.lastMsg.content.membership">
-                                {{ room.lastMsg.user_id | mUserDisplayName: room.room_id }}
-                                {{ {"invite": "invited", "ban": "banned"}[room.lastMsg.content.membership] }}
-                                {{ room.lastMsg.state_key | mUserDisplayName: room.room_id }}
-                                <span ng-if="'ban' === room.lastMsg.content.prev && room.lastMsg.content.reason">
-                                    : {{ room.lastMsg.content.reason }}
+                            <span ng-if="'invite' === lastMsg.content.membership || 'ban' === lastMsg.content.membership">
+                                {{ lastMsg.user_id | mUserDisplayName: room.room_id }}
+                                {{ {"invite": "invited", "ban": "banned"}[lastMsg.content.membership] }}
+                                {{ lastMsg.state_key | mUserDisplayName: room.room_id }}
+                                <span ng-if="'ban' === lastMsg.content.prev && lastMsg.content.reason">
+                                    : {{ lastMsg.content.reason }}
                                 </span>
                             </span>
                         </div>
 
                         <div ng-switch-when="m.room.message">
-                            <div ng-switch="room.lastMsg.content.msgtype">
+                            <div ng-switch="lastMsg.content.msgtype">
                                 <div ng-switch-when="m.text">
-                                    {{ room.lastMsg.user_id | mUserDisplayName: room.room_id }} :
-                                    <span ng-bind-html="(room.lastMsg.content.body) | linky:'_blank'">
+                                    {{ lastMsg.user_id | mUserDisplayName: room.room_id }} :
+                                    <span ng-bind-html="(lastMsg.content.body) | linky:'_blank'">
                                     </span>
                                 </div>
 
                                 <div ng-switch-when="m.image">
-                                    {{ room.lastMsg.user_id | mUserDisplayName: room.room_id }} sent an image
+                                    {{ lastMsg.user_id | mUserDisplayName: room.room_id }} sent an image
                                 </div>
 
                                 <div ng-switch-when="m.emote">
-                                    <span ng-bind-html="'* ' + (room.lastMsg.user_id | mUserDisplayName: room.room_id) + ' ' + room.lastMsg.content.body | linky:'_blank'">
+                                    <span ng-bind-html="'* ' + (lastMsg.user_id | mUserDisplayName: room.room_id) + ' ' + lastMsg.content.body | linky:'_blank'">
                                     </span>
                                 </div>
 
                                 <div ng-switch-default>
-                                    {{ room.lastMsg.content }}
+                                    {{ lastMsg.content }}
                                 </div>
                             </div>
                         </div>
 
                         <div ng-switch-when="m.room.topic">
-                            {{ room.lastMsg.user_id | mUserDisplayName: room.room_id }} changed the topic to: {{ room.lastMsg.content.topic }}
+                            {{ lastMsg.user_id | mUserDisplayName: room.room_id }} changed the topic to: {{ lastMsg.content.topic }}
                         </div>
 
                         <div ng-switch-when="m.room.name">
-                            {{ room.lastMsg.user_id | mUserDisplayName: room.room_id }} changed the room name to: {{ room.lastMsg.content.name }}
+                            {{ lastMsg.user_id | mUserDisplayName: room.room_id }} changed the room name to: {{ lastMsg.content.name }}
                         </div>
 
                         <div ng-switch-default>
-                            <div ng-if="room.lastMsg.type.indexOf('m.call.') === 0">
+                            <div ng-if="lastMsg.type.indexOf('m.call.') === 0">
                                 Call
                             </div>
                         </div>