summary refs log tree commit diff
path: root/syweb/webclient
diff options
context:
space:
mode:
Diffstat (limited to 'syweb/webclient')
-rw-r--r--syweb/webclient/components/matrix/event-handler-service.js73
-rw-r--r--syweb/webclient/room/room-controller.js173
2 files changed, 101 insertions, 145 deletions
diff --git a/syweb/webclient/components/matrix/event-handler-service.js b/syweb/webclient/components/matrix/event-handler-service.js
index 2d8f25f0b4..de0436d209 100644
--- a/syweb/webclient/components/matrix/event-handler-service.js
+++ b/syweb/webclient/components/matrix/event-handler-service.js
@@ -50,11 +50,6 @@ function(matrixService, $rootScope, $q, $timeout, $filter, mPresence, notificati
         eventMap = {};
     };
     reset();
-
-    var resetRoomMessages = function(room_id) {
-        var room = modelService.getRoom(room_id);
-        room.events = [];
-    };
     
     // Generic method to handle events data
     var handleRoomStateEvent = function(event, isLiveEvent, addToRoomMessages) {
@@ -318,7 +313,30 @@ function(matrixService, $rootScope, $q, $timeout, $filter, mPresence, notificati
 
             console.log("Redacted an event.");
         }
-    }
+    };
+    
+    // resolves a room ID or alias, returning a deferred.
+    var resolveRoomIdentifier = function(roomIdOrAlias) {
+        var defer = $q.defer();
+        if ('#' === roomIdOrAlias[0]) {
+            matrixService.resolveRoomAlias(roomIdOrAlias).then(function(response) {
+                defer.resolve(response.data.room_id);
+                console.log("resolveRoomIdentifier: "+roomIdOrAlias+" -> " + response.data.room_id);
+            },
+            function(err) {
+                console.error("resolveRoomIdentifier: lookup failed. "+JSON.stringify(err.data));
+                defer.reject(err.data);
+            });
+        }
+        else if ('!' === roomIdOrAlias[0]) {
+            defer.resolve(roomIdOrAlias);
+        }
+        else {
+            console.error("resolveRoomIdentifier: Unknown roomIdOrAlias => "+roomIdOrAlias);
+            defer.reject("Bad room identifier: "+roomIdOrAlias);
+        }
+        return defer.promise;
+    };
 
     return {
         ROOM_CREATE_EVENT: ROOM_CREATE_EVENT,
@@ -337,7 +355,6 @@ function(matrixService, $rootScope, $q, $timeout, $filter, mPresence, notificati
         },
     
         handleEvent: function(event, isLiveEvent, isStateEvent) {
-
             // Avoid duplicated events
             // Needed for rooms where initialSync has not been done. 
             // In this case, we do not know where to start pagination. So, it starts from the END
@@ -488,15 +505,49 @@ function(matrixService, $rootScope, $q, $timeout, $filter, mPresence, notificati
 
             initialSyncDeferred.resolve(response);
         },
+        
+        // joins a room and handles the requests which need to be done e.g. getting room state
+        joinRoom: function(roomIdOrAlias) {
+            var defer = $q.defer();
+            var eventHandlerService = this;
+            
+            var errorFunc = function(error) {
+                console.error("joinRoom: " + JSON.stringify(error));
+                defer.reject(error);
+            };
+            
+            resolveRoomIdentifier(roomIdOrAlias).then(function(roomId) {
+                // check if you are joined already
+                eventHandlerService.waitForInitialSyncCompletion().then(function() {
+                    var members = modelService.getRoom(roomId).current_room_state.members;
+                    var me = matrixService.config().user_id;
+                    if (me in members) {
+                        if ("join" === members[me].event.content.membership) {
+                            console.log("joinRoom: Already joined room "+roomId);
+                            defer.resolve(roomId);
+                            return;
+                        }
+                    }
+                    // join the room and get current room state
+                    matrixService.join(roomId).then(function() {
+                        matrixService.roomState(roomId).then(function(response) {
+                            var room = modelService.getRoom(roomId);
+                            room.current_room_state.storeStateEvents(response.data);
+                            room.old_room_state.storeStateEvents(response.data);
+                            console.log("joinRoom: Joined room "+roomId);
+                            defer.resolve(roomId);
+                        }, errorFunc);
+                    }, errorFunc);
+                }, errorFunc);
+            }, errorFunc);
+            
+            return defer.promise;
+        },
 
         // Returns a promise that resolves when the initialSync request has been processed
         waitForInitialSyncCompletion: function() {
             return initialSyncDeferred.promise;
         },
-
-        resetRoomMessages: function(room_id) {
-            resetRoomMessages(room_id);
-        },
         
         eventContainsBingWord: function(event) {
             return containsBingWord(event);
diff --git a/syweb/webclient/room/room-controller.js b/syweb/webclient/room/room-controller.js
index fdd10d7c9a..df05a8e573 100644
--- a/syweb/webclient/room/room-controller.js
+++ b/syweb/webclient/room/room-controller.js
@@ -26,7 +26,6 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput', 'a
 
     // Room ids. Computed and resolved in onInit
     $scope.room_id = undefined;
-    $scope.room_alias = undefined;
 
     $scope.state = {
         user_id: matrixService.config().user_id,
@@ -157,13 +156,8 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput', 'a
     $scope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) {
         // if there is a live event affecting us
         if (isLive && event.room_id === $scope.room_id && event.state_key === $scope.state.user_id) {
-            if ($scope.state.waiting_for_joined_event) {
-                // The user has successfully joined the room, we can getting data for this room
-                $scope.state.waiting_for_joined_event = false;
-                onInit3();
-            }
             // if someone else changed our state..
-            else if (event.user_id !== $scope.state.user_id && "invite" !== event.content.membership && "join" !== event.content.membership) {    
+            if (event.user_id !== $scope.state.user_id && "invite" !== event.content.membership && "join" !== event.content.membership) {    
                 if ("ban" === event.content.membership) {
                     $scope.state.permission_denied = "You have been banned by " + mUserDisplayNameFilter(event.user_id);
                 }
@@ -343,145 +337,56 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput', 'a
     $scope.onInit = function() {
         console.log("onInit");
 
-        // Try to find out the room ID to load.
+        // Extract the room identifier being loaded
         var room_id_or_alias;
         if ($routeParams.room_id_or_alias) { // provided in the url
             room_id_or_alias = decodeURIComponent($routeParams.room_id_or_alias);
         }
+        
+        eventHandlerService.joinRoom(room_id_or_alias).then(function(roomId) {
+            $scope.room_id = roomId;
+            $scope.room = modelService.getRoom($scope.room_id);
+            
+            var messages = $scope.room.events;
 
-        if (room_id_or_alias && '!' === room_id_or_alias[0]) {
-            // it's a room ID since they start with !
-            $scope.room_id = room_id_or_alias;
-            $scope.room_alias = modelService.getRoomIdToAliasMapping($scope.room_id);
-            onInit2();
-        }
-        else {
-            if (room_id_or_alias && '#' === room_id_or_alias[0]) {
-                $scope.room_alias = room_id_or_alias;
+            if (0 === messages.length
+            || (1 === messages.length && "m.room.member" === messages[0].type && "invite" === messages[0].content.membership && $scope.state.user_id === messages[0].state_key)) {
+                // If we just joined a room, we won't have this history from initial sync, so we should try to paginate it anyway    
+                $scope.state.first_pagination = true;
             }
-            else  {
-                // Else get the room alias by hand from the URL
-                // ie: extract #public:localhost:8080 from http://127.0.0.1:8000/#/room/#public:localhost:8080
-                if (3 === location.hash.split("#").length) {
-                    $scope.room_alias = "#" + location.hash.split("#")[2];
-                }
-                else {
-                    // In case of issue, go to the default page
-                    console.log("Error: cannot extract room alias");
-                    $location.url("/");
-                    return;
-                }
+            else {
+                // There is no need to do a 1st pagination (initialSync provided enough to fill a page)
+                $scope.state.first_pagination = false;
             }
             
-            // Need a room ID required in Matrix API requests
-            console.log("Resolving alias: " + $scope.room_alias);
-            matrixService.resolveRoomAlias($scope.room_alias).then(function(response) {
-                $scope.room_id = response.data.room_id;
-                console.log("   -> Room ID: " + $scope.room_id);
-
-                // Now, we can go on
-                onInit2();
-            },
-            function () {
-                // In case of issue, go to the default page
-                console.log("Error: cannot resolve room alias");
-                $location.url("/");
-            });
-        }
-    };
-    
-    var onInit2 = function() {
-        $scope.room = modelService.getRoom($scope.room_id);
-        
-        // Scroll down as soon as possible so that we point to the last message
-        // if it already exists in memory
-        scrollToBottom(true);
-
-        // Make sure the initialSync has been before going further
-        eventHandlerService.waitForInitialSyncCompletion().then(
-            function() {
-                console.log("initialSync is complete.");
-                var needsToJoin = true;
-                
-                // The room members is available in the data fetched by initialSync
-                if ($scope.room) {
-                    var messages = $scope.room.events;
-
-                    if (0 === messages.length
-                    || (1 === messages.length && "m.room.member" === messages[0].type && "invite" === messages[0].content.membership && $scope.state.user_id === messages[0].state_key)) {
-                        // If we just joined a room, we won't have this history from initial sync, so we should try to paginate it anyway    
-                        $scope.state.first_pagination = true;
-                    }
-                    else {
-                        // There is no need to do a 1st pagination (initialSync provided enough to fill a page)
-                        $scope.state.first_pagination = false;
-                    }
+            // Make recents highlight the current room
+            recentsService.setSelectedRoomId($scope.room_id);
+            
+            updatePresenceTimes();
 
-                    var members = $scope.room.current_room_state.members;
+            // Allow pagination
+            $scope.state.can_paginate = true;
 
-                    // Check if the user has already join the room
-                    if ($scope.state.user_id in members) {
-                        if ("join" === members[$scope.state.user_id].event.content.membership) {
-                            needsToJoin = false;
-                        }
-                    }
-                }
-                
-                // Do we to join the room before starting?
-                if (needsToJoin) {
-                    $scope.state.waiting_for_joined_event = true;
-                    matrixService.join($scope.room_id).then(
-                        function() {
-                            // TODO: factor out the common housekeeping whenever we try to join a room or alias
-                            matrixService.roomState($scope.room_id).then(
-                                function(response) {
-                                    eventHandlerService.handleEvents(response.data, false, true);
-                                },
-                                function(error) {
-                                    console.error("Failed to get room state for: " + $scope.room_id);
-                                }
-                            );                                        
-                            
-                            // onInit3 will be called once the joined m.room.member event is received from the events stream
-                            // This avoids to get the joined information twice in parallel:
-                            //    - one from the events stream
-                            //    - one from the pagination because the pagination window covers this event ts
-                            console.log("Joined room "+$scope.room_id);
-                        },
-                        function(reason) {
-                            console.log("Can't join room: " + JSON.stringify(reason));
-                            // FIXME: what if it wasn't a perms problem?
-                            $scope.state.permission_denied = "You do not have permission to join this room";
-                        });
-                }
-                else {
-                    onInit3();
-                }
+            // Do a first pagination only if it is required (e.g. we've JUST joined a room and have no messages to display.)
+            // FIXME: Should be no more require when initialSync/{room_id} will be available
+            if ($scope.state.first_pagination) {
+                paginate(MESSAGES_PER_PAGINATION);
             }
-        );
-    };
-
-    var onInit3 = function() {
-        console.log("onInit3");
-
-        // Make recents highlight the current room
-        recentsService.setSelectedRoomId($scope.room_id);
-        
-        updatePresenceTimes();
-
-        // Allow pagination
-        $scope.state.can_paginate = true;
-
-        // Do a first pagination only if it is required
-        // FIXME: Should be no more require when initialSync/{room_id} will be available
-        if ($scope.state.first_pagination) {
-            paginate(MESSAGES_PER_PAGINATION);
-        }
-        else {
-            // There are already messages, go to the last message
+            
+            // Scroll down as soon as possible so that we point to the last message
+            // if it already exists in memory
             scrollToBottom(true);
-        }
-    }; 
+        },
+        function(err) {
+            if (err.data.errcode === "M_FORBIDDEN") {
+                $scope.state.permission_denied = "You do not have permission to join this room";
+            }
+            else {
+                console.log("Error: cannot join room: "+JSON.stringify(err));
+                $location.url("/");
+            }
+        });
+    };
 
     $scope.leaveRoom = function() {