diff options
Diffstat (limited to 'webclient/room')
-rw-r--r-- | webclient/room/room-controller.js | 114 | ||||
-rw-r--r-- | webclient/room/room.html | 6 |
2 files changed, 82 insertions, 38 deletions
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."); diff --git a/webclient/room/room.html b/webclient/room/room.html index 8fc7d5d360..3b9ba713de 100644 --- a/webclient/room/room.html +++ b/webclient/room/room.html @@ -35,7 +35,7 @@ <div class="bubble"> {{ msg.content.msgtype === "m.emote" ? ("* " + (members[msg.user_id].displayname || msg.user_id) + " " + msg.content.body) : "" }} {{ msg.content.msgtype === "m.text" ? msg.content.body : "" }} - <img class="image" ng-hide='msg.content.msgtype !== "m.image"' src="{{ msg.content.url }}" alt="{{ msg.content.body }}"/> + <img class="image" ng-hide='msg.content.msgtype !== "m.image"' ng-src="{{ msg.content.url }}" alt="{{ msg.content.body }}"/> </div> </td> <td class="rightBlock"> @@ -86,6 +86,10 @@ <button ng-click="inviteUser(userIDToInvite)">Invite</button> </span> <button ng-click="leaveRoom()">Leave</button> + <button ng-click="loadMoreHistory()" ng-disabled="!state.can_paginate">Load more history</button> + <div ng-hide="!state.stream_failure"> + {{ state.stream_failure.data.error || "Connection failure" }} + </div> </div> </div> |