From 40c998336d3562018162bfc14b4dade1139f414c Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 14 Aug 2014 15:47:38 +0100 Subject: Finish up room controller too. May have missed one or two, but testing didn't pick anything up. --- webclient/room/room-controller.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'webclient/room/room-controller.js') diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js index 470f41521a..cec19f7994 100644 --- a/webclient/room/room-controller.js +++ b/webclient/room/room-controller.js @@ -99,8 +99,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 +108,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 +171,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; }); }; @@ -190,13 +190,13 @@ angular.module('RoomController', []) // 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; } ); }, @@ -224,8 +224,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,8 +234,8 @@ 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; }); }; -- cgit 1.4.1 From 30da8c81c761a1f58c9643f41450240bfe1d6cc5 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 14 Aug 2014 17:23:47 +0100 Subject: webclient: You can now paginate in rooms. Defaults to 10 messages, with a button to get more (needs to be hooked into infini-scrolling). --- docs/client-server/specification.rst | 3 + webclient/components/matrix/matrix-service.js | 11 ++++ webclient/room/room-controller.js | 80 ++++++++++++++++++++------- webclient/room/room.html | 1 + 4 files changed, 74 insertions(+), 21 deletions(-) (limited to 'webclient/room/room-controller.js') diff --git a/docs/client-server/specification.rst b/docs/client-server/specification.rst index 97c8587a6d..b82093f2d3 100644 --- a/docs/client-server/specification.rst +++ b/docs/client-server/specification.rst @@ -414,6 +414,9 @@ The server checks this, finds it is valid, and returns: { "access_token": "abcdef0123456789" } +The server may optionally return "user_id" to confirm or change the user's ID. +This is particularly useful if the home server wishes to support localpart entry +of usernames (e.g. "bob" rather than "@bob:matrix.org"). OAuth2-based ------------ diff --git a/webclient/components/matrix/matrix-service.js b/webclient/components/matrix/matrix-service.js index 132c996f7a..6d66111469 100644 --- a/webclient/components/matrix/matrix-service.js +++ b/webclient/components/matrix/matrix-service.js @@ -212,6 +212,17 @@ angular.module('matrixService', []) path = path.replace("$room_id", room_id); return doRequest("GET", path); }, + + paginateBackMessages: function(room_id, from_token, limit) { + var path = "/rooms/$room_id/messages/list"; + path = path.replace("$room_id", room_id); + var params = { + from: from_token, + to: "START", + limit: limit + }; + return doRequest("GET", path, params); + }, // get a list of public rooms on your home server publicRooms: function() { diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js index cec19f7994..8003105654 100644 --- a/webclient/room/room-controller.js +++ b/webclient/room/room-controller.js @@ -18,11 +18,14 @@ 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 }; $scope.messages = []; $scope.members = {}; @@ -30,6 +33,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("paginateBackMessages Ruh roh: " + JSON.stringify(error)); + } + ) + }; var shortPoll = function() { $http.get(matrixService.config().homeserver + matrixService.prefix + "/events", { @@ -41,28 +91,10 @@ angular.module('RoomController', []) .then(function(response) { 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."); } @@ -199,6 +231,8 @@ angular.module('RoomController', []) $scope.feedback = "Failed get member list: " + error.data.error; } ); + + paginate(MESSAGES_PER_PAGINATION); }, function(reason) { $scope.feedback = "Can't join room: " + reason; @@ -238,6 +272,10 @@ angular.module('RoomController', []) $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 91e900c678..0f86a158ec 100644 --- a/webclient/room/room.html +++ b/webclient/room/room.html @@ -86,6 +86,7 @@ + -- cgit 1.4.1 From 5de086b736218d43bd51c3b83ca26118806488a2 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 14 Aug 2014 17:40:27 +0100 Subject: More helpful display when the event stream fails, wiping it when the connection is regained. --- webclient/room/room-controller.js | 10 ++++++---- webclient/room/room.html | 5 ++++- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'webclient/room/room-controller.js') diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js index 8003105654..fb6e2025fc 100644 --- a/webclient/room/room-controller.js +++ b/webclient/room/room-controller.js @@ -25,7 +25,8 @@ angular.module('RoomController', []) 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. - can_paginate: true + 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 = {}; @@ -76,7 +77,7 @@ angular.module('RoomController', []) } }, function(error) { - console.log("paginateBackMessages Ruh roh: " + JSON.stringify(error)); + console.log("Failed to paginateBackMessages: " + JSON.stringify(error)); } ) }; @@ -89,6 +90,7 @@ 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 = ""; @@ -102,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; @@ -215,7 +217,7 @@ 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); diff --git a/webclient/room/room.html b/webclient/room/room.html index 0f86a158ec..3b9ba713de 100644 --- a/webclient/room/room.html +++ b/webclient/room/room.html @@ -86,7 +86,10 @@ - + +
+ {{ state.stream_failure.data.error || "Connection failure" }} +
-- cgit 1.4.1