summaryrefslogtreecommitdiffstats
path: root/js
diff options
context:
space:
mode:
authorBernhard Posselt <dev@bernhard-posselt.com>2014-05-30 15:14:07 +0200
committerBernhard Posselt <dev@bernhard-posselt.com>2014-05-30 15:14:07 +0200
commit88279961c5e2f2bd0711fc4200d58b93b425199e (patch)
tree1e07557fdbd6f037b143fd49f454199737d12f45 /js
parentabd5ef4c4c6ad3cf8e879f6c4b9181b077165952 (diff)
fix autopaging and marking read, render items
Diffstat (limited to 'js')
-rw-r--r--js/build/app.js185
-rw-r--r--js/controller/ContentController.js7
-rw-r--r--js/directive/NewsAudio.js39
-rw-r--r--js/directive/NewsScroll.js47
-rw-r--r--js/filter/TrustUrl.js16
-rw-r--r--js/service/FeedResource.js8
-rw-r--r--js/service/SettingsResource.js7
-rw-r--r--js/tests/unit/controller/ContentControllerSpec.js6
-rw-r--r--js/tests/unit/service/FeedResourceSpec.js7
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);
+ }));
+
});