1
0
mirror of https://github.com/chylex/Nextcloud-News.git synced 2025-05-06 07:34:06 +02:00

Cleanup JS and prolong error notification

This commit is contained in:
Sean Molenaar 2019-02-24 11:40:29 +01:00 committed by Sean Molenaar
parent 45474dc862
commit 6a4e56e727
15 changed files with 406 additions and 432 deletions

View File

@ -19,7 +19,7 @@
"strict": true, "strict": true,
"maxparams": false, "maxparams": false,
"maxdepth": 3, "maxdepth": 3,
"maxlen": 80, "maxlen": 120,
"browser": true, "browser": true,
"devel": true, "devel": true,
"jquery": true, "jquery": true,

View File

@ -9,10 +9,10 @@
*/ */
$('#content.app-news') $('#content.app-news')
.attr('ng-app', 'News') .attr('ng-app', 'News')
.attr('ng-cloak', '') .attr('ng-cloak', '')
.attr('ng-strict-di', '') .attr('ng-strict-di', '')
.attr('ng-controller', 'AppController as App'); .attr('ng-controller', 'AppController as App');
/* jshint unused: false */ /* jshint unused: false */
var app = angular.module('News', ['ngRoute', 'ngSanitize', 'ngAnimate']); var app = angular.module('News', ['ngRoute', 'ngSanitize', 'ngAnimate']);

View File

@ -7,8 +7,7 @@
* @author Bernhard Posselt <dev@bernhard-posselt.com> * @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright Bernhard Posselt 2014 * @copyright Bernhard Posselt 2014
*/ */
app.config( app.config(function ($routeProvider, $provide, $httpProvider, $locationProvider) {
function ($routeProvider, $provide, $httpProvider, $locationProvider) {
'use strict'; 'use strict';
var feedType = { var feedType = {
@ -58,26 +57,31 @@ app.config(
403: t('news', 'Request forbidden. Are you an admin?'), 403: t('news', 'Request forbidden. Are you an admin?'),
412: t('news', 'Token expired or app not enabled! Reload the page!'), 412: t('news', 'Token expired or app not enabled! Reload the page!'),
500: t('news', 'Internal server error! Please check your ' + 500: t('news', 'Internal server error! Please check your ' +
'data/nextcloud.log file for additional ' + 'data/nextcloud.log file for additional ' +
'information!'), 'information!'),
503: t('news', 'Request failed, Nextcloud is in currently ' + 503: t('news', 'Request failed, Nextcloud is in currently ' +
'in maintenance mode!') 'in maintenance mode!')
}; };
$provide.factory('ConnectionErrorInterceptor', function ($q, $timeout) { $provide.factory('ConnectionErrorInterceptor', function ($q, $timeout) {
var timer; var timer;
return { return {
responseError: function (response) { responseError: function (response) {
// status 0 is a network error // status 0 is a network error
if (response.status in errorMessages) { function sendNotification() {
if (timer) {
$timeout.cancel(timer);
}
OC.Notification.hide();
OC.Notification.showHtml(errorMessages[response.status]); OC.Notification.showHtml(errorMessages[response.status]);
timer = $timeout(function () { timer = $timeout(function () {
OC.Notification.hide(); OC.Notification.hide();
}, 5000); }, 5000);
} }
if (response.status in errorMessages) {
if (timer) {
timer.then(function (){
sendNotification();
});
} else {
sendNotification();
}
}
return $q.reject(response); return $q.reject(response);
} }
}; };
@ -90,8 +94,8 @@ app.config(
return { return {
// request to items also returns feeds // request to items also returns feeds
data: /* @ngInject */ function ( data: /* @ngInject */ function (
$http, $route, $q, $location, BASE_URL, ITEM_BATCH_SIZE, FEED_TYPE, $http, $route, $q, $location, BASE_URL, ITEM_BATCH_SIZE, FEED_TYPE,
SettingsResource, FeedResource) { SettingsResource, FeedResource) {
var showAll = SettingsResource.get('showAll'); var showAll = SettingsResource.get('showAll');
var oldestFirst = SettingsResource.get('oldestFirst'); var oldestFirst = SettingsResource.get('oldestFirst');
@ -129,7 +133,7 @@ app.config(
} }
return $http({ return $http({
url: BASE_URL + '/items', url: BASE_URL + '/items',
method: 'GET', method: 'GET',
params: parameters params: parameters
}).then(function (response) { }).then(function (response) {
@ -143,7 +147,7 @@ app.config(
var getExploreResolve = function () { var getExploreResolve = function () {
return { return {
sites: /* @ngInject */ function ( sites: /* @ngInject */ function (
$http, $q, BASE_URL, $location, Publisher, SettingsResource) { $http, $q, BASE_URL, $location, Publisher, SettingsResource) {
// always use the code from the url // always use the code from the url
var language = $location.search().lang; var language = $location.search().lang;
if (!language) { if (!language) {
@ -198,13 +202,13 @@ app.config(
resolve: getItemResolve(feedType.FOLDER), resolve: getItemResolve(feedType.FOLDER),
type: feedType.FOLDER type: feedType.FOLDER
}).when('/explore', { }).when('/explore', {
controller: 'ExploreController as Explore', controller: 'ExploreController as Explore',
templateUrl: 'explore.html', templateUrl: 'explore.html',
resolve: getExploreResolve(), resolve: getExploreResolve(),
type: feedType.EXPLORE type: feedType.EXPLORE
}).when('/shortcuts', { }).when('/shortcuts', {
templateUrl: 'shortcuts.html', templateUrl: 'shortcuts.html',
type: -1 type: -1
}); });
}); });

View File

@ -7,9 +7,8 @@
* @author Bernhard Posselt <dev@bernhard-posselt.com> * @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright Bernhard Posselt 2014 * @copyright Bernhard Posselt 2014
*/ */
app.run(function ($rootScope, $location, $http, $q, $interval, $route, Loading, app.run(function ($rootScope, $location, $http, $q, $interval, $route, Loading, ItemResource, FeedResource,
ItemResource, FeedResource, FolderResource, SettingsResource, FolderResource, SettingsResource, Publisher, BASE_URL, FEED_TYPE, REFRESH_RATE) {
Publisher, BASE_URL, FEED_TYPE, REFRESH_RATE) {
'use strict'; 'use strict';
// show Loading screen // show Loading screen
@ -18,53 +17,50 @@ app.run(function ($rootScope, $location, $http, $q, $interval, $route, Loading,
// listen to keys in returned queries to automatically distribute the // listen to keys in returned queries to automatically distribute the
// incoming values to models // incoming values to models
Publisher.subscribe(ItemResource).toChannels(['items', 'newestItemId', Publisher.subscribe(ItemResource).toChannels(['items', 'newestItemId',
'starred']); 'starred']);
Publisher.subscribe(FolderResource).toChannels(['folders']); Publisher.subscribe(FolderResource).toChannels(['folders']);
Publisher.subscribe(FeedResource).toChannels(['feeds']); Publisher.subscribe(FeedResource).toChannels(['feeds']);
Publisher.subscribe(SettingsResource).toChannels(['settings']); Publisher.subscribe(SettingsResource).toChannels(['settings']);
// load feeds, settings and last read feed // load feeds, settings and last read feed
var settingsPromise = $http.get(BASE_URL + '/settings').then( var settingsPromise = $http.get(BASE_URL + '/settings').then(function (response) {
function (response) { Publisher.publishAll(response.data);
Publisher.publishAll(response.data); return response.data;
return response.data;
}); });
var path = $location.path(); var path = $location.path();
var activeFeedPromise = $http.get(BASE_URL + '/feeds/active') var activeFeedPromise = $http.get(BASE_URL + '/feeds/active')
.then(function (response) { .then(function (response) {
var url; var url;
switch (response.data.activeFeed.type) {
case FEED_TYPE.FEED:
url = '/items/feeds/' + response.data.activeFeed.id;
break;
switch (response.data.activeFeed.type) { case FEED_TYPE.FOLDER:
url = '/items/folders/' + response.data.activeFeed.id;
break;
case FEED_TYPE.FEED: case FEED_TYPE.STARRED:
url = '/items/feeds/' + response.data.activeFeed.id; url = '/items/starred';
break; break;
case FEED_TYPE.FOLDER: case FEED_TYPE.EXPLORE:
url = '/items/folders/' + response.data.activeFeed.id; url = '/explore';
break; break;
case FEED_TYPE.STARRED: default:
url = '/items/starred'; url = '/items';
break; }
case FEED_TYPE.EXPLORE: // only redirect if url is empty or faulty
url = '/explore'; if (!/^\/items(\/(starred|explore|feeds\/\d+|folders\/\d+))?\/?$/
break; .test(path)) {
$location.path(url);
}
default: return response.data;
url = '/items'; });
}
// only redirect if url is empty or faulty
if (!/^\/items(\/(starred|explore|feeds\/\d+|folders\/\d+))?\/?$/
.test(path)) {
$location.path(url);
}
return response.data;
});
var feeds; var feeds;
var feedPromise = $http.get(BASE_URL + '/feeds').then(function (response) { var feedPromise = $http.get(BASE_URL + '/feeds').then(function (response) {
@ -74,10 +70,10 @@ app.run(function ($rootScope, $location, $http, $q, $interval, $route, Loading,
var folders; var folders;
var folderPromise = $http.get(BASE_URL + '/folders') var folderPromise = $http.get(BASE_URL + '/folders')
.then(function (response) { .then(function (response) {
folders = response.data; folders = response.data;
return folders; return folders;
}); });
$q.all([ $q.all([
feedPromise, feedPromise,

View File

@ -7,8 +7,7 @@
* @author Bernhard Posselt <dev@bernhard-posselt.com> * @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright Bernhard Posselt 2014 * @copyright Bernhard Posselt 2014
*/ */
app.controller('AppController', app.controller('AppController', function (Loading, FeedResource, FolderResource) {
function (Loading, FeedResource, FolderResource) {
'use strict'; 'use strict';
this.loading = Loading; this.loading = Loading;

View File

@ -7,221 +7,213 @@
* @author Bernhard Posselt <dev@bernhard-posselt.com> * @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright Bernhard Posselt 2014 * @copyright Bernhard Posselt 2014
*/ */
app.controller('ContentController', app.controller('ContentController', function (Publisher, FeedResource, ItemResource, SettingsResource, data, $route,
function (Publisher, FeedResource, ItemResource, SettingsResource, data, $routeParams, $location, FEED_TYPE, ITEM_AUTO_PAGE_SIZE, Loading,
$route, $routeParams, $location, FEED_TYPE, ITEM_AUTO_PAGE_SIZE, $filter) {
Loading, $filter) { 'use strict';
'use strict';
var self = this; var self = this;
ItemResource.clear(); ItemResource.clear();
// distribute data to models based on key // distribute data to models based on key
Publisher.publishAll(data); Publisher.publishAll(data);
this.getFirstItem = function () { this.getFirstItem = function () {
var orderFilter = $filter('orderBy'); var orderFilter = $filter('orderBy');
var orderedItems = orderFilter(this.getItems(), this.orderBy()); var orderedItems = orderFilter(this.getItems(), this.orderBy());
var firstItem = orderedItems[0]; var firstItem = orderedItems[0];
if (firstItem === undefined) { if (firstItem === undefined) {
return undefined; return undefined;
} else {
return firstItem.id;
}
};
this.isAutoPagingEnabled = true;
// the interface should show a hint if there are not enough items sent
// it's assumed that theres nothing to autpage
if (ItemResource.size() >= ITEM_AUTO_PAGE_SIZE) {
this.isNothingMoreToAutoPage = false;
} else { } else {
this.isNothingMoreToAutoPage = true; return firstItem.id;
}
};
this.isAutoPagingEnabled = true;
// the interface should show a hint if there are not enough items sent
// it's assumed that theres nothing to autpage
this.isNothingMoreToAutoPage = ItemResource.size() < ITEM_AUTO_PAGE_SIZE;
this.getItems = function () {
return ItemResource.getAll();
};
this.isItemActive = function (id) {
return this.activeItem === id;
};
this.setItemActive = function (id) {
this.activeItem = id;
};
this.toggleStar = function (itemId) {
ItemResource.toggleStar(itemId);
};
this.toggleItem = function (item) {
// TODO: unittest
if (this.isCompactView()) {
item.show = !item.show;
}
};
this.isShowAll = function () {
return SettingsResource.get('showAll');
};
this.markRead = function (itemId) {
var item = ItemResource.get(itemId);
if (!item.keepUnread && item.unread === true) {
ItemResource.markItemRead(itemId);
FeedResource.markItemOfFeedRead(item.feedId);
}
};
this.getFeed = function (feedId) {
return FeedResource.getById(feedId);
};
this.toggleKeepUnread = function (itemId) {
var item = ItemResource.get(itemId);
if (!item.unread) {
FeedResource.markItemOfFeedUnread(item.feedId);
ItemResource.markItemRead(itemId, false);
} }
this.getItems = function () { item.keepUnread = !item.keepUnread;
return ItemResource.getAll(); };
};
this.isItemActive = function (id) { var getOrdering = function () {
return this.activeItem === id; var ordering = SettingsResource.get('oldestFirst');
};
this.setItemActive = function (id) { if (self.isFeed()) {
this.activeItem = id; var feed = FeedResource.getById($routeParams.id);
}; if (feed && feed.ordering === 1) {
ordering = true;
this.toggleStar = function (itemId) { } else if (feed && feed.ordering === 2) {
ItemResource.toggleStar(itemId); ordering = false;
};
this.toggleItem = function (item) {
// TODO: unittest
if (this.isCompactView()) {
item.show = !item.show;
} }
}; }
this.isShowAll = function () { return ordering;
return SettingsResource.get('showAll'); };
};
this.markRead = function (itemId) { this.orderBy = function () {
if (getOrdering()) {
return 'id';
} else {
return '-id';
}
};
this.isCompactView = function () {
return SettingsResource.get('compact');
};
this.isCompactExpand = function () {
return SettingsResource.get('compactExpand');
};
this.autoPagingEnabled = function () {
return this.isAutoPagingEnabled;
};
this.markReadEnabled = function () {
return !SettingsResource.get('preventReadOnScroll');
};
this.scrollRead = function (itemIds) {
var ids = [];
var feedIds = [];
itemIds.forEach(function (itemId) {
var item = ItemResource.get(itemId); var item = ItemResource.get(itemId);
if (!item.keepUnread) {
if (!item.keepUnread && item.unread === true) { ids.push(itemId);
ItemResource.markItemRead(itemId); feedIds.push(item.feedId);
FeedResource.markItemOfFeedRead(item.feedId);
} }
}; });
this.getFeed = function (feedId) { if (ids.length > 0) {
return FeedResource.getById(feedId); FeedResource.markItemsOfFeedsRead(feedIds);
}; ItemResource.markItemsRead(ids);
}
};
this.toggleKeepUnread = function (itemId) { this.isFeed = function () {
var item = ItemResource.get(itemId); return $route.current.$$route.type === FEED_TYPE.FEED;
if (!item.unread) { };
FeedResource.markItemOfFeedUnread(item.feedId);
ItemResource.markItemRead(itemId, false);
}
item.keepUnread = !item.keepUnread; this.autoPage = function () {
}; if (this.isNothingMoreToAutoPage) {
return;
}
var getOrdering = function () { // in case a subsequent autopage request comes in wait until
var ordering = SettingsResource.get('oldestFirst'); // the current one finished and execute a request immediately
// afterwards
if (!this.isAutoPagingEnabled) {
this.autoPageAgain = true;
return;
}
if (self.isFeed()) { this.isAutoPagingEnabled = false;
var feed = FeedResource.getById($routeParams.id); this.autoPageAgain = false;
if (feed && feed.ordering === 1) {
ordering = true;
} else if (feed && feed.ordering === 2) {
ordering = false;
}
}
return ordering; var type = $route.current.$$route.type;
}; var id = $routeParams.id;
var oldestFirst = getOrdering();
var showAll = SettingsResource.get('showAll');
var self = this;
var search = $location.search().search;
this.orderBy = function () { Loading.setLoading('autopaging', true);
if (getOrdering()) {
return 'id';
} else {
return '-id';
}
};
this.isCompactView = function () { ItemResource.autoPage(type, id, oldestFirst, showAll, search).then(function (response) {
return SettingsResource.get('compact'); Publisher.publishAll(response.data);
};
this.isCompactExpand = function () { if (response.data.items.length >= ITEM_AUTO_PAGE_SIZE) {
return SettingsResource.get('compactExpand');
};
this.autoPagingEnabled = function () {
return this.isAutoPagingEnabled;
};
this.markReadEnabled = function () {
return !SettingsResource.get('preventReadOnScroll');
};
this.scrollRead = function (itemIds) {
var ids = [];
var feedIds = [];
itemIds.forEach(function (itemId) {
var item = ItemResource.get(itemId);
if (!item.keepUnread) {
ids.push(itemId);
feedIds.push(item.feedId);
}
});
if (ids.length > 0) {
FeedResource.markItemsOfFeedsRead(feedIds);
ItemResource.markItemsRead(ids);
}
};
this.isFeed = function () {
return $route.current.$$route.type === FEED_TYPE.FEED;
};
this.autoPage = function () {
if (this.isNothingMoreToAutoPage) {
return;
}
// in case a subsequent autopage request comes in wait until
// the current one finished and execute a request immediately
// afterwards
if (!this.isAutoPagingEnabled) {
this.autoPageAgain = true;
return;
}
this.isAutoPagingEnabled = false;
this.autoPageAgain = false;
var type = $route.current.$$route.type;
var id = $routeParams.id;
var oldestFirst = getOrdering();
var showAll = SettingsResource.get('showAll');
var self = this;
var search = $location.search().search;
Loading.setLoading('autopaging', true);
ItemResource.autoPage(type, id, oldestFirst, showAll, search)
.then(function (response) {
Publisher.publishAll(response.data);
if (response.data.items.length >= ITEM_AUTO_PAGE_SIZE) {
self.isAutoPagingEnabled = true;
} else {
self.isNothingMoreToAutoPage = true;
}
if (self.isAutoPagingEnabled && self.autoPageAgain) {
self.autoPage();
}
return response.data;
}, function () {
self.isAutoPagingEnabled = true; self.isAutoPagingEnabled = true;
}).finally(function () {
Loading.setLoading('autopaging', false);
});
};
this.getRelativeDate = function (timestamp) {
if (timestamp !== undefined && timestamp !== '') {
var languageCode = SettingsResource.get('language');
var date =
moment.unix(timestamp).locale(languageCode).fromNow() + '';
return date;
} else { } else {
return ''; self.isNothingMoreToAutoPage = true;
} }
};
this.refresh = function () { if (self.isAutoPagingEnabled && self.autoPageAgain) {
$route.reload(); self.autoPage();
};
this.getMediaType = function (type) {
if (type && type.indexOf('audio') === 0) {
return 'audio';
} else if (type && type.indexOf('video') === 0) {
return 'video';
} else {
return undefined;
} }
}; return response.data;
}, function () {
self.isAutoPagingEnabled = true;
}).finally(function () {
Loading.setLoading('autopaging', false);
});
};
this.activeItem = this.getFirstItem(); this.getRelativeDate = function (timestamp) {
}); if (timestamp !== undefined && timestamp !== '') {
var languageCode = SettingsResource.get('language');
return moment.unix(timestamp).locale(languageCode).fromNow() + '';
} else {
return '';
}
};
this.refresh = function () {
$route.reload();
};
this.getMediaType = function (type) {
if (type && type.indexOf('audio') === 0) {
return 'audio';
} else if (type && type.indexOf('video') === 0) {
return 'video';
} else {
return undefined;
}
};
this.activeItem = this.getFirstItem();
});

View File

@ -7,52 +7,51 @@
* @author Bernhard Posselt <dev@bernhard-posselt.com> * @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright Bernhard Posselt 2014 * @copyright Bernhard Posselt 2014
*/ */
app.controller('ExploreController', app.controller('ExploreController', function (sites, $rootScope, FeedResource, SettingsResource, $location) {
function (sites, $rootScope, FeedResource, SettingsResource, $location) { 'use strict';
'use strict';
this.sites = sites; this.sites = sites;
// join all sites // join all sites
this.feeds = Object.keys(sites).map(function (key) { this.feeds = Object.keys(sites).map(function (key) {
return [key, sites[key]]; return [key, sites[key]];
}).reduce(function (xs, x) { }).reduce(function (xs, x) {
var category = x[0]; var category = x[0];
var feedList = x[1]; var feedList = x[1];
feedList.forEach(function (feed) { feedList.forEach(function (feed) {
feed.category = category; feed.category = category;
}); });
return xs.concat(feedList); return xs.concat(feedList);
}, []); }, []);
this.feedExists = function (location) { this.feedExists = function (location) {
return FeedResource.getByLocation(location) !== undefined; return FeedResource.getByLocation(location) !== undefined;
}; };
this.subscribeTo = function (location) { this.subscribeTo = function (location) {
$rootScope.$broadcast('addFeed', location); $rootScope.$broadcast('addFeed', location);
}; };
this.isCategoryShown = function (data) { this.isCategoryShown = function (data) {
return data.filter(function (element) { return data.filter(function (element) {
return FeedResource.getByLocation(element.feed) === undefined; return FeedResource.getByLocation(element.feed) === undefined;
}).length > 0; }).length > 0;
}; };
this.getSupportedLanguageCodes = function () { this.getSupportedLanguageCodes = function () {
return SettingsResource.getSupportedLanguageCodes(); return SettingsResource.getSupportedLanguageCodes();
}; };
this.getCurrentLanguageCode = function () { this.getCurrentLanguageCode = function () {
var language = $location.search().lang; var language = $location.search().lang;
if (!language) { if (!language) {
language = SettingsResource.get('language'); language = SettingsResource.get('language');
} }
return language; return language;
}; };
this.showLanguage = function (languageCode) { this.showLanguage = function (languageCode) {
$location.url('/explore/?lang=' + languageCode); $location.url('/explore/?lang=' + languageCode);
}; };
this.selectedLanguageCode = this.getCurrentLanguageCode(); this.selectedLanguageCode = this.getCurrentLanguageCode();
}); });

View File

@ -7,9 +7,8 @@
* @author Bernhard Posselt <dev@bernhard-posselt.com> * @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright Bernhard Posselt 2014 * @copyright Bernhard Posselt 2014
*/ */
app.controller('NavigationController', app.controller('NavigationController', function ($route, FEED_TYPE, FeedResource, FolderResource, ItemResource,
function ($route, FEED_TYPE, FeedResource, FolderResource, ItemResource, SettingsResource, Publisher, $rootScope, $location, $q) {
SettingsResource, Publisher, $rootScope, $location, $q) {
'use strict'; 'use strict';
this.feedError = ''; this.feedError = '';
@ -84,7 +83,7 @@ function ($route, FEED_TYPE, FeedResource, FolderResource, ItemResource,
return this.getFeedUnreadCount(feedId) > 0; return this.getFeedUnreadCount(feedId) > 0;
}; };
this.getFolderUnreadCount= function (folderId) { this.getFolderUnreadCount = function (folderId) {
return FeedResource.getFolderUnreadCount(folderId); return FeedResource.getFolderUnreadCount(folderId);
}; };
@ -175,15 +174,11 @@ function ($route, FEED_TYPE, FeedResource, FolderResource, ItemResource,
// is closed or has no unread articles // is closed or has no unread articles
existingFolder.getsFeed = true; existingFolder.getsFeed = true;
FeedResource.create(feed.url, existingFolder.id, undefined, FeedResource.create(feed.url, existingFolder.id, undefined, feed.user, feed.password).then(function (data) {
feed.user, feed.password)
.then(function (data) {
Publisher.publishAll(data); Publisher.publishAll(data);
// set folder as default // set folder as default
$location.path('/items/feeds/' + data.feeds[0].id + '/'); $location.path('/items/feeds/' + data.feeds[0].id + '/');
}).finally(function () { }).finally(function () {
existingFolder.getsFeed = undefined; existingFolder.getsFeed = undefined;
feed.url = ''; feed.url = '';

View File

@ -7,84 +7,80 @@
* @author Bernhard Posselt <dev@bernhard-posselt.com> * @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright Bernhard Posselt 2014 * @copyright Bernhard Posselt 2014
*/ */
app.controller('SettingsController', app.controller('SettingsController', function ($route, $q, SettingsResource, ItemResource, OPMLParser, OPMLImporter,
function ($route, $q, SettingsResource, ItemResource, OPMLParser, Publisher) {
OPMLImporter, Publisher) { 'use strict';
'use strict'; this.isOPMLImporting = false;
this.isOPMLImporting = false; this.isArticlesImporting = false;
this.isArticlesImporting = false; this.opmlImportError = false;
this.articleImportError = false;
this.opmlImportEmptyError = false;
var self = this;
var set = function (key, value) {
SettingsResource.set(key, value);
if (['showAll', 'oldestFirst', 'compact'].indexOf(key) >= 0) {
$route.reload();
}
};
this.toggleSetting = function (key) {
set(key, !this.getSetting(key));
};
this.getSetting = function (key) {
return SettingsResource.get(key);
};
this.importOPML = function (fileContent) {
self.opmlImportError = false;
self.opmlImportEmptyError = false;
self.articleImportError = false;
try {
this.isOPMLImporting = false;
var parsedContent = OPMLParser.parse(fileContent);
var jobSize = 5;
if (parsedContent.folders.length === 0 &&
parsedContent.feeds.length === 0) {
self.opmlImportEmptyError = true;
} else {
OPMLImporter.importFolders(parsedContent).then(function (feedQueue) {
return OPMLImporter.importFeedQueue(feedQueue, jobSize);
}).finally(function () {
self.isOPMLImporting = false;
});
}
} catch (error) {
this.opmlImportError = true;
console.error(error);
this.isOPMLImporting = false;
}
};
this.importArticles = function (content) {
this.opmlImportError = false; this.opmlImportError = false;
this.articleImportError = false; this.articleImportError = false;
this.opmlImportEmptyError = false;
var self = this;
var set = function (key, value) { try {
SettingsResource.set(key, value); this.isArticlesImporting = true;
var articles = JSON.parse(content);
if (['showAll', 'oldestFirst', 'compact'].indexOf(key) >= 0) { var self = this;
$route.reload(); ItemResource.importArticles(articles).then(function (data) {
} Publisher.publishAll(data);
}; }).finally(function () {
self.isArticlesImporting = false;
});
this.toggleSetting = function (key) { } catch (error) {
set(key, !this.getSetting(key)); console.error(error);
}; this.articleImportError = true;
this.isArticlesImporting = false;
this.getSetting = function (key) { }
return SettingsResource.get(key); };
}; });
this.importOPML = function (content) {
self.opmlImportError = false;
self.opmlImportEmptyError = false;
self.articleImportError = false;
try {
this.isOPMLImporting = false;
var parsedContent = OPMLParser.parse(content);
var jobSize = 5;
if (parsedContent.folders.length === 0 &&
parsedContent.feeds.length === 0) {
self.opmlImportEmptyError = true;
} else {
OPMLImporter.importFolders(parsedContent)
.then(function (feedQueue) {
return OPMLImporter.importFeedQueue(feedQueue,
jobSize);
}).finally(function () {
self.isOPMLImporting = false;
});
}
} catch (error) {
this.opmlImportError = true;
console.error(error);
this.isOPMLImporting = false;
}
};
this.importArticles = function (content) {
this.opmlImportError = false;
this.articleImportError = false;
try {
this.isArticlesImporting = true;
var articles = JSON.parse(content);
var self = this;
ItemResource.importArticles(articles).then(function (data) {
Publisher.publishAll(data);
}).finally(function () {
self.isArticlesImporting = false;
});
} catch (error) {
console.error(error);
this.articleImportError = true;
this.isArticlesImporting = false;
}
};
});

View File

@ -163,8 +163,7 @@ app.factory('FeedResource', function (Resource, $http, BASE_URL, $q) {
}; };
FeedResource.prototype.create = function (url, folderId, title, user, FeedResource.prototype.create = function (url, folderId, title, user, password) {
password) {
url = url.trim(); url = url.trim();
if (!url.startsWith('http')) { if (!url.startsWith('http')) {
url = 'https://' + url; url = 'https://' + url;
@ -203,8 +202,7 @@ app.factory('FeedResource', function (Resource, $http, BASE_URL, $q) {
}; };
FeedResource.prototype.reversiblyDelete = function (id, updateCache, FeedResource.prototype.reversiblyDelete = function (id, updateCache, isFolder) {
isFolder) {
var feed = this.getById(id); var feed = this.getById(id);
// if a folder is deleted it does not have to trigger the delete // if a folder is deleted it does not have to trigger the delete
@ -329,7 +327,7 @@ app.factory('FeedResource', function (Resource, $http, BASE_URL, $q) {
var feed = this.getById(feedId); var feed = this.getById(feedId);
if (feed) { if (feed) {
Object.keys(diff).forEach(function(key) { Object.keys(diff).forEach(function (key) {
feed[key] = diff[key]; feed[key] = diff[key];
}); });
var url = this.BASE_URL + '/feeds/' + feedId; var url = this.BASE_URL + '/feeds/' + feedId;

View File

@ -7,8 +7,7 @@
* @author Bernhard Posselt <dev@bernhard-posselt.com> * @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright Bernhard Posselt 2014 * @copyright Bernhard Posselt 2014
*/ */
app.factory('ItemResource', function (Resource, $http, BASE_URL, app.factory('ItemResource', function (Resource, $http, BASE_URL, ITEM_BATCH_SIZE) {
ITEM_BATCH_SIZE) {
'use strict'; 'use strict';
var ItemResource = function ($http, BASE_URL, ITEM_BATCH_SIZE) { var ItemResource = function ($http, BASE_URL, ITEM_BATCH_SIZE) {
@ -29,42 +28,41 @@ app.factory('ItemResource', function (Resource, $http, BASE_URL,
ItemResource.prototype.receive = function (value, channel) { ItemResource.prototype.receive = function (value, channel) {
switch (channel) { switch (channel) {
case 'newestItemId':
this.newestItemId = value;
break;
case 'newestItemId': case 'starred':
this.newestItemId = value; this.starredCount = value;
break; break;
case 'starred': default:
this.starredCount = value; var self = this;
break; var importValues = [];
value.forEach(function (item) {
// initialize lowest and highest id
if (self.lowestId === 0) {
self.lowestId = item.id;
}
if (self.highestId === 0) {
self.highestId = item.id;
}
default: if (item.id > self.highestId) {
var self = this; self.highestId = item.id;
var importValues = []; }
value.forEach(function (item) { if (item.id < self.lowestId) {
// initialize lowest and highest id self.lowestId = item.id;
if (self.lowestId === 0) { }
self.lowestId = item.id;
}
if (self.highestId === 0) {
self.highestId = item.id;
}
if (item.id > self.highestId) { // filter out duplicates
self.highestId = item.id; if (self.fingerprints[item.fingerprint] === undefined) {
} self.fingerprints[item.fingerprint] = true;
if (item.id < self.lowestId) { importValues.push(item);
self.lowestId = item.id; }
} });
// filter out duplicates Resource.prototype.receive.call(this, importValues, channel);
if (self.fingerprints[item.fingerprint] === undefined) {
self.fingerprints[item.fingerprint] = true;
importValues.push(item);
}
});
Resource.prototype.receive.call(this, importValues, channel);
} }
}; };
@ -135,7 +133,7 @@ app.factory('ItemResource', function (Resource, $http, BASE_URL,
ItemResource.prototype.markItemsRead = function (itemIds) { ItemResource.prototype.markItemsRead = function (itemIds) {
var self = this; var self = this;
itemIds.forEach(function(itemId) { itemIds.forEach(function (itemId) {
self.get(itemId).unread = false; self.get(itemId).unread = false;
}); });
@ -183,8 +181,7 @@ app.factory('ItemResource', function (Resource, $http, BASE_URL,
}; };
ItemResource.prototype.autoPage = function (type, id, oldestFirst, ItemResource.prototype.autoPage = function (type, id, oldestFirst, showAll, search) {
showAll, search) {
var offset; var offset;
if (oldestFirst) { if (oldestFirst) {
@ -216,7 +213,7 @@ app.factory('ItemResource', function (Resource, $http, BASE_URL,
data: { data: {
json: json json: json
} }
}).then(function(response) { }).then(function (response) {
return response.data; return response.data;
}); });
}; };

View File

@ -7,8 +7,7 @@
* @author Bernhard Posselt <dev@bernhard-posselt.com> * @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright Bernhard Posselt 2014 * @copyright Bernhard Posselt 2014
*/ */
app.service('OPMLImporter', function (FeedResource, FolderResource, Publisher, app.service('OPMLImporter', function (FeedResource, FolderResource, Publisher, $q) {
$q) {
'use strict'; 'use strict';
var startFeedJob = function (queue) { var startFeedJob = function (queue) {
var deferred = $q.defer(); var deferred = $q.defer();

View File

@ -43,7 +43,6 @@ app.service('OPMLParser', function () {
if (entry.type === 'feed') { if (entry.type === 'feed') {
root.feeds.push(entry); root.feeds.push(entry);
} else { } else {
// only first level should append folders // only first level should append folders
if (firstLevel) { if (firstLevel) {
recursivelyParse(outline.children('outline'), entry, false); recursivelyParse(outline.children('outline'), entry, false);
@ -57,8 +56,8 @@ app.service('OPMLParser', function () {
return root; return root;
}; };
this.parse = function (xml) { this.parse = function (fileContent) {
xml = $.parseXML(xml); var xml = $.parseXML(fileContent);
var firstLevel = $(xml).find('body > outline'); var firstLevel = $(xml).find('body > outline');
var root = { var root = {

View File

@ -55,7 +55,7 @@ app.factory('Resource', function () {
Resource.prototype.delete = function (id) { Resource.prototype.delete = function (id) {
// find index of object that should be deleted // find index of object that should be deleted
var self = this; var self = this;
var deleteAtIndex = this.values.findIndex(function(element) { var deleteAtIndex = this.values.findIndex(function (element) {
return element[self.id] === id; return element[self.id] === id;
}); });

View File

@ -3,7 +3,7 @@
<p><?php p($l->t('Ajax or webcron mode detected! Your feeds will not be updated!')); ?></p> <p><?php p($l->t('Ajax or webcron mode detected! Your feeds will not be updated!')); ?></p>
<ul> <ul>
<li> <li>
<a href="https://docs.nextcloud.org/server/9/admin_manual/configuration_server/background_jobs_configuration.html#cron" <a href="https://docs.nextcloud.org/server/latest/admin_manual/configuration_server/background_jobs_configuration.html#cron"
target="_blank" target="_blank"
rel="noreferrer"> rel="noreferrer">
<?php <?php
@ -29,7 +29,7 @@
<p><?php p($l->t('Non UTF-8 charset for MySQL/MariaDB database detected!')); ?></p> <p><?php p($l->t('Non UTF-8 charset for MySQL/MariaDB database detected!')); ?></p>
<ul> <ul>
<li> <li>
<a href="https://docs.nextcloud.com/server/13/admin_manual/configuration_database/mysql_4byte_support.html" <a href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_database/mysql_4byte_support.html"
target="_blank" target="_blank"
rel="noreferrer"> rel="noreferrer">
<?php <?php