diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js
index 470f41521a..fb6e2025fc 100644
--- a/webclient/room/room-controller.js
+++ b/webclient/room/room-controller.js
@@ -18,11 +18,15 @@ angular.module('RoomController', [])
.controller('RoomController', ['$scope', '$http', '$timeout', '$routeParams', '$location', 'matrixService',
function($scope, $http, $timeout, $routeParams, $location, matrixService) {
'use strict';
+ var MESSAGES_PER_PAGINATION = 10;
$scope.room_id = $routeParams.room_id;
$scope.room_alias = matrixService.getRoomIdToAliasMapping($scope.room_id);
$scope.state = {
user_id: matrixService.config().user_id,
- events_from: "START"
+ events_from: "END", // when to start the event stream from.
+ earliest_token: "END", // stores how far back we've paginated.
+ can_paginate: true, // this is toggled off when we run out of items
+ stream_failure: undefined // the response when the stream fails
};
$scope.messages = [];
$scope.members = {};
@@ -30,6 +34,53 @@ angular.module('RoomController', [])
$scope.imageURLToSend = "";
$scope.userIDToInvite = "";
+
+ var scrollToBottom = function() {
+ $timeout(function() {
+ var objDiv = document.getElementsByClassName("messageTableWrapper")[0];
+ objDiv.scrollTop = objDiv.scrollHeight;
+ },0);
+ };
+
+ var parseChunk = function(chunks, appendToStart) {
+ for (var i = 0; i < chunks.length; i++) {
+ var chunk = chunks[i];
+ if (chunk.room_id == $scope.room_id && chunk.type == "m.room.message") {
+ if ("membership_target" in chunk.content) {
+ chunk.user_id = chunk.content.membership_target;
+ }
+ if (appendToStart) {
+ $scope.messages.unshift(chunk);
+ }
+ else {
+ $scope.messages.push(chunk);
+ scrollToBottom();
+ }
+ }
+ else if (chunk.room_id == $scope.room_id && chunk.type == "m.room.member") {
+ updateMemberList(chunk);
+ }
+ else if (chunk.type === "m.presence") {
+ updatePresence(chunk);
+ }
+ }
+ };
+
+ var paginate = function(numItems) {
+ matrixService.paginateBackMessages($scope.room_id, $scope.state.earliest_token, numItems).then(
+ function(response) {
+ parseChunk(response.data.chunk, true);
+ $scope.state.earliest_token = response.data.end;
+ if (response.data.chunk.length < MESSAGES_PER_PAGINATION) {
+ // no more messages to paginate :(
+ $scope.state.can_paginate = false;
+ }
+ },
+ function(error) {
+ console.log("Failed to paginateBackMessages: " + JSON.stringify(error));
+ }
+ )
+ };
var shortPoll = function() {
$http.get(matrixService.config().homeserver + matrixService.prefix + "/events", {
@@ -39,30 +90,13 @@ angular.module('RoomController', [])
"timeout": 5000
}})
.then(function(response) {
+ $scope.state.stream_failure = undefined;
console.log("Got response from "+$scope.state.events_from+" to "+response.data.end);
$scope.state.events_from = response.data.end;
-
$scope.feedback = "";
- for (var i = 0; i < response.data.chunk.length; i++) {
- var chunk = response.data.chunk[i];
- if (chunk.room_id == $scope.room_id && chunk.type == "m.room.message") {
- if ("membership_target" in chunk.content) {
- chunk.user_id = chunk.content.membership_target;
- }
- $scope.messages.push(chunk);
- $timeout(function() {
- var objDiv = document.getElementsByClassName("messageTableWrapper")[0];
- objDiv.scrollTop = objDiv.scrollHeight;
- },0);
- }
- else if (chunk.room_id == $scope.room_id && chunk.type == "m.room.member") {
- updateMemberList(chunk);
- }
- else if (chunk.type === "m.presence") {
- updatePresence(chunk);
- }
- }
+ parseChunk(response.data.chunk, false);
+
if ($scope.stopPoll) {
console.log("Stopping polling.");
}
@@ -70,7 +104,7 @@ angular.module('RoomController', [])
$timeout(shortPoll, 0);
}
}, function(response) {
- $scope.feedback = "Can't stream: " + response.data;
+ $scope.state.stream_failure = response;
if (response.status == 403) {
$scope.stopPoll = true;
@@ -99,8 +133,8 @@ angular.module('RoomController', [])
function(response) {
var member = $scope.members[chunk.target_user_id];
if (member !== undefined) {
- console.log("Updated displayname "+chunk.target_user_id+" to " + response.displayname);
- member.displayname = response.displayname;
+ console.log("Updated displayname "+chunk.target_user_id+" to " + response.data.displayname);
+ member.displayname = response.data.displayname;
}
}
);
@@ -108,8 +142,8 @@ angular.module('RoomController', [])
function(response) {
var member = $scope.members[chunk.target_user_id];
if (member !== undefined) {
- console.log("Updated image for "+chunk.target_user_id+" to " + response.avatar_url);
- member.avatar_url = response.avatar_url;
+ console.log("Updated image for "+chunk.target_user_id+" to " + response.data.avatar_url);
+ member.avatar_url = response.data.avatar_url;
}
}
);
@@ -171,8 +205,8 @@ angular.module('RoomController', [])
console.log("Sent message");
$scope.textInput = "";
},
- function(reason) {
- $scope.feedback = "Failed to send: " + reason;
+ function(error) {
+ $scope.feedback = "Failed to send: " + error.data.error;
});
};
@@ -183,22 +217,24 @@ angular.module('RoomController', [])
// Join the room
matrixService.join($scope.room_id).then(
function() {
- console.log("Joined room");
+ console.log("Joined room "+$scope.room_id);
// Now start reading from the stream
$timeout(shortPoll, 0);
// Get the current member list
matrixService.getMemberList($scope.room_id).then(
function(response) {
- for (var i = 0; i < response.chunk.length; i++) {
- var chunk = response.chunk[i];
+ for (var i = 0; i < response.data.chunk.length; i++) {
+ var chunk = response.data.chunk[i];
updateMemberList(chunk);
}
},
- function(reason) {
- $scope.feedback = "Failed get member list: " + reason;
+ function(error) {
+ $scope.feedback = "Failed get member list: " + error.data.error;
}
);
+
+ paginate(MESSAGES_PER_PAGINATION);
},
function(reason) {
$scope.feedback = "Can't join room: " + reason;
@@ -224,8 +260,8 @@ angular.module('RoomController', [])
console.log("Left room ");
$location.path("rooms");
},
- function(reason) {
- $scope.feedback = "Failed to leave room: " + reason;
+ function(error) {
+ $scope.feedback = "Failed to leave room: " + error.data.error;
});
};
@@ -234,10 +270,14 @@ angular.module('RoomController', [])
function() {
console.log("Image sent");
},
- function(reason) {
- $scope.feedback = "Failed to send image: " + reason;
+ function(error) {
+ $scope.feedback = "Failed to send image: " + error.data.error;
});
};
+
+ $scope.loadMoreHistory = function() {
+ paginate(MESSAGES_PER_PAGINATION);
+ };
$scope.$on('$destroy', function(e) {
console.log("onDestroyed: Stopping poll.");
|