From dee17d002d87667f7d0f4478e1f0180135618c38 Mon Sep 17 00:00:00 2001 From: Bernhard Posselt Date: Tue, 16 Apr 2013 15:19:05 +0200 Subject: dont show unread count when it is 0, dont bold read feeds, implemented autopaging --- js/app/app.coffee | 4 ++ js/app/controllers/itemcontroller.coffee | 10 ++++- js/app/directives/newsitemscroll.coffee | 8 +++- .../businesslayer/itembusinesslayer.coffee | 7 +++- js/app/services/models/itemmodel.coffee | 11 ++++++ js/public/app.js | 45 +++++++++++++++++++--- .../businesslayer/itembusinesslayerSpec.coffee | 15 +++++++- js/tests/services/models/itemmodelSpec.coffee | 9 ++++- 8 files changed, 97 insertions(+), 12 deletions(-) (limited to 'js') diff --git a/js/app/app.coffee b/js/app/app.coffee index 2042a9ebf..264078b57 100644 --- a/js/app/app.coffee +++ b/js/app/app.coffee @@ -28,6 +28,10 @@ angular.module('News', ['OC', 'ui']).config ($provide) -> scrollTimeout: 500 feedUpdateInterval: 600000 itemBatchSize: 20 + # the autoPageFactor defines how many heights of the box must be left + # before it starts autopaging e.g. if it was 2, then it will start + # to fetch new items if less than the height*2 px is left to scroll + autoPageFactor: 6 angular.module('News').run ['Persistence', 'Config', 'FeedBusinessLayer', diff --git a/js/app/controllers/itemcontroller.coffee b/js/app/controllers/itemcontroller.coffee index 4fd00ec59..0d912b507 100644 --- a/js/app/controllers/itemcontroller.coffee +++ b/js/app/controllers/itemcontroller.coffee @@ -31,6 +31,8 @@ Language) -> constructor: (@_$scope, @_itemBusinessLayer, @_feedModel, @_feedLoading, @_feedBusinessLayer, @_language) -> + @_autoPaging = true + @_$scope.itemBusinessLayer = @_itemBusinessLayer @_$scope.feedBusinessLayer = @_feedBusinessLayer @@ -54,10 +56,14 @@ Language) -> @_$scope.$on 'readItem', (scope, data) => - console.log data @_itemBusinessLayer.setRead(data) - + @_$scope.$on 'autoPage', => + if @_autoPaging + # prevent multiple autopaging requests + @_autoPaging = false + @_itemBusinessLayer.loadNext => + @_autoPaging = true return new ItemController($scope, ItemBusinessLayer, FeedModel, FeedLoading, diff --git a/js/app/directives/newsitemscroll.coffee b/js/app/directives/newsitemscroll.coffee index 5e7e42a3e..619710bf3 100644 --- a/js/app/directives/newsitemscroll.coffee +++ b/js/app/directives/newsitemscroll.coffee @@ -49,14 +49,18 @@ angular.module('News').directive 'newsItemScroll', ['$rootScope', 'Config', offset = $(feedItem).position().top if offset <= -50 id = parseInt($(feedItem).data('id'), 10) - #$rootScope.$broadcast 'readItem', id + $rootScope.$broadcast 'readItem', id else break , Config.MarkReadTimeout - scope.$apply attr.newsItemScroll + # autopaging + tolerance = elm.height() * Config.autoPageFactor + remaining = elm[0].scrollHeight - elm.scrollTop() - tolerance + if remaining <= 0 + $rootScope.$broadcast 'autoPage' ] diff --git a/js/app/services/businesslayer/itembusinesslayer.coffee b/js/app/services/businesslayer/itembusinesslayer.coffee index b93f9035d..0b79cd638 100644 --- a/js/app/services/businesslayer/itembusinesslayer.coffee +++ b/js/app/services/businesslayer/itembusinesslayer.coffee @@ -105,7 +105,12 @@ StarredBusinessLayer) -> return feed.title - loadNext: -> + loadNext: (callback) -> + lowestItemId = @_itemModel.getLowestId() + if angular.isDefined(lowestItemId) + @_persistence.getItems @_activeFeed.getType(), + @_activeFeed.getId(), lowestItemId, + callback diff --git a/js/app/services/models/itemmodel.coffee b/js/app/services/models/itemmodel.coffee index 70b3a9f5c..1b03d65f8 100644 --- a/js/app/services/models/itemmodel.coffee +++ b/js/app/services/models/itemmodel.coffee @@ -109,5 +109,16 @@ angular.module('News').factory 'ItemModel', return 0 + getLowestId: -> + query = new _MinimumQuery('id') + lowestId = @get(query) + + if angular.isDefined(lowestId) + return lowestId.id + else + return 0 + + + return new ItemModel() ] \ No newline at end of file diff --git a/js/public/app.js b/js/public/app.js index ab3c73783..406007894 100644 --- a/js/public/app.js +++ b/js/public/app.js @@ -42,7 +42,8 @@ License along with this library. If not, see . markReadTimeout: 500, scrollTimeout: 500, feedUpdateInterval: 600000, - itemBatchSize: 20 + itemBatchSize: 20, + autoPageFactor: 6 }); }); @@ -247,6 +248,8 @@ License along with this library. If not, see . '$rootScope', 'Config', function($rootScope, Config) { return function(scope, elm, attr) { return elm.bind('scroll', function() { + var remaining, tolerance; + if (scrolling) { scrolling = false; setTimeout(function() { @@ -264,7 +267,8 @@ License along with this library. If not, see . feedItem = $elems[_i]; offset = $(feedItem).position().top; if (offset <= -50) { - _results.push(id = parseInt($(feedItem).data('id'), 10)); + id = parseInt($(feedItem).data('id'), 10); + _results.push($rootScope.$broadcast('readItem', id)); } else { break; } @@ -272,7 +276,11 @@ License along with this library. If not, see . return _results; }, Config.MarkReadTimeout); } - return scope.$apply(attr.newsItemScroll); + tolerance = elm.height() * Config.autoPageFactor; + remaining = elm[0].scrollHeight - elm.scrollTop() - tolerance; + if (remaining <= 0) { + return $rootScope.$broadcast('autoPage'); + } } }); }; @@ -444,6 +452,7 @@ License along with this library. If not, see . this._feedLoading = _feedLoading; this._feedBusinessLayer = _feedBusinessLayer; this._language = _language; + this._autoPaging = true; this._$scope.itemBusinessLayer = this._itemBusinessLayer; this._$scope.feedBusinessLayer = this._feedBusinessLayer; this._$scope.isLoading = function() { @@ -467,9 +476,16 @@ License along with this library. If not, see . } }; this._$scope.$on('readItem', function(scope, data) { - console.log(data); return _this._itemBusinessLayer.setRead(data); }); + this._$scope.$on('autoPage', function() { + if (_this._autoPaging) { + _this._autoPaging = false; + return _this._itemBusinessLayer.loadNext(function() { + return _this._autoPaging = true; + }); + } + }); } return ItemController; @@ -1223,7 +1239,14 @@ License along with this library. If not, see . } }; - ItemBusinessLayer.prototype.loadNext = function() {}; + ItemBusinessLayer.prototype.loadNext = function(callback) { + var lowestItemId; + + lowestItemId = this._itemModel.getLowestId(); + if (angular.isDefined(lowestItemId)) { + return this._persistence.getItems(this._activeFeed.getType(), this._activeFeed.getId(), lowestItemId, callback); + } + }; ItemBusinessLayer.prototype.loadNew = function() {}; @@ -2015,6 +2038,18 @@ License along with this library. If not, see . } }; + ItemModel.prototype.getLowestId = function() { + var lowestId, query; + + query = new _MinimumQuery('id'); + lowestId = this.get(query); + if (angular.isDefined(lowestId)) { + return lowestId.id; + } else { + return 0; + } + }; + return ItemModel; })(_Model); diff --git a/js/tests/services/businesslayer/itembusinesslayerSpec.coffee b/js/tests/services/businesslayer/itembusinesslayerSpec.coffee index d5333c1f4..5f4744ffa 100644 --- a/js/tests/services/businesslayer/itembusinesslayerSpec.coffee +++ b/js/tests/services/businesslayer/itembusinesslayerSpec.coffee @@ -35,9 +35,9 @@ describe 'ItemBusinessLayer', -> @FeedType, @FeedModel, @StarredBusinessLayer) => @item1 = {id: 5, title: 'hi', unreadCount:134, urlHash: 'a3', folderId: 3} @FeedModel.add(@item1) + @ActiveFeed.handle({type: @FeedType.Feed, id: 3}) - it 'should return all items', => item1 = {id: 6, feedId: 5, guidHash: 'a1'} item2 = {id: 3, feedId: 5, guidHash: 'a2'} @@ -233,3 +233,16 @@ describe 'ItemBusinessLayer', -> expect(@item1.unreadCount).toBe(135) + it 'should load the next items', => + @persistence.getItems = jasmine.createSpy('autopage') + callback = -> + + @ItemModel.add({id: 2, guidHash: 'abc', feedId: 2, status: 16}) + @ItemModel.add({id: 3, guidHash: 'abcd', feedId: 2, status: 16}) + @ItemModel.add({id: 1, guidHash: 'abce', feedId: 2, status: 16}) + @ItemModel.add({id: 6, guidHash: 'abcf', feedId: 2, status: 16}) + + @ItemBusinessLayer.loadNext(callback) + + expect(@persistence.getItems).toHaveBeenCalledWith( + @FeedType.Feed, 3, 1, jasmine.any(Function)) diff --git a/js/tests/services/models/itemmodelSpec.coffee b/js/tests/services/models/itemmodelSpec.coffee index ef6b535c4..4e93609ea 100644 --- a/js/tests/services/models/itemmodelSpec.coffee +++ b/js/tests/services/models/itemmodelSpec.coffee @@ -103,4 +103,11 @@ describe 'ItemModel', -> expect(@ItemModel.getById(3).isStarred()).toBe(false) - \ No newline at end of file + + it 'should return the lowest id', => + @ItemModel.add({id: 2, guidHash: 'abc', feedId: 2, status: 16}) + @ItemModel.add({id: 3, guidHash: 'abcd', feedId: 2, status: 16}) + @ItemModel.add({id: 1, guidHash: 'abce', feedId: 2, status: 16}) + @ItemModel.add({id: 6, guidHash: 'abcf', feedId: 2, status: 16}) + + expect(@ItemModel.getLowestId()).toBe(1) \ No newline at end of file -- cgit v1.2.3