From b63dd9506ea286f8bdaffd213fa79a382933eb35 Mon Sep 17 00:00:00 2001 From: Emmanuel ROHEE Date: Wed, 10 Sep 2014 12:01:00 +0200 Subject: [PATCH] Improved requests: pagination is done from the data received in initialSync --- .../matrix/event-handler-service.js | 28 +++++++++++++++---- .../components/matrix/event-stream-service.js | 9 +++++- webclient/room/room-controller.js | 16 +++++------ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js index 94ac91db5e..24d634a28b 100644 --- a/webclient/components/matrix/event-handler-service.js +++ b/webclient/components/matrix/event-handler-service.js @@ -55,6 +55,11 @@ angular.module('eventHandlerService', []) $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 + } } }; @@ -187,17 +192,21 @@ angular.module('eventHandlerService', []) NAME_EVENT: NAME_EVENT, handleEvent: function(event, isLiveEvent) { - // FIXME: event duplication suppression is all broken as the code currently expect to handles - // events multiple times to get their side-effects... -/* + // 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 + // and we can have the same event (ex: joined, invitation) coming from the pagination + // AND from the event stream. + // FIXME: This workaround should be no more required when /initialSync on a particular room + // will be available (as opposite to the global /initialSync done at startup) if (eventMap[event.event_id]) { - console.log("discarding duplicate event: " + JSON.stringify(event)); + console.log("discarding duplicate event: " + JSON.stringify(event, undefined, 4)); return; } else { eventMap[event.event_id] = 1; } -*/ + if (event.type.indexOf('m.call.') === 0) { handleCallEvent(event, isLiveEvent); } @@ -247,6 +256,15 @@ angular.module('eventHandlerService', []) } }, + // Handle messages from /initialSync or /messages + handleRoomMessages: function(room_id, messages, isLiveEvents) { + this.handleEvents(messages.chunk); + + // Store how far back we've paginated + // This assumes the paginations requests are contiguous and in reverse chronological order + $rootScope.events.rooms[room_id].pagination.earliest_token = messages.end; + }, + handleInitialSyncDone: function(initialSyncData) { console.log("# handleInitialSyncDone"); initialSyncDeferred.resolve(initialSyncData); diff --git a/webclient/components/matrix/event-stream-service.js b/webclient/components/matrix/event-stream-service.js index 1bc850a8fa..d7ccc63e89 100644 --- a/webclient/components/matrix/event-stream-service.js +++ b/webclient/components/matrix/event-stream-service.js @@ -112,9 +112,16 @@ angular.module('eventStreamService', []) var rooms = response.data.rooms; for (var i = 0; i < rooms.length; ++i) { var room = rooms[i]; + // console.log("got room: " + room.room_id); if ("state" in room) { - eventHandlerService.handleEvents(room.state, false); + //eventHandlerService.handleEvents(room.state, false); + } + + if ("messages" in room) { + eventHandlerService.handleRoomMessages(room.room_id, room.messages, false); + + console.log(room.messages.start + " - " + room.messages.end); } } diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js index 3d75ef5499..9bb0d8e2d4 100644 --- a/webclient/room/room-controller.js +++ b/webclient/room/room-controller.js @@ -27,8 +27,6 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) $scope.state = { user_id: matrixService.config().user_id, - events_from: "END", // when to start the event stream from. - earliest_token: "END", // stores how far back we've paginated. first_pagination: true, // this is toggled off when the first pagination is done can_paginate: false, // this is toggled off when we are not ready yet to paginate or when we run out of items paginating: false, // used to avoid concurrent pagination requests pulling in dup contents @@ -159,12 +157,15 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) else { $scope.state.paginating = true; } - // console.log("paginateBackMessages from " + $scope.state.earliest_token + " for " + numItems); + + console.log("paginateBackMessages from " + $rootScope.events.rooms[$scope.room_id].pagination.earliest_token + " for " + numItems); var originalTopRow = $("#messageTable>tbody>tr:first")[0]; - matrixService.paginateBackMessages($scope.room_id, $scope.state.earliest_token, numItems).then( + + // Paginate events from the point in cache + matrixService.paginateBackMessages($scope.room_id, $rootScope.events.rooms[$scope.room_id].pagination.earliest_token, numItems).then( function(response) { - eventHandlerService.handleEvents(response.data.chunk, false); - $scope.state.earliest_token = response.data.end; + + eventHandlerService.handleRoomMessages($scope.room_id, response.data, false); if (response.data.chunk.length < MESSAGES_PER_PAGINATION) { // no more messages to paginate. this currently never gets turned true again, as we never // expire paginated contents in the current implementation. @@ -659,9 +660,6 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) 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;