diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js
index 7514770583..2f7580d682 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);
@@ -124,8 +126,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..441148670e 100644
--- a/webclient/components/matrix/event-stream-service.js
+++ b/webclient/components/matrix/event-stream-service.js
@@ -25,7 +25,8 @@ the eventHandlerService.
angular.module('eventStreamService', [])
.factory('eventStreamService', ['$q', '$timeout', 'matrixService', 'eventHandlerService', function($q, $timeout, matrixService, eventHandlerService) {
var END = "END";
- var TIMEOUT_MS = 30000;
+ var SERVER_TIMEOUT_MS = 30000;
+ var CLIENT_TIMEOUT_MS = 40000;
var ERR_TIMEOUT_MS = 5000;
var settings = {
@@ -55,7 +56,7 @@ angular.module('eventStreamService', [])
deferred = deferred || $q.defer();
// run the stream from the latest token
- matrixService.getEventStream(settings.from, TIMEOUT_MS).then(
+ matrixService.getEventStream(settings.from, SERVER_TIMEOUT_MS, CLIENT_TIMEOUT_MS).then(
function(response) {
if (!settings.isActive) {
console.log("[EventStream] Got response but now inactive. Dropping data.");
@@ -80,7 +81,7 @@ angular.module('eventStreamService', [])
}
},
function(error) {
- if (error.status == 403) {
+ if (error.status === 403) {
settings.shouldPoll = false;
}
@@ -96,7 +97,7 @@ angular.module('eventStreamService', [])
);
return deferred.promise;
- }
+ };
var startEventStream = function() {
settings.shouldPoll = true;
@@ -110,18 +111,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/components/matrix/matrix-service.js b/webclient/components/matrix/matrix-service.js
index 2feddac5d8..b56eef6af5 100644
--- a/webclient/components/matrix/matrix-service.js
+++ b/webclient/components/matrix/matrix-service.js
@@ -41,7 +41,7 @@ angular.module('matrixService', [])
var prefixPath = "/matrix/client/api/v1";
var MAPPING_PREFIX = "alias_for_";
- var doRequest = function(method, path, params, data) {
+ var doRequest = function(method, path, params, data, $httpParams) {
if (!config) {
console.warn("No config exists. Cannot perform request to "+path);
return;
@@ -58,7 +58,7 @@ angular.module('matrixService', [])
path = prefixPath + path;
}
- return doBaseRequest(config.homeserver, method, path, params, data, undefined);
+ return doBaseRequest(config.homeserver, method, path, params, data, undefined, $httpParams);
};
var doBaseRequest = function(baseUrl, method, path, params, data, headers, $httpParams) {
@@ -343,15 +343,31 @@ angular.module('matrixService', [])
return doBaseRequest(config.homeserver, "POST", path, params, file, headers, $httpParams);
},
-
- // start listening on /events
- getEventStream: function(from, timeout) {
+
+ /**
+ * Start listening on /events
+ * @param {String} from the token from which to listen events to
+ * @param {Integer} serverTimeout the time in ms the server will hold open the connection
+ * @param {Integer} clientTimeout the timeout in ms used at the client HTTP request level
+ * @returns a promise
+ */
+ getEventStream: function(from, serverTimeout, clientTimeout) {
var path = "/events";
var params = {
from: from,
- timeout: timeout
+ timeout: serverTimeout
};
- return doRequest("GET", path, params);
+
+ var $httpParams;
+ if (clientTimeout) {
+ // If the Internet connection is lost, this timeout is used to be able to
+ // cancel the current request and notify the client so that it can retry with a new request.
+ $httpParams = {
+ timeout: clientTimeout
+ };
+ }
+
+ return doRequest("GET", path, params, undefined, $httpParams);
},
// Indicates if user authentications details are stored in cache
@@ -420,34 +436,38 @@ angular.module('matrixService', [])
/****** Room aliases management ******/
/**
- * Enhance data returned by rooms() and publicRooms() by adding room_alias
- * & room_display_name which are computed from data already retrieved from the server.
- * @param {Array} data the response of rooms() and publicRooms()
- * @returns {Array} the same array with enriched objects
+ * Get the room_alias & room_display_name which are computed from data
+ * already retrieved from the server.
+ * @param {Room object} room one element of the array returned by the response
+ * of rooms() and publicRooms()
+ * @returns {Object} {room_alias: "...", room_display_name: "..."}
*/
- assignRoomAliases: function(data) {
- for (var i=0; i<data.length; i++) {
- var alias = this.getRoomIdToAliasMapping(data[i].room_id);
- if (alias) {
- // use the existing alias from storage
- data[i].room_alias = alias;
- data[i].room_display_name = alias;
- }
- else if (data[i].aliases && data[i].aliases[0]) {
- // save the mapping
- // TODO: select the smarter alias from the array
- this.createRoomIdToAliasMapping(data[i].room_id, data[i].aliases[0]);
- data[i].room_display_name = data[i].aliases[0];
- }
- else if (data[i].membership == "invite" && "inviter" in data[i]) {
- data[i].room_display_name = data[i].inviter + "'s room"
- }
- else {
- // last resort use the room id
- data[i].room_display_name = data[i].room_id;
- }
+ getRoomAliasAndDisplayName: function(room) {
+ var result = {
+ room_alias: undefined,
+ room_display_name: undefined
+ };
+
+ var alias = this.getRoomIdToAliasMapping(room.room_id);
+ if (alias) {
+ // use the existing alias from storage
+ result.room_alias = alias;
+ result.room_display_name = alias;
+ }
+ else if (room.aliases && room.aliases[0]) {
+ // save the mapping
+ // TODO: select the smarter alias from the array
+ this.createRoomIdToAliasMapping(room.room_id, room.aliases[0]);
+ result.room_display_name = room.aliases[0];
+ }
+ else if (room.membership === "invite" && "inviter" in room) {
+ result.room_display_name = room.inviter + "'s room";
+ }
+ else {
+ // last resort use the room id
+ result.room_display_name = room.room_id;
}
- return data;
+ return result;
},
createRoomIdToAliasMapping: function(roomId, alias) {
|