diff --git a/src/main/webapp/js/controllers.js b/src/main/webapp/js/controllers.js index 40077f7c..0e717d47 100644 --- a/src/main/webapp/js/controllers.js +++ b/src/main/webapp/js/controllers.js @@ -665,15 +665,17 @@ module.controller('FeedListCtrl', [ '$route', '$state', '$window', + '$timeout', '$location', 'EntryService', 'SettingsService', 'FeedService', 'CategoryService', 'AnalyticsService', - function($scope, $stateParams, $http, $route, $state, $window, $location, EntryService, SettingsService, FeedService, + function($scope, $stateParams, $http, $route, $state, $window, $timeout, $location, EntryService, SettingsService, FeedService, CategoryService, AnalyticsService) { + $window = angular.element($window); AnalyticsService.track(); $scope.keywords = $location.search().q; @@ -758,6 +760,79 @@ module.controller('FeedListCtrl', [ }, callback); }; + var watch_scrolling = true; + var watch_current = true; + + $scope.$watch('current', function(newValue, oldValue) { + if (!watch_current) { + return; + } + if (newValue && newValue !== oldValue) { + var force = $scope.navigationMode == 'keyboard'; + + // timeout here to execute after dom update + $timeout(function() { + var docTop = $(window).scrollTop(); + var docBottom = docTop + $(window).height(); + + var elem = $('#entry_' + newValue.id); + var elemTop = elem.offset().top; + var elemBottom = elemTop + elem.height(); + + if (!force && (elemTop > docTop) && (elemBottom < docBottom)) { + // element is entirely visible + return; + } else { + var scrollTop = elemTop - $('#toolbar').outerHeight(); + watch_scrolling = false; + $('html, body').animate({ + scrollTop : scrollTop + }, 400, 'swing', function() { + watch_scrolling = true; + }); + } + }); + } + }); + + var scrollHandler = function() { + if (!watch_scrolling || _.size($scope.entries) === 0) { + return; + } + + $scope.navigationMode = 'scroll'; + if (SettingsService.settings.viewMode == 'expanded') { + var w = $(window); + var docTop = w.scrollTop(); + + var current = null; + for ( var i = 0; i < $scope.entries.length; i++) { + var entry = $scope.entries[i]; + var e = $('#entry_' + entry.id); + if (e.offset().top + e.height() > docTop + $('#toolbar').outerHeight()) { + current = entry; + break; + } + } + + var previous = $scope.current; + $scope.current = current; + if (previous != current) { + if (SettingsService.settings.scrollMarks) { + $scope.mark($scope.current, true); + } + watch_current = false; + $scope.$apply(); + watch_current = true; + } + } + }; + var scrollListener = _.throttle(scrollHandler, 200); + $window.on('scroll', scrollListener); + $scope.$on('$destroy', function() { + return $window.off('scroll', scrollListener); + }); + $scope.goToFeed = function(id) { $state.transitionTo('feeds.view', { _type : 'feed', @@ -955,16 +1030,6 @@ module.controller('FeedListCtrl', [ } }; - $scope.onScroll = function(entry) { - $scope.navigationMode = 'scroll'; - if (SettingsService.settings.viewMode == 'expanded') { - $scope.current = entry; - if (SettingsService.settings.scrollMarks) { - $scope.mark(entry, true); - } - } - }; - Mousetrap.bind('j', function(e) { $scope.$apply(function() { $scope.navigationMode = 'keyboard'; diff --git a/src/main/webapp/js/directives.js b/src/main/webapp/js/directives.js index 8906ec0c..ab9e7ab7 100644 --- a/src/main/webapp/js/directives.js +++ b/src/main/webapp/js/directives.js @@ -59,96 +59,6 @@ module.directive('ngBlur', function() { }; }); -/** - * Fired when the top of the element is not visible anymore - */ -module.directive('onScrollMiddle', function() { - return { - restrict : 'A', - link : function(scope, element, attrs) { - - var w = $(window); - var e = $(element); - var d = $(document); - - var offset = parseInt(attrs.onScrollMiddleOffset, 10); - - var down = function() { - var docTop = w.scrollTop(); - var elemTop = e.offset().top; - var threshold = docTop === 0 ? elemTop - 1 : docTop + offset; - return (elemTop > threshold) ? 'below' : 'above'; - }; - var up = function() { - var docTop = w.scrollTop(); - var elemTop = e.offset().top; - var elemBottom = elemTop + e.height(); - var threshold = docTop === 0 ? elemBottom - 1 : docTop + offset; - return (elemBottom > threshold) ? 'below' : 'above'; - }; - - if (!w.data.scrollInit) { - w.data.scrollPosition = d.scrollTop(); - w.data.scrollDirection = 'down'; - - var onScroll = function(e) { - var scroll = d.scrollTop(); - w.data.scrollDirection = (scroll - w.data.scrollPosition > 0) ? 'down' : 'up'; - w.data.scrollPosition = scroll; - scope.$apply(); - }; - w.bind('scroll', _.throttle(onScroll, 500)); - w.data.scrollInit = true; - } - scope.$watch(down, function downCallback(value, oldValue) { - if (value != oldValue && value == 'above') - scope.$eval(attrs.onScrollMiddle); - }); - scope.$watch(up, function upCallback(value, oldValue) { - if (value != oldValue && value == 'below') - scope.$eval(attrs.onScrollMiddle); - }); - } - }; -}); - -/** - * Scrolls to the element if the value is true and the attribute is not fully - * visible, unless the attribute scroll-to-force is true - */ -module.directive('scrollTo', ['$timeout', function($timeout) { - return { - restrict : 'A', - link : function(scope, element, attrs) { - scope.$watch(attrs.scrollTo, function(value) { - if (!value) - return; - var force = scope.$eval(attrs.scrollToForce); - - // timeout here to execute after dom update - $timeout(function() { - var docTop = $(window).scrollTop(); - var docBottom = docTop + $(window).height(); - - var elemTop = $(element).offset().top; - var elemBottom = elemTop + $(element).height(); - - if (!force && (elemTop > docTop) && (elemBottom < docBottom)) { - // element is entirely visible - return; - } else { - var offset = parseInt(attrs.scrollToOffset, 10); - var scrollTop = $(element).offset().top + offset; - $('html, body').animate({ - scrollTop : scrollTop - }, 0); - } - }); - }); - } - }; -}]); - /** * Prevent mousewheel scrolling from propagating to the parent when scrollbar * reaches top or bottom diff --git a/src/main/webapp/templates/feeds.html b/src/main/webapp/templates/feeds.html index 147ceedc..2df55ea9 100644 --- a/src/main/webapp/templates/feeds.html +++ b/src/main/webapp/templates/feeds.html @@ -8,7 +8,7 @@