mirror of
https://mau.dev/maunium/synapse.git
synced 2024-12-14 17:03:50 +01:00
slightly hacky but more functional infinite scrolling
This commit is contained in:
parent
9f7c5f161c
commit
4068339770
1 changed files with 36 additions and 30 deletions
|
@ -15,36 +15,11 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
angular.module('RoomController', [])
|
angular.module('RoomController', [])
|
||||||
// FIXME move directives outta here!
|
|
||||||
.directive("keepScroll", function() {
|
|
||||||
return {
|
|
||||||
controller : function($scope) {
|
|
||||||
var element = 0;
|
|
||||||
this.setElement = function(el){
|
|
||||||
element = el;
|
|
||||||
}
|
|
||||||
this.addItem = function(item){
|
|
||||||
element.scrollTop = (element.scrollTop + item.clientHeight);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
link : function(scope, el, attr, ctrl) {
|
|
||||||
ctrl.setElement(el[0]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})
|
|
||||||
// FIXME move directives outta here!
|
|
||||||
.directive("scrollItem", function(){
|
|
||||||
return {
|
|
||||||
require : "^keepScroll",
|
|
||||||
link : function(scope, el, att, scrCtrl){
|
|
||||||
scrCtrl.addItem(el[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.controller('RoomController', ['$scope', '$http', '$timeout', '$routeParams', '$location', 'matrixService', 'eventStreamService', 'eventHandlerService',
|
.controller('RoomController', ['$scope', '$http', '$timeout', '$routeParams', '$location', 'matrixService', 'eventStreamService', 'eventHandlerService',
|
||||||
function($scope, $http, $timeout, $routeParams, $location, matrixService, eventStreamService, eventHandlerService) {
|
function($scope, $http, $timeout, $routeParams, $location, matrixService, eventStreamService, eventHandlerService) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var MESSAGES_PER_PAGINATION = 10;
|
var MESSAGES_PER_PAGINATION = 30;
|
||||||
$scope.room_id = $routeParams.room_id;
|
$scope.room_id = $routeParams.room_id;
|
||||||
$scope.room_alias = matrixService.getRoomIdToAliasMapping($scope.room_id);
|
$scope.room_alias = matrixService.getRoomIdToAliasMapping($scope.room_id);
|
||||||
$scope.state = {
|
$scope.state = {
|
||||||
|
@ -52,6 +27,7 @@ angular.module('RoomController', [])
|
||||||
events_from: "END", // when to start the event stream from.
|
events_from: "END", // when to start the event stream from.
|
||||||
earliest_token: "END", // stores how far back we've paginated.
|
earliest_token: "END", // stores how far back we've paginated.
|
||||||
can_paginate: true, // this is toggled off when we run out of items
|
can_paginate: true, // this is toggled off when we run out of items
|
||||||
|
paginating: false, // used to avoid concurrent pagination requests pulling in dup contents
|
||||||
stream_failure: undefined // the response when the stream fails
|
stream_failure: undefined // the response when the stream fails
|
||||||
};
|
};
|
||||||
$scope.members = {};
|
$scope.members = {};
|
||||||
|
@ -61,7 +37,7 @@ angular.module('RoomController', [])
|
||||||
|
|
||||||
var scrollToBottom = function() {
|
var scrollToBottom = function() {
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
var objDiv = document.getElementsByClassName("messageTableWrapper")[0];
|
var objDiv = document.getElementById("messageTableWrapper");
|
||||||
objDiv.scrollTop = objDiv.scrollHeight;
|
objDiv.scrollTop = objDiv.scrollHeight;
|
||||||
},0);
|
},0);
|
||||||
};
|
};
|
||||||
|
@ -82,18 +58,33 @@ angular.module('RoomController', [])
|
||||||
|
|
||||||
$scope.paginateMore = function() {
|
$scope.paginateMore = function() {
|
||||||
if ($scope.state.can_paginate) {
|
if ($scope.state.can_paginate) {
|
||||||
console.log("Paginating more.");
|
// console.log("Paginating more.");
|
||||||
paginate(MESSAGES_PER_PAGINATION, false);
|
paginate(MESSAGES_PER_PAGINATION, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var paginate = function(numItems, toBottom) {
|
var paginate = function(numItems, toBottom) {
|
||||||
|
// console.log("paginate " + numItems + ", " + toBottom);
|
||||||
|
if ($scope.state.paginating) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.state.paginating = true;
|
||||||
|
}
|
||||||
|
// console.log("paginateBackMessages from " + $scope.state.earliest_token + " for " + numItems);
|
||||||
|
var originalTopRow = $("#messageTable>tbody>tr:first")[0];
|
||||||
matrixService.paginateBackMessages($scope.room_id, $scope.state.earliest_token, numItems).then(
|
matrixService.paginateBackMessages($scope.room_id, $scope.state.earliest_token, numItems).then(
|
||||||
function(response) {
|
function(response) {
|
||||||
|
// hacky bodge to ensure we always scroll to the bottom on the first pagination
|
||||||
|
if (!$scope.events.rooms[$scope.room_id]) {
|
||||||
|
toBottom = true;
|
||||||
|
}
|
||||||
|
|
||||||
eventHandlerService.handleEvents(response.data.chunk, false);
|
eventHandlerService.handleEvents(response.data.chunk, false);
|
||||||
$scope.state.earliest_token = response.data.end;
|
$scope.state.earliest_token = response.data.end;
|
||||||
if (response.data.chunk.length < MESSAGES_PER_PAGINATION) {
|
if (response.data.chunk.length < MESSAGES_PER_PAGINATION) {
|
||||||
// no more messages to paginate :(
|
// no more messages to paginate. this currently never gets turned true again, as we never
|
||||||
|
// expire paginated contents in the current implementation.
|
||||||
$scope.state.can_paginate = false;
|
$scope.state.can_paginate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,9 +92,24 @@ angular.module('RoomController', [])
|
||||||
console.log("Scrolling to bottom");
|
console.log("Scrolling to bottom");
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$timeout(function() {
|
||||||
|
// FIXME: this risks a flicker before the scrollTop is actually updated, but we have to
|
||||||
|
// dispatch it into a function in order to first update the layout. The right solution
|
||||||
|
// might be to implement it as a directive, more like
|
||||||
|
// http://stackoverflow.com/questions/23736647/how-to-retain-scroll-position-of-ng-repeat-in-angularjs
|
||||||
|
// however, this specific solution breaks because it measures the rows height before
|
||||||
|
// the contents are interpolated.
|
||||||
|
var objDiv = document.getElementById("messageTableWrapper");
|
||||||
|
objDiv.scrollTop = originalTopRow ? (originalTopRow.offsetTop + objDiv.scrollTop) : 0;
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.state.paginating = false;
|
||||||
},
|
},
|
||||||
function(error) {
|
function(error) {
|
||||||
console.log("Failed to paginateBackMessages: " + JSON.stringify(error));
|
console.log("Failed to paginateBackMessages: " + JSON.stringify(error));
|
||||||
|
$scope.state.paginating = false;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue