forked from MirrorHub/synapse
Added infinite scrolling. It's sliiiightly buggy in that it jumps down the list a bit, but it is overall working pretty well. Added ng-infinite-scroll-matrix.js and jquery-1.8.3 as deps.
This commit is contained in:
parent
02e45da895
commit
5b817ecd44
7 changed files with 115 additions and 9 deletions
|
@ -22,7 +22,8 @@ var matrixWebClient = angular.module('matrixWebClient', [
|
|||
'RoomsController',
|
||||
'matrixService',
|
||||
'eventStreamService',
|
||||
'eventHandlerService'
|
||||
'eventHandlerService',
|
||||
'infinite-scroll'
|
||||
]);
|
||||
|
||||
matrixWebClient.config(['$routeProvider', '$provide', '$httpProvider',
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
<link rel="stylesheet" href="app.css">
|
||||
<link rel="icon" href="favicon.ico">
|
||||
|
||||
<script type='text/javascript' src='js/jquery-1.8.3.min.js'></script>
|
||||
<script src="js/angular.js"></script>
|
||||
<script src="js/angular-route.js"></script>
|
||||
<script type='text/javascript' src='js/ng-infinite-scroll-matrix.js'></script>
|
||||
<script src="app.js"></script>
|
||||
<script src="app-controller.js"></script>
|
||||
<script src="login/login-controller.js"></script>
|
||||
|
|
2
webclient/js/jquery-1.8.3.min.js
vendored
Normal file
2
webclient/js/jquery-1.8.3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
63
webclient/js/ng-infinite-scroll-matrix.js
Normal file
63
webclient/js/ng-infinite-scroll-matrix.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* ng-infinite-scroll - v1.0.0 - 2013-02-23
|
||||
Matrix: Modified to support scrolling UP to get infinite loading and to listen
|
||||
to scroll events on the PARENT element, not the window.
|
||||
*/
|
||||
var mod;
|
||||
|
||||
mod = angular.module('infinite-scroll', []);
|
||||
|
||||
mod.directive('infiniteScroll', [
|
||||
'$rootScope', '$window', '$timeout', function($rootScope, $window, $timeout) {
|
||||
return {
|
||||
link: function(scope, elem, attrs) {
|
||||
var checkWhenEnabled, handler, scrollDistance, scrollEnabled;
|
||||
$window = angular.element($window);
|
||||
scrollDistance = 0;
|
||||
if (attrs.infiniteScrollDistance != null) {
|
||||
scope.$watch(attrs.infiniteScrollDistance, function(value) {
|
||||
return scrollDistance = parseInt(value, 10);
|
||||
});
|
||||
}
|
||||
scrollEnabled = true;
|
||||
checkWhenEnabled = false;
|
||||
if (attrs.infiniteScrollDisabled != null) {
|
||||
scope.$watch(attrs.infiniteScrollDisabled, function(value) {
|
||||
scrollEnabled = !value;
|
||||
if (scrollEnabled && checkWhenEnabled) {
|
||||
checkWhenEnabled = false;
|
||||
return handler();
|
||||
}
|
||||
});
|
||||
}
|
||||
handler = function() {
|
||||
var elementTop, remaining, shouldScroll, windowTop;
|
||||
windowTop = 0;
|
||||
elementTop = elem.offset().top;
|
||||
shouldScroll = elementTop >= 0; // top of list is at the top of the window or further down the page
|
||||
if (shouldScroll && scrollEnabled) {
|
||||
if ($rootScope.$$phase) {
|
||||
return scope.$eval(attrs.infiniteScroll);
|
||||
} else {
|
||||
return scope.$apply(attrs.infiniteScroll);
|
||||
}
|
||||
} else if (shouldScroll) {
|
||||
return checkWhenEnabled = true;
|
||||
}
|
||||
};
|
||||
elem.parent().on('scroll', handler);
|
||||
scope.$on('$destroy', function() {
|
||||
return elem.parent().off('scroll', handler);
|
||||
});
|
||||
return $timeout((function() {
|
||||
if (attrs.infiniteScrollImmediateCheck) {
|
||||
if (scope.$eval(attrs.infiniteScrollImmediateCheck)) {
|
||||
return handler();
|
||||
}
|
||||
} else {
|
||||
return handler();
|
||||
}
|
||||
}), 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
|
@ -15,6 +15,32 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
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+1); //1px for margin
|
||||
};
|
||||
},
|
||||
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',
|
||||
function($scope, $http, $timeout, $routeParams, $location, matrixService, eventStreamService, eventHandlerService) {
|
||||
'use strict';
|
||||
|
@ -54,7 +80,14 @@ angular.module('RoomController', [])
|
|||
updatePresence(event);
|
||||
});
|
||||
|
||||
var paginate = function(numItems) {
|
||||
$scope.paginateMore = function() {
|
||||
if ($scope.state.can_paginate) {
|
||||
console.log("Paginating more.");
|
||||
paginate(MESSAGES_PER_PAGINATION, false);
|
||||
}
|
||||
};
|
||||
|
||||
var paginate = function(numItems, toBottom) {
|
||||
matrixService.paginateBackMessages($scope.room_id, $scope.state.earliest_token, numItems).then(
|
||||
function(response) {
|
||||
eventHandlerService.handleEvents(response.data.chunk, false);
|
||||
|
@ -63,6 +96,11 @@ angular.module('RoomController', [])
|
|||
// no more messages to paginate :(
|
||||
$scope.state.can_paginate = false;
|
||||
}
|
||||
|
||||
if (toBottom) {
|
||||
console.log("Scrolling to bottom");
|
||||
scrollToBottom();
|
||||
}
|
||||
},
|
||||
function(error) {
|
||||
console.log("Failed to paginateBackMessages: " + JSON.stringify(error));
|
||||
|
@ -181,7 +219,7 @@ angular.module('RoomController', [])
|
|||
}
|
||||
);
|
||||
|
||||
paginate(MESSAGES_PER_PAGINATION);
|
||||
paginate(MESSAGES_PER_PAGINATION, true);
|
||||
},
|
||||
function(reason) {
|
||||
$scope.feedback = "Can't join room: " + reason;
|
||||
|
@ -223,6 +261,6 @@ angular.module('RoomController', [])
|
|||
};
|
||||
|
||||
$scope.loadMoreHistory = function() {
|
||||
paginate(MESSAGES_PER_PAGINATION);
|
||||
paginate(MESSAGES_PER_PAGINATION, false);
|
||||
};
|
||||
}]);
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<div class="messageTableWrapper">
|
||||
<table class="messageTable">
|
||||
<tr ng-repeat="msg in events.rooms[room_id].messages" ng-class="msg.user_id === state.user_id ? 'mine' : ''">
|
||||
<div class="messageTableWrapper" keep-scroll>
|
||||
<table class="messageTable" infinite-scroll="paginateMore()">
|
||||
<tr ng-repeat="msg in events.rooms[room_id].messages" ng-class="msg.user_id === state.user_id ? 'mine' : ''" scroll-item>
|
||||
<td class="leftBlock">
|
||||
<div class="sender" ng-hide="events.rooms[room_id].messages[$index - 1].user_id === msg.user_id">{{ members[msg.user_id].displayname || msg.user_id }}</div>
|
||||
<div class="timestamp">{{ msg.content.hsob_ts | date:'MMM d HH:mm:ss' }}</div>
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
</div>
|
||||
<div>
|
||||
<form>
|
||||
<input size="40" ng-model="joinAlias.room_alias" ng-enter="joinAlias(joinAlias.room_alias)" placeholder="(e.g. #foo_channe:example.org)"/>
|
||||
<input size="40" ng-model="joinAlias.room_alias" ng-enter="joinAlias(joinAlias.room_alias)" placeholder="(e.g. #foo_channel:example.org)"/>
|
||||
<button ng-disabled="!joinAlias.room_alias" ng-click="joinAlias(joinAlias.room_alias)">Join room</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue