diff options
-rw-r--r-- | js/app/Config.js | 72 | ||||
-rw-r--r-- | js/app/Run.js | 41 | ||||
-rw-r--r-- | js/build/app.js | 125 | ||||
-rw-r--r-- | js/controller/ContentController.js (renamed from js/controller/ItemController.js) | 0 | ||||
-rw-r--r-- | js/service/Item.js | 24 | ||||
-rw-r--r-- | js/service/Publisher.js | 13 | ||||
-rw-r--r-- | js/tests/unit/service/ItemSpec.js | 43 | ||||
-rw-r--r-- | js/tests/unit/service/PublisherSpec.js | 19 |
8 files changed, 278 insertions, 59 deletions
diff --git a/js/app/Config.js b/js/app/Config.js index 290726343..5581af0e4 100644 --- a/js/app/Config.js +++ b/js/app/Config.js @@ -9,19 +9,22 @@ */ app.config(function ($routeProvider, $provide, $httpProvider) { 'use strict'; + var getResolve, + feedType; - // constants - $provide.constant('CONFIG', { - REFRESH_RATE: 60 // refresh feeds every 60 seconds - }); - $provide.constant('BASE_URL', OC.generateUrl('/apps/news')); - $provide.constant('FEED_TYPE', { + feedType = { FEED: 0, FOLDER: 1, STARRED: 2, SUBSCRIPTIONS: 3, SHARED: 4 - }); + }; + + // constants + $provide.constant('REFRESH_RATE', 60); // seconds, how often feeds and folders shoudl be refreshed + $provide.constant('ITEM_BATCH_SIZE', 50); // how many items to autopage by + $provide.constant('BASE_URL', OC.generateUrl('/apps/news')); + $provide.constant('FEED_TYPE', feedType); // make sure that the CSRF header is only sent to the ownCloud domain $provide.factory('CSRFInterceptor', function ($q, BASE_URL) { @@ -38,26 +41,65 @@ app.config(function ($routeProvider, $provide, $httpProvider) { $httpProvider.interceptors.push('CSRFInterceptor'); // routing + getResolve = function (type) { + return { + // request to items also returns feeds + data: [ + '$http', + '$route', + '$q', + 'BASE_URL', + 'ITEM_BATCH_SIZE', + function ($http, $route, $q, BASE_URL, ITEM_BATCH_SIZE) { + + var parameters, + deferred; + + parameters = { + type: type, + limit: ITEM_BATCH_SIZE + }; + + if ($route.current.params.id !== undefined) { + parameters.id = $route.current.params.id; + } + + deferred = $q.defer(); + + $http({ + url: BASE_URL + '/items', + method: 'GET', + params: parameters + }).success(function (data) { + deferred.resolve(data); + }); + + return deferred.promise; + } + ] + }; + }; + $routeProvider .when('/items', { - controller: 'ItemController', + controller: 'ContentController', templateUrl: 'content.html', - resolve: {} + resolve: getResolve(feedType.SUBSCRIPTIONS) }) .when('/items/starred', { - controller: 'StarredController', + controller: 'ContentController', templateUrl: 'content.html', - resolve: {} + resolve: getResolve(feedType.STARRED) }) .when('/items/feeds/:id', { - controller: 'FeedController', + controller: 'ContentController', templateUrl: 'content.html', - resolve: {} + resolve: getResolve(feedType.FEED) }) .when('/items/folders/:id', { - controller: 'FolderController', + controller: 'ContentController', templateUrl: 'content.html', - resolve: {} + resolve: getResolve(feedType.FOLDER) }) .otherwise({ redirectTo: '/items' diff --git a/js/app/Run.js b/js/app/Run.js index ad5d80ca1..829c9666c 100644 --- a/js/app/Run.js +++ b/js/app/Run.js @@ -9,7 +9,7 @@ */ app.run(function ($rootScope, $location, $http, $q, $interval, Loading, Item, Feed, Folder, Settings, Publisher, BASE_URL, FEED_TYPE, - CONFIG) { + REFRESH_RATE) { 'use strict'; // show Loading screen @@ -17,23 +17,25 @@ app.run(function ($rootScope, $location, $http, $q, $interval, Loading, Item, // listen to keys in returned queries to automatically distribute the // incoming values to models - Publisher.subscribe(Item).toChannel('items'); - Publisher.subscribe(Folder).toChannel('folders'); - Publisher.subscribe(Feed).toChannel('feeds'); - Publisher.subscribe(Settings).toChannel('settings'); + Publisher.subscribe(Item).toChannels('items', 'newestItemId', 'starred'); + Publisher.subscribe(Folder).toChannels('folders'); + Publisher.subscribe(Feed).toChannels('feeds'); + Publisher.subscribe(Settings).toChannels('settings'); // load feeds, settings and last read feed var settingsDeferred, - activeFeedDeferred; + activeFeedDeferred, + folderDeferred, + feedDeferred; settingsDeferred = $q.defer(); - $http.get(BASE_URL + '/settings').then(function (data) { + $http.get(BASE_URL + '/settings').success(function (data) { Publisher.publishAll(data); settingsDeferred.resolve(); }); activeFeedDeferred = $q.defer(); - $http.get(BASE_URL + '/feeds/active').then(function (data) { + $http.get(BASE_URL + '/feeds/active').success(function (data) { var url; switch (data.type) { @@ -58,8 +60,27 @@ app.run(function ($rootScope, $location, $http, $q, $interval, Loading, Item, activeFeedDeferred.resolve(); }); + folderDeferred = $q.defer(); + $http.get(BASE_URL + '/folders').success(function (data) { + Publisher.publishAll(data); + folderDeferred.resolve(); + }); + + feedDeferred = $q.defer(); + $http.get(BASE_URL + '/feeds').success(function (data) { + Publisher.publishAll(data); + feedDeferred.resolve(); + }); + // disable loading if all initial requests finished - $q.all([settingsDeferred.promise, activeFeedDeferred.promise]) + $q.all( + [ + settingsDeferred.promise, + activeFeedDeferred.promise, + feedDeferred.promise, + folderDeferred.promise + ] + ) .then(function () { Loading.setLoading('global', false); }); @@ -68,7 +89,7 @@ app.run(function ($rootScope, $location, $http, $q, $interval, Loading, Item, $interval(function () { $http.get(BASE_URL + '/feeds'); $http.get(BASE_URL + '/folders'); - }, CONFIG.REFRESH_RATE * 1000); + }, REFRESH_RATE * 1000); $rootScope.$on('$routeChangeStart', function () { diff --git a/js/build/app.js b/js/build/app.js index 42eff7be1..d2a4e54c1 100644 --- a/js/build/app.js +++ b/js/build/app.js @@ -14,16 +14,21 @@ app.config([ '$httpProvider', function ($routeProvider, $provide, $httpProvider) { 'use strict'; - // constants - $provide.constant('CONFIG', { REFRESH_RATE: 60 }); - $provide.constant('BASE_URL', OC.generateUrl('/apps/news')); - $provide.constant('FEED_TYPE', { + var getResolve, feedType; + feedType = { FEED: 0, FOLDER: 1, STARRED: 2, SUBSCRIPTIONS: 3, SHARED: 4 - }); + }; + // constants + $provide.constant('REFRESH_RATE', 60); + // seconds, how often feeds and folders shoudl be refreshed + $provide.constant('ITEM_BATCH_SIZE', 50); + // how many items to autopage by + $provide.constant('BASE_URL', OC.generateUrl('/apps/news')); + $provide.constant('FEED_TYPE', feedType); // make sure that the CSRF header is only sent to the ownCloud domain $provide.factory('CSRFInterceptor', function ($q, BASE_URL) { return { @@ -37,22 +42,52 @@ app.config([ }); $httpProvider.interceptors.push('CSRFInterceptor'); // routing + getResolve = function (type) { + return { + data: [ + '$http', + '$route', + '$q', + 'BASE_URL', + 'ITEM_BATCH_SIZE', + function ($http, $route, $q, BASE_URL, ITEM_BATCH_SIZE) { + var parameters, deferred; + parameters = { + type: type, + limit: ITEM_BATCH_SIZE + }; + if ($route.current.params.id !== undefined) { + parameters.id = $route.current.params.id; + } + deferred = $q.defer(); + $http({ + url: BASE_URL + '/items', + method: 'GET', + params: parameters + }).success(function (data) { + deferred.resolve(data); + }); + return deferred.promise; + } + ] + }; + }; $routeProvider.when('/items', { - controller: 'ItemController', + controller: 'ContentController', templateUrl: 'content.html', - resolve: {} + resolve: getResolve(feedType.SUBSCRIPTIONS) }).when('/items/starred', { - controller: 'StarredController', + controller: 'ContentController', templateUrl: 'content.html', - resolve: {} + resolve: getResolve(feedType.STARRED) }).when('/items/feeds/:id', { - controller: 'FeedController', + controller: 'ContentController', templateUrl: 'content.html', - resolve: {} + resolve: getResolve(feedType.FEED) }).when('/items/folders/:id', { - controller: 'FolderController', + controller: 'ContentController', templateUrl: 'content.html', - resolve: {} + resolve: getResolve(feedType.FOLDER) }).otherwise({ redirectTo: '/items' }); } ]); @@ -70,26 +105,26 @@ app.run([ 'Publisher', 'BASE_URL', 'FEED_TYPE', - 'CONFIG', - function ($rootScope, $location, $http, $q, $interval, Loading, Item, Feed, Folder, Settings, Publisher, BASE_URL, FEED_TYPE, CONFIG) { + 'REFRESH_RATE', + function ($rootScope, $location, $http, $q, $interval, Loading, Item, Feed, Folder, Settings, Publisher, BASE_URL, FEED_TYPE, REFRESH_RATE) { 'use strict'; // show Loading screen Loading.setLoading('global', true); // listen to keys in returned queries to automatically distribute the // incoming values to models - Publisher.subscribe(Item).toChannel('items'); - Publisher.subscribe(Folder).toChannel('folders'); - Publisher.subscribe(Feed).toChannel('feeds'); - Publisher.subscribe(Settings).toChannel('settings'); + Publisher.subscribe(Item).toChannels('items', 'newestItemId', 'starred'); + Publisher.subscribe(Folder).toChannels('folders'); + Publisher.subscribe(Feed).toChannels('feeds'); + Publisher.subscribe(Settings).toChannels('settings'); // load feeds, settings and last read feed - var settingsDeferred, activeFeedDeferred; + var settingsDeferred, activeFeedDeferred, folderDeferred, feedDeferred; settingsDeferred = $q.defer(); - $http.get(BASE_URL + '/settings').then(function (data) { + $http.get(BASE_URL + '/settings').success(function (data) { Publisher.publishAll(data); settingsDeferred.resolve(); }); activeFeedDeferred = $q.defer(); - $http.get(BASE_URL + '/feeds/active').then(function (data) { + $http.get(BASE_URL + '/feeds/active').success(function (data) { var url; switch (data.type) { case FEED_TYPE.FEED: @@ -107,10 +142,22 @@ app.run([ $location.path(url); activeFeedDeferred.resolve(); }); + folderDeferred = $q.defer(); + $http.get(BASE_URL + '/folders').success(function (data) { + Publisher.publishAll(data); + folderDeferred.resolve(); + }); + feedDeferred = $q.defer(); + $http.get(BASE_URL + '/feeds').success(function (data) { + Publisher.publishAll(data); + feedDeferred.resolve(); + }); // disable loading if all initial requests finished $q.all([ settingsDeferred.promise, - activeFeedDeferred.promise + activeFeedDeferred.promise, + feedDeferred.promise, + folderDeferred.promise ]).then(function () { Loading.setLoading('global', false); }); @@ -118,7 +165,7 @@ app.run([ $interval(function () { $http.get(BASE_URL + '/feeds'); $http.get(BASE_URL + '/folders'); - }, CONFIG.REFRESH_RATE * 1000); + }, REFRESH_RATE * 1000); $rootScope.$on('$routeChangeStart', function () { Loading.setLoading('content', true); }); @@ -185,6 +232,24 @@ app.factory('Item', [ Model.call(this, 'id'); }; Item.prototype = Object.create(Model.prototype); + Item.prototype.receive = function (value, channel) { + switch (channel) { + case 'newestItemId': + this.newestItemId = value; + break; + case 'starred': + this.starredCount = value; + break; + default: + Model.prototype.receive.call(this, value, channel); + } + }; + Item.prototype.getNewestItemId = function () { + return this.newestItemId; + }; + Item.prototype.getStarredCount = function () { + return this.starredCount; + }; return new Item(); } ]); @@ -271,9 +336,13 @@ app.service('Publisher', function () { this.channels = {}; this.subscribe = function (object) { return { - toChannel: function (channel) { - self.channels[channel] = self.channels[channel] || []; - self.channels[channel].push(object); + toChannels: function () { + var counter, channel; + for (counter = 0; counter < arguments.length; counter += 1) { + channel = arguments[counter]; + self.channels[channel] = self.channels[channel] || []; + self.channels[channel].push(object); + } } }; }; @@ -282,7 +351,7 @@ app.service('Publisher', function () { for (channel in data) { if (data.hasOwnProperty(channel) && this.channels[channel] !== undefined) { for (counter = 0; counter < this.channels[channel].length; counter += 1) { - this.channels[channel][counter].receive(data[channel]); + this.channels[channel][counter].receive(data[channel], channel); } } } diff --git a/js/controller/ItemController.js b/js/controller/ContentController.js index ffada2a5c..ffada2a5c 100644 --- a/js/controller/ItemController.js +++ b/js/controller/ContentController.js diff --git a/js/service/Item.js b/js/service/Item.js index 0dd9b8677..ec3512f22 100644 --- a/js/service/Item.js +++ b/js/service/Item.js @@ -16,5 +16,29 @@ app.factory('Item', function (Model) { Item.prototype = Object.create(Model.prototype); + Item.prototype.receive = function (value, channel) { + switch (channel) { + + case 'newestItemId': + this.newestItemId = value; + break; + + case 'starred': + this.starredCount = value; + break; + default: + Model.prototype.receive.call(this, value, channel); + } + }; + + Item.prototype.getNewestItemId = function () { + return this.newestItemId; + }; + + Item.prototype.getStarredCount = function () { + return this.starredCount; + }; + + return new Item(); });
\ No newline at end of file diff --git a/js/service/Publisher.js b/js/service/Publisher.js index da9b0a470..784b2fff6 100644 --- a/js/service/Publisher.js +++ b/js/service/Publisher.js @@ -15,9 +15,14 @@ app.service('Publisher', function () { this.subscribe = function (object) { return { - toChannel: function (channel) { - self.channels[channel] = self.channels[channel] || []; - self.channels[channel].push(object); + toChannels: function () { + var counter, + channel; + for (counter = 0; counter < arguments.length; counter += 1) { + channel = arguments[counter]; + self.channels[channel] = self.channels[channel] || []; + self.channels[channel].push(object); + } } }; }; @@ -29,7 +34,7 @@ app.service('Publisher', function () { for (channel in data) { if (data.hasOwnProperty(channel) && this.channels[channel] !== undefined) { for (counter = 0; counter < this.channels[channel].length; counter += 1) { - this.channels[channel][counter].receive(data[channel]); + this.channels[channel][counter].receive(data[channel], channel); } } } diff --git a/js/tests/unit/service/ItemSpec.js b/js/tests/unit/service/ItemSpec.js new file mode 100644 index 000000000..85ee5789e --- /dev/null +++ b/js/tests/unit/service/ItemSpec.js @@ -0,0 +1,43 @@ +/** + * ownCloud - News + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Bernhard Posselt <dev@bernhard-posselt.com> + * @copyright Bernhard Posselt 2014 + */ +describe('Item', function () { + 'use strict'; + + beforeEach(module('News')); + + + it('should receive the newestItemId', inject(function (Item) { + Item.receive(3, 'newestItemId'); + + expect(Item.getNewestItemId()).toBe(3); + })); + + + it('should receive the newestItemId', inject(function (Item) { + Item.receive(2, 'starred'); + + expect(Item.getStarredCount()).toBe(2); + })); + + + it('should receive items', inject(function (Item) { + Item.receive([ + { + id: 3 + }, + { + id: 4 + } + ], 'items'); + + expect(Item.size()).toBe(2); + })); + +});
\ No newline at end of file diff --git a/js/tests/unit/service/PublisherSpec.js b/js/tests/unit/service/PublisherSpec.js index 2b9206c93..8d7b65e58 100644 --- a/js/tests/unit/service/PublisherSpec.js +++ b/js/tests/unit/service/PublisherSpec.js @@ -17,13 +17,28 @@ describe('Publisher', function () { var obj = { receive: jasmine.createSpy('receive') }; - Publisher.subscribe(obj).toChannel('test'); + Publisher.subscribe(obj).toChannels('test'); Publisher.publishAll({ test: 'tom' }); - expect(obj.receive).toHaveBeenCalledWith('tom'); + expect(obj.receive).toHaveBeenCalledWith('tom', 'test'); + })); + + + it('should should publish on all possible channels', inject(function (Publisher) { + + var obj = { + receive: jasmine.createSpy('receive') + }; + Publisher.subscribe(obj).toChannels('test', 'tiny'); + + Publisher.publishAll({ + tiny: 'tom' + }); + + expect(obj.receive).toHaveBeenCalledWith('tom', 'tiny'); })); |