diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js
index 6ea0f58bc5..df61429db5 100644
--- a/webclient/components/matrix/event-handler-service.js
+++ b/webclient/components/matrix/event-handler-service.js
@@ -27,13 +27,15 @@ Typically, this service will store events or broadcast them to any listeners
if typically all the $on method would do is update its own $scope.
*/
angular.module('eventHandlerService', [])
-.factory('eventHandlerService', ['matrixService', '$rootScope', function(matrixService, $rootScope) {
+.factory('eventHandlerService', ['matrixService', '$rootScope', '$q', function(matrixService, $rootScope, $q) {
var MSG_EVENT = "MSG_EVENT";
var MEMBER_EVENT = "MEMBER_EVENT";
var PRESENCE_EVENT = "PRESENCE_EVENT";
+
+ var InitialSyncDeferred = $q.defer();
$rootScope.events = {
- rooms: {}, // will contain roomId: { messages:[], members:{userid1: event} }
+ rooms: {} // will contain roomId: { messages:[], members:{userid1: event} }
};
$rootScope.presence = {};
@@ -47,11 +49,11 @@ angular.module('eventHandlerService', [])
}
}
- var reInitRoom = function(room_id) {
- $rootScope.events.rooms[room_id] = {};
- $rootScope.events.rooms[room_id].messages = [];
- $rootScope.events.rooms[room_id].members = {};
- }
+ var resetRoomMessages = function(room_id) {
+ if ($rootScope.events.rooms[room_id]) {
+ $rootScope.events.rooms[room_id].messages = [];
+ }
+ };
var handleMessage = function(event, isLiveEvent) {
initRoom(event.room_id);
@@ -125,8 +127,18 @@ angular.module('eventHandlerService', [])
}
},
- reInitRoom: function(room_id) {
- reInitRoom(room_id);
+ handleInitialSyncDone: function() {
+ console.log("# handleInitialSyncDone");
+ InitialSyncDeferred.resolve($rootScope.events, $rootScope.presence);
},
+
+ // Returns a promise that resolves when the initialSync request has been processed
+ waitForInitialSyncCompletion: function() {
+ return InitialSyncDeferred.promise;
+ },
+
+ resetRoomMessages: function(room_id) {
+ resetRoomMessages(room_id);
+ }
};
}]);
diff --git a/webclient/components/matrix/event-stream-service.js b/webclient/components/matrix/event-stream-service.js
index a1a98b2a36..4cc2bf4c4e 100644
--- a/webclient/components/matrix/event-stream-service.js
+++ b/webclient/components/matrix/event-stream-service.js
@@ -96,7 +96,7 @@ angular.module('eventStreamService', [])
);
return deferred.promise;
- }
+ };
var startEventStream = function() {
settings.shouldPoll = true;
@@ -110,18 +110,17 @@ angular.module('eventStreamService', [])
for (var i = 0; i < rooms.length; ++i) {
var room = rooms[i];
if ("state" in room) {
- for (var j = 0; j < room.state.length; ++j) {
- eventHandlerService.handleEvents(room.state[j], false);
- }
+ eventHandlerService.handleEvents(room.state, false);
}
}
var presence = response.data.presence;
- for (var i = 0; i < presence.length; ++i) {
- eventHandlerService.handleEvent(presence[i], false);
- }
+ eventHandlerService.handleEvents(presence, false);
+
+ // Initial sync is done
+ eventHandlerService.handleInitialSyncDone();
- settings.from = response.data.end
+ settings.from = response.data.end;
doEventStream(deferred);
},
function(error) {
diff --git a/webclient/home/home-controller.js b/webclient/home/home-controller.js
index 62f6ef2d95..008dff7422 100644
--- a/webclient/home/home-controller.js
+++ b/webclient/home/home-controller.js
@@ -17,8 +17,8 @@ limitations under the License.
'use strict';
angular.module('HomeController', ['matrixService', 'eventHandlerService', 'RecentsController'])
-.controller('HomeController', ['$scope', '$location', 'matrixService', 'eventHandlerService', 'eventStreamService',
- function($scope, $location, matrixService, eventHandlerService, eventStreamService) {
+.controller('HomeController', ['$scope', '$location', 'matrixService',
+ function($scope, $location, matrixService) {
$scope.config = matrixService.config();
$scope.public_rooms = [];
diff --git a/webclient/recents/recents-controller.js b/webclient/recents/recents-controller.js
index bf6a1b8874..803ab420f9 100644
--- a/webclient/recents/recents-controller.js
+++ b/webclient/recents/recents-controller.js
@@ -17,21 +17,32 @@
'use strict';
angular.module('RecentsController', ['matrixService', 'eventHandlerService'])
-.controller('RecentsController', ['$scope', 'matrixService', 'eventHandlerService', 'eventStreamService',
- function($scope, matrixService, eventHandlerService, eventStreamService) {
+.controller('RecentsController', ['$scope', 'matrixService', 'eventHandlerService',
+ function($scope, matrixService, eventHandlerService) {
$scope.rooms = {};
// $scope of the parent where the recents component is included can override this value
// in order to highlight a specific room in the list
$scope.recentsSelectedRoomID;
- // Refresh the list on matrix invitation and message event
- $scope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) {
- refresh();
- });
- $scope.$on(eventHandlerService.MSG_EVENT, function(ngEvent, event, isLive) {
- refresh();
- });
+ var listenToEventStream = function() {
+ // Refresh the list on matrix invitation and message event
+ $scope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) {
+ var config = matrixService.config();
+ if (event.state_key === config.user_id && event.content.membership === "invite") {
+ console.log("Invited to room " + event.room_id);
+ // FIXME push membership to top level key to match /im/sync
+ event.membership = event.content.membership;
+ // FIXME bodge a nicer name than the room ID for this invite.
+ event.room_display_name = event.user_id + "'s room";
+ $scope.rooms[event.room_id] = event;
+ }
+ });
+ $scope.$on(eventHandlerService.MSG_EVENT, function(ngEvent, event, isLive) {
+ $scope.rooms[event.room_id].lastMsg = event;
+ });
+ };
+
var refresh = function() {
// List all rooms joined or been invited to
@@ -56,6 +67,9 @@ angular.module('RecentsController', ['matrixService', 'eventHandlerService'])
for (var i = 0; i < presence.length; ++i) {
eventHandlerService.handleEvent(presence[i], false);
}
+
+ // From now, update recents from the stream
+ listenToEventStream();
},
function(error) {
$scope.feedback = "Failure: " + error.data;
diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js
index e775d88570..910168754c 100644
--- a/webclient/room/room-controller.js
+++ b/webclient/room/room-controller.js
@@ -15,8 +15,8 @@ limitations under the License.
*/
angular.module('RoomController', ['ngSanitize', 'mFileInput', 'mUtilities'])
-.controller('RoomController', ['$scope', '$http', '$timeout', '$routeParams', '$location', 'matrixService', 'eventStreamService', 'eventHandlerService', 'mFileUpload', 'mUtilities', '$rootScope',
- function($scope, $http, $timeout, $routeParams, $location, matrixService, eventStreamService, eventHandlerService, mFileUpload, mUtilities, $rootScope) {
+.controller('RoomController', ['$scope', '$http', '$timeout', '$routeParams', '$location', 'matrixService', 'eventHandlerService', 'mFileUpload', 'mUtilities', '$rootScope',
+ function($scope, $http, $timeout, $routeParams, $location, matrixService, eventHandlerService, mFileUpload, mUtilities, $rootScope) {
'use strict';
var MESSAGES_PER_PAGINATION = 30;
var THUMBNAIL_SIZE = 320;
@@ -282,7 +282,7 @@ angular.module('RoomController', ['ngSanitize', 'mFileInput', 'mUtilities'])
}
if (room_id_or_alias && '!' === room_id_or_alias[0]) {
- // Yes. We can start right now
+ // Yes. We can go on right now
$scope.room_id = room_id_or_alias;
$scope.room_alias = matrixService.getRoomIdToAliasMapping($scope.room_id);
onInit2();
@@ -313,7 +313,7 @@ angular.module('RoomController', ['ngSanitize', 'mFileInput', 'mUtilities'])
$scope.room_id = response.data.room_id;
console.log(" -> Room ID: " + $scope.room_id);
- // Now, we can start
+ // Now, we can go on
onInit2();
},
function () {
@@ -323,36 +323,61 @@ angular.module('RoomController', ['ngSanitize', 'mFileInput', 'mUtilities'])
});
}
};
-
+
var onInit2 = function() {
- eventHandlerService.reInitRoom($scope.room_id);
-
- // Make recents highlight the current room
- $scope.recentsSelectedRoomID = $scope.room_id;
-
- // Join the room
- matrixService.join($scope.room_id).then(
+ console.log("onInit2");
+
+ // Make sure the initialSync has been before going further
+ eventHandlerService.waitForInitialSyncCompletion().then(
function() {
- console.log("Joined room "+$scope.room_id);
+ var needsToJoin = true;
+
+ // The room members is available in the data fetched by initialSync
+ if ($rootScope.events.rooms[$scope.room_id]) {
+ var members = $rootScope.events.rooms[$scope.room_id].members;
+
+ // Update the member list
+ for (var i in members) {
+ var member = members[i];
+ updateMemberList(member);
+ }
- // Get the current member list
- matrixService.getMemberList($scope.room_id).then(
- function(response) {
- for (var i = 0; i < response.data.chunk.length; i++) {
- var chunk = response.data.chunk[i];
- updateMemberList(chunk);
+ // Check if the user has already join the room
+ if ($scope.state.user_id in members) {
+ if ("join" === members[$scope.state.user_id].membership) {
+ needsToJoin = false;
}
- },
- function(error) {
- $scope.feedback = "Failed get member list: " + error.data.error;
}
- );
+ }
- paginate(MESSAGES_PER_PAGINATION);
- },
- function(reason) {
- $scope.feedback = "Can't join room: " + reason;
- });
+ // Do we to join the room before starting?
+ if (needsToJoin) {
+ matrixService.join($scope.room_id).then(
+ function() {
+ console.log("Joined room "+$scope.room_id);
+ onInit3();
+ },
+ function(reason) {
+ $scope.feedback = "Can't join room: " + reason;
+ });
+ }
+ else {
+ onInit3();
+ }
+ }
+ );
+ };
+
+ var onInit3 = function() {
+ console.log("onInit3");
+
+ // TODO: We should be able to keep them
+ eventHandlerService.resetRoomMessages($scope.room_id);
+
+ // Make recents highlight the current room
+ $scope.recentsSelectedRoomID = $scope.room_id;
+
+ paginate(MESSAGES_PER_PAGINATION);
};
$scope.inviteUser = function(user_id) {
|