diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/build/app.js | 185 | ||||
-rw-r--r-- | js/controller/ContentController.js | 7 | ||||
-rw-r--r-- | js/directive/NewsAudio.js | 39 | ||||
-rw-r--r-- | js/directive/NewsScroll.js | 47 | ||||
-rw-r--r-- | js/filter/TrustUrl.js | 16 | ||||
-rw-r--r-- | js/service/FeedResource.js | 8 | ||||
-rw-r--r-- | js/service/SettingsResource.js | 7 | ||||
-rw-r--r-- | js/tests/unit/controller/ContentControllerSpec.js | 6 | ||||
-rw-r--r-- | js/tests/unit/service/FeedResourceSpec.js | 7 |
9 files changed, 249 insertions, 73 deletions
diff --git a/js/build/app.js b/js/build/app.js index 27cd1ba6f..a8119dc82 100644 --- a/js/build/app.js +++ b/js/build/app.js @@ -235,6 +235,7 @@ var $__build_47_app__ = function () { }; this.scrollRead = function (itemIds) { var ids = []; + var feedIds = []; for (var $__3 = itemIds[$traceurRuntime.toProperty(Symbol.iterator)](), $__4; !($__4 = $__3.next()).done;) { try { throw undefined; @@ -247,12 +248,13 @@ var $__build_47_app__ = function () { item = ItemResource.get(itemId); if (!item.keepUnread) { ids.push(itemId); - FeedResource.markItemOfFeedRead(item.feedId); + feedIds.push(item.feedId); } } } } } + FeedResource.markItemsOfFeedsRead(feedIds); ItemResource.markItemsRead(ids); }; this.autoPage = function () { @@ -272,9 +274,14 @@ var $__build_47_app__ = function () { if (timestamp !== undefined && timestamp !== '') { try { throw undefined; - } catch (languageCode) { - languageCode = SettingsResource.get('language'); - return moment.unix(timestamp).lang(languageCode).fromNow(); + } catch (date) { + try { + throw undefined; + } catch (languageCode) { + languageCode = SettingsResource.get('language'); + date = moment.unix(timestamp).lang(languageCode).fromNow() + ''; + return date; + } } } else { return ''; @@ -384,6 +391,15 @@ var $__build_47_app__ = function () { }; } ]); + app.filter('trustUrl', [ + '$sce', + function ($sce) { + 'use strict'; + return function (url) { + return $sce.trustAsResourceUrl(url); + }; + } + ]); app.factory('FeedResource', [ 'Resource', '$http', @@ -475,6 +491,19 @@ var $__build_47_app__ = function () { this.ids[$traceurRuntime.toProperty(feedId)].unreadCount -= 1; this.updateUnreadCache(); }, + markItemsOfFeedsRead: function (feedIds) { + for (var $__3 = feedIds[$traceurRuntime.toProperty(Symbol.iterator)](), $__4; !($__4 = $__3.next()).done;) { + try { + throw undefined; + } catch (feedId) { + feedId = $__4.value; + { + this.ids[$traceurRuntime.toProperty(feedId)].unreadCount -= 1; + } + } + } + this.updateUnreadCache(); + }, markItemOfFeedUnread: function (feedId) { this.ids[$traceurRuntime.toProperty(feedId)].unreadCount += 1; this.updateUnreadCache(); @@ -810,7 +839,12 @@ var $__build_47_app__ = function () { function ($http, BASE_URL) { 'use strict'; var $__0 = this; - this.settings = {}; + this.settings = { + language: 'en', + showAll: false, + compact: false, + oldestFirst: false + }; this.defaultLanguageCode = 'en'; this.supportedLanguageCodes = [ 'ar-ma', @@ -1308,6 +1342,30 @@ var $__build_47_app__ = function () { writable: true }), $__2; }; + app.directive('newsAudio', function () { + 'use strict'; + return { + restrict: 'E', + scope: { + src: '@', + type: '@' + }, + transclude: true, + template: '' + '<audio controls="controls" preload="none" ng-hide="cantPlay()">' + '<source ng-src="{{ src|trustUrl }}">' + '</audio>' + '<a ng-href="{{ src|trustUrl }}" class="button" ng-show="cantPlay()" ' + 'ng-transclude></a>', + link: function (scope, elm) { + var source = elm.children().children('source')[0]; + var cantPlay = false; + source.addEventListener('error', function () { + scope.$apply(function () { + cantPlay = true; + }); + }); + scope.cantPlay = function () { + return cantPlay; + }; + } + }; + }); app.directive('newsAutoFocus', function () { 'use strict'; return function (scope, elem, attrs) { @@ -1341,55 +1399,92 @@ var $__build_47_app__ = function () { '$timeout', function ($timeout) { 'use strict'; - var autoPage = function (enabled, limit, callback, elem) { + var autoPage = function (enabled, limit, elem, scope) { if (enabled) { try { throw undefined; - } catch (counter) { - counter = 0; - for (var $__3 = reverse(elem.find('.feed_item'))[$traceurRuntime.toProperty(Symbol.iterator)](), $__4; !($__4 = $__3.next()).done;) { - try { - throw undefined; - } catch (item) { - item = $__4.value; - { - item = $(item); - if (counter >= limit) { - break; - } - if (item.position().top < 0) { - callback(); - break; + } catch (articles) { + try { + throw undefined; + } catch (counter) { + counter = 0; + articles = elem.find('.item'); + { + try { + throw undefined; + } catch ($i) { + $i = articles.length - 1; + for (; $i >= 0; $i -= 1) { + try { + throw undefined; + } catch (i) { + i = $i; + try { + try { + throw undefined; + } catch (item) { + item = $(articles[$traceurRuntime.toProperty(i)]); + if (counter >= limit) { + break; + } + if (item.position().top < 0) { + scope.$apply(scope.newsScrollAutoPage); + break; + } + counter += 1; + } + } finally { + $i = i; + } + } } - counter += 1; } } } } } }; - var markRead = function (enabled, callback, elem) { + var markRead = function (enabled, elem, scope) { if (enabled) { try { throw undefined; - } catch (ids) { - ids = []; - for (var $__3 = elem.find('.feed_item:not(.read)')[$traceurRuntime.toProperty(Symbol.iterator)](), $__4; !($__4 = $__3.next()).done;) { - try { - throw undefined; - } catch (item) { - item = $__4.value; - { - item = $(item); - if (item.position().top <= -50) { - ids.push(parseInt(item.data('id'), 10)); - } else { - break; + } catch (articles) { + try { + throw undefined; + } catch (ids) { + ids = []; + articles = elem.find('.item:not(.read)'); + { + try { + throw undefined; + } catch ($i) { + $i = 0; + for (; $i < articles.length; $i += 1) { + try { + throw undefined; + } catch (i) { + i = $i; + try { + try { + throw undefined; + } catch (item) { + item = $(articles[$traceurRuntime.toProperty(i)]); + if (item.position().top <= -50) { + ids.push(parseInt(item.data('id'), 10)); + } else { + break; + } + } + } finally { + $i = i; + } + } } } } + scope.itemIds = ids; + scope.$apply(scope.newsScrollMarkRead); } - callback(ids); } } }; @@ -1399,26 +1494,26 @@ var $__build_47_app__ = function () { 'newsScrollAutoPage': '&', 'newsScrollMarkRead': '&', 'newsScrollEnabledMarkRead': '=', - 'newsScrollEnableAutoPage': '=', + 'newsScrollEnabledAutoPage': '=', 'newsScrollMarkReadTimeout': '@', 'newsScrollTimeout': '@', 'newsScrollAutoPageWhenLeft': '@' }, link: function (scope, elem) { var allowScroll = true; - scope.newsScrollTimeout = scope.newsScrollTimeout || 1; - scope.newsScrollMarkReadTimeout = scope.newsScrollMarkReadTimeout || 1; - scope.newsScrollAutoPageWhenLeft = scope.newsScrollAutoPageWhenLeft || 50; + var scrollTimeout = scope.newsScrollTimeout || 1; + var markReadTimeout = scope.newsScrollMarkReadTimeout || 1; + var autoPageLimit = scope.newsScrollAutoPageWhenLeft || 50; var scrollHandler = function () { if (allowScroll) { allowScroll = false; $timeout(function () { allowScroll = true; - }, scope.newsScrollTimeout * 1000); - autoPage(scope.newsScrollEnableAutoPage, scope.newsScrollAutoPageWhenLeft, scope.newsScrollAutoPage, elem); + }, scrollTimeout * 1000); + autoPage(scope.newsScrollEnabledAutoPage, autoPageLimit, elem, scope); $timeout(function () { - markRead(scope.newsScrollEnabledMarkRead, scope.newsScrollMarkRead, elem); - }, scope.newsScrollMarkReadTimeout * 1000); + markRead(scope.newsScrollEnabledMarkRead, elem, scope); + }, markReadTimeout * 1000); } }; elem.on('scroll', scrollHandler); diff --git a/js/controller/ContentController.js b/js/controller/ContentController.js index 1af22ea5c..a42ff04f6 100644 --- a/js/controller/ContentController.js +++ b/js/controller/ContentController.js @@ -74,15 +74,17 @@ function (Publisher, FeedResource, ItemResource, SettingsResource, data, this.scrollRead = (itemIds) => { let ids = []; + let feedIds = []; for (let itemId of itemIds) { let item = ItemResource.get(itemId); if (!item.keepUnread) { ids.push(itemId); - FeedResource.markItemOfFeedRead(item.feedId); + feedIds.push(item.feedId); } } + FeedResource.markItemsOfFeedsRead(feedIds); ItemResource.markItemsRead(ids); }; @@ -106,7 +108,8 @@ function (Publisher, FeedResource, ItemResource, SettingsResource, data, this.getRelativeDate = (timestamp) => { if (timestamp !== undefined && timestamp !== '') { let languageCode = SettingsResource.get('language'); - return moment.unix(timestamp).lang(languageCode).fromNow(); + let date = moment.unix(timestamp).lang(languageCode).fromNow() + ''; + return date; } else { return ''; } diff --git a/js/directive/NewsAudio.js b/js/directive/NewsAudio.js new file mode 100644 index 000000000..efcf5dfec --- /dev/null +++ b/js/directive/NewsAudio.js @@ -0,0 +1,39 @@ +/** + * 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 + */ +app.directive('newsAudio', () => { + 'use strict'; + return { + restrict: 'E', + scope: { + src: '@', + type: '@' + }, + transclude: true, + template: '' + + '<audio controls="controls" preload="none" ng-hide="cantPlay()">' + + '<source ng-src="{{ src|trustUrl }}">' + + '</audio>' + + '<a ng-href="{{ src|trustUrl }}" class="button" ng-show="cantPlay()" ' + + 'ng-transclude></a>', + link: (scope, elm) => { + let source = elm.children().children('source')[0]; + let cantPlay = false; + source.addEventListener('error', () => { + scope.$apply(() => { + cantPlay = true; + }); + }); + + scope.cantPlay = () => { + return cantPlay; + }; + } + }; +});
\ No newline at end of file diff --git a/js/directive/NewsScroll.js b/js/directive/NewsScroll.js index 126c79b11..3d566aebe 100644 --- a/js/directive/NewsScroll.js +++ b/js/directive/NewsScroll.js @@ -11,11 +11,13 @@ app.directive('newsScroll', ($timeout) => { 'use strict'; // autopaging - let autoPage = (enabled, limit, callback, elem) => { + let autoPage = (enabled, limit, elem, scope) => { if (enabled) { let counter = 0; - for (let item of reverse(elem.find('.feed_item'))) { - item = $(item); + let articles = elem.find('.item'); + + for (let i = articles.length - 1; i >= 0; i -= 1) { + let item = $(articles[i]); // if the counter is higher than the size it means @@ -29,7 +31,7 @@ app.directive('newsScroll', ($timeout) => { // below the top and we didnt hit the factor yet so // autopage and break if (item.position().top < 0) { - callback(); + scope.$apply(scope.newsScrollAutoPage); break; } @@ -39,12 +41,14 @@ app.directive('newsScroll', ($timeout) => { }; // mark read - let markRead = (enabled, callback, elem) => { + let markRead = (enabled, elem, scope) => { if (enabled) { let ids = []; - for (let item of elem.find('.feed_item:not(.read)')) { - item = $(item); + let articles = elem.find('.item:not(.read)'); + + for (let i = 0; i < articles.length; i += 1) { + let item = $(articles[i]); if (item.position().top <= -50) { ids.push(parseInt(item.data('id'), 10)); @@ -53,7 +57,8 @@ app.directive('newsScroll', ($timeout) => { } } - callback(ids); + scope.itemIds = ids; + scope.$apply(scope.newsScrollMarkRead); } }; @@ -63,7 +68,7 @@ app.directive('newsScroll', ($timeout) => { 'newsScrollAutoPage': '&', 'newsScrollMarkRead': '&', 'newsScrollEnabledMarkRead': '=', - 'newsScrollEnableAutoPage': '=', + 'newsScrollEnabledAutoPage': '=', 'newsScrollMarkReadTimeout': '@', // optional, defaults to 1 second 'newsScrollTimeout': '@', // optional, defaults to 1 second 'newsScrollAutoPageWhenLeft': '@' // optional, defaults to 50 @@ -71,11 +76,9 @@ app.directive('newsScroll', ($timeout) => { link: (scope, elem) => { let allowScroll = true; - scope.newsScrollTimeout = scope.newsScrollTimeout || 1; - scope.newsScrollMarkReadTimeout = - scope.newsScrollMarkReadTimeout || 1; - scope.newsScrollAutoPageWhenLeft = - scope.newsScrollAutoPageWhenLeft || 50; + let scrollTimeout = scope.newsScrollTimeout || 1; + let markReadTimeout = scope.newsScrollMarkReadTimeout || 1; + let autoPageLimit = scope.newsScrollAutoPageWhenLeft || 50; let scrollHandler = () => { // allow only one scroll event to trigger at once @@ -84,19 +87,19 @@ app.directive('newsScroll', ($timeout) => { $timeout(() => { allowScroll = true; - }, scope.newsScrollTimeout*1000); + }, scrollTimeout*1000); - autoPage(scope.newsScrollEnableAutoPage, - scope.newsScrollAutoPageWhenLeft, - scope.newsScrollAutoPage, - elem); + autoPage(scope.newsScrollEnabledAutoPage, + autoPageLimit, + elem, + scope); // allow user to undo accidental scroll $timeout(() => { markRead(scope.newsScrollEnabledMarkRead, - scope.newsScrollMarkRead, - elem); - }, scope.newsScrollMarkReadTimeout*1000); + elem, + scope); + }, markReadTimeout*1000); } }; diff --git a/js/filter/TrustUrl.js b/js/filter/TrustUrl.js new file mode 100644 index 000000000..e0958ad2d --- /dev/null +++ b/js/filter/TrustUrl.js @@ -0,0 +1,16 @@ +/** + * 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 + */ +app.filter('trustUrl', ($sce) => { + 'use strict'; + + return (url) => { + return $sce.trustAsResourceUrl(url); + }; +});
\ No newline at end of file diff --git a/js/service/FeedResource.js b/js/service/FeedResource.js index 135601b2f..ab5aec9b4 100644 --- a/js/service/FeedResource.js +++ b/js/service/FeedResource.js @@ -89,6 +89,14 @@ app.factory('FeedResource', (Resource, $http, BASE_URL) => { } + markItemsOfFeedsRead (feedIds) { + for (let feedId of feedIds) { + this.ids[feedId].unreadCount -= 1; + } + this.updateUnreadCache(); + } + + markItemOfFeedUnread (feedId) { this.ids[feedId].unreadCount += 1; this.updateUnreadCache(); diff --git a/js/service/SettingsResource.js b/js/service/SettingsResource.js index 30982a916..99a6cf72d 100644 --- a/js/service/SettingsResource.js +++ b/js/service/SettingsResource.js @@ -12,7 +12,12 @@ app.service('SettingsResource', function ($http, BASE_URL) { 'use strict'; - this.settings = {}; + this.settings = { + language: 'en', + showAll: false, + compact: false, + oldestFirst: false + }; this.defaultLanguageCode = 'en'; this.supportedLanguageCodes = [ 'ar-ma', 'ar', 'bg', 'ca', 'cs', 'cv', 'da', 'de', 'el', 'en-ca', diff --git a/js/tests/unit/controller/ContentControllerSpec.js b/js/tests/unit/controller/ContentControllerSpec.js index 9fe769ffa..e649219d6 100644 --- a/js/tests/unit/controller/ContentControllerSpec.js +++ b/js/tests/unit/controller/ContentControllerSpec.js @@ -223,7 +223,7 @@ describe('ContentController', () => { Publisher.subscribe(ItemResource).toChannels('items'); ItemResource.markItemsRead = jasmine.createSpy('markRead'); - FeedResource.markItemOfFeedRead = jasmine.createSpy('markRead'); + FeedResource.markItemsOfFeedsRead = jasmine.createSpy('markRead'); let ctrl = $controller('ContentController', { ItemResource: ItemResource, @@ -231,7 +231,7 @@ describe('ContentController', () => { data: { 'items': [{ id: 3, - feedId: 4 + feedId: 6 }, { id: 2, @@ -248,7 +248,7 @@ describe('ContentController', () => { ctrl.scrollRead([3, 2, 1]); expect(ItemResource.markItemsRead).toHaveBeenCalledWith([3, 1]); - expect(FeedResource.markItemOfFeedRead.callCount).toBe(2); + expect(FeedResource.markItemsOfFeedsRead).toHaveBeenCalledWith([6, 4]); })); diff --git a/js/tests/unit/service/FeedResourceSpec.js b/js/tests/unit/service/FeedResourceSpec.js index d14d7f716..5187435f0 100644 --- a/js/tests/unit/service/FeedResourceSpec.js +++ b/js/tests/unit/service/FeedResourceSpec.js @@ -97,4 +97,11 @@ describe('FeedResource', () => { FeedResource.markRead(); expect(FeedResource.getFolderUnreadCount(4)).toBe(0); })); + + + it('should cache unreadcount', inject((FeedResource) => { + FeedResource.markItemsOfFeedsRead([1, 2]); + expect(FeedResource.getUnreadCount()).toBe(68); + })); + }); |