diff options
author | Bernhard Posselt <dev@bernhard-posselt.com> | 2014-09-16 16:24:20 +0200 |
---|---|---|
committer | Bernhard Posselt <dev@bernhard-posselt.com> | 2014-09-16 16:24:20 +0200 |
commit | 9e36ef31f9bf16d43326fd047619ada5ff16e072 (patch) | |
tree | e228816adedacfed87eb08e8bc86658536cbbe86 /js/build/app.js | |
parent | 6a7ac3d9da3dea4130eb08a07a0a0603418d54ab (diff) | |
parent | 21728afff571adfc508cf5fa473d094946ef188f (diff) |
merge
Diffstat (limited to 'js/build/app.js')
-rw-r--r-- | js/build/app.js | 2252 |
1 files changed, 2252 insertions, 0 deletions
diff --git a/js/build/app.js b/js/build/app.js new file mode 100644 index 000000000..442f2095e --- /dev/null +++ b/js/build/app.js @@ -0,0 +1,2252 @@ +(function(window, document, angular, $, OC, csrfToken, undefined){ + +'use strict'; + + +var app = angular.module('News', ['ngRoute', 'ngSanitize']); +app.config(["$routeProvider", "$provide", "$httpProvider", function ($routeProvider, $provide, $httpProvider) { + 'use strict'; + + var feedType = { + FEED: 0, + FOLDER: 1, + STARRED: 2, + SUBSCRIPTIONS: 3, + SHARED: 4 + }; + + // constants + $provide.constant('REFRESH_RATE', 60); // seconds + $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', ["$q", "BASE_URL", function ($q, BASE_URL) { + return { + request: function (config) { + if (config.url.indexOf(BASE_URL) === 0) { + config.headers.requesttoken = csrfToken; + } + + return config || $q.when(config); + } + }; + }]); + $httpProvider.interceptors.push('CSRFInterceptor'); + + // routing + var 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 = { + type: type, + limit: ITEM_BATCH_SIZE + }; + + if ($route.current.params.id !== undefined) { + parameters.id = $route.current.params.id; + } + + var 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: 'ContentController as Content', + templateUrl: 'content.html', + resolve: getResolve(feedType.SUBSCRIPTIONS), + type: feedType.SUBSCRIPTIONS + }) + .when('/items/starred', { + controller: 'ContentController as Content', + templateUrl: 'content.html', + resolve: getResolve(feedType.STARRED), + type: feedType.STARRED + }) + .when('/items/feeds/:id', { + controller: 'ContentController as Content', + templateUrl: 'content.html', + resolve: getResolve(feedType.FEED), + type: feedType.FEED + }) + .when('/items/folders/:id', { + controller: 'ContentController as Content', + templateUrl: 'content.html', + resolve: getResolve(feedType.FOLDER), + type: feedType.FOLDER + }); + +}]); + + +app.run(["$rootScope", "$location", "$http", "$q", "$interval", "Loading", "ItemResource", "FeedResource", "FolderResource", "SettingsResource", "Publisher", "BASE_URL", "FEED_TYPE", "REFRESH_RATE", function ($rootScope, $location, $http, $q, $interval, Loading, + ItemResource, FeedResource, FolderResource, SettingsResource, + 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(ItemResource).toChannels(['items', 'newestItemId', + 'starred']); + Publisher.subscribe(FolderResource).toChannels(['folders']); + Publisher.subscribe(FeedResource).toChannels(['feeds']); + Publisher.subscribe(SettingsResource).toChannels(['settings']); + + // load feeds, settings and last read feed + var settingsDeferred = $q.defer(); + $http.get(BASE_URL + '/settings').success(function (data) { + Publisher.publishAll(data); + settingsDeferred.resolve(); + }); + + var activeFeedDeferred = $q.defer(); + var path = $location.path(); + $http.get(BASE_URL + '/feeds/active').success(function (data) { + var url; + + switch (data.activeFeed.type) { + + case FEED_TYPE.FEED: + url = '/items/feeds/' + data.activeFeed.id; + break; + + case FEED_TYPE.FOLDER: + url = '/items/folders/' + data.activeFeed.id; + break; + + case FEED_TYPE.STARRED: + url = '/items/starred'; + break; + + default: + url = '/items'; + } + + // only redirect if url is empty or faulty + if (!/^\/items(\/(starred|feeds\/\d+|folders\/\d+))?\/?$/.test(path)) { + $location.path(url); + } + + activeFeedDeferred.resolve(); + }); + + var folderDeferred = $q.defer(); + $http.get(BASE_URL + '/folders').success(function (data) { + Publisher.publishAll(data); + folderDeferred.resolve(); + }); + + var 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, + feedDeferred.promise, + folderDeferred.promise + ] + ) + .then(function () { + Loading.setLoading('global', false); + }); + + // refresh feeds and folders + $interval(function () { + $http.get(BASE_URL + '/feeds'); + $http.get(BASE_URL + '/folders'); + }, REFRESH_RATE * 1000); + + + $rootScope.$on('$routeChangeStart', function () { + Loading.setLoading('content', true); + }); + + $rootScope.$on('$routeChangeSuccess', function () { + Loading.setLoading('content', false); + }); + + // in case of wrong id etc show all items + $rootScope.$on('$routeChangeError', function () { + $location.path('/items'); + }); + +}]); +app.controller('AppController', +["Loading", "FeedResource", "FolderResource", function (Loading, FeedResource, FolderResource) { + 'use strict'; + + this.loading = Loading; + + this.isFirstRun = function () { + return FeedResource.size() === 0 && FolderResource.size() === 0; + }; + +}]); +app.controller('ContentController', +["Publisher", "FeedResource", "ItemResource", "SettingsResource", "data", "$route", "$routeParams", "FEED_TYPE", function (Publisher, FeedResource, ItemResource, SettingsResource, data, + $route, $routeParams, FEED_TYPE) { + 'use strict'; + + // dont cache items across multiple route changes + ItemResource.clear(); + + // distribute data to models based on key + Publisher.publishAll(data); + + + this.isAutoPagingEnabled = true; + + this.getItems = function () { + return ItemResource.getAll(); + }; + + this.toggleStar = function (itemId) { + ItemResource.toggleStar(itemId); + }; + + this.toggleItem = function (item) { + // TODO: unittest + if (this.isCompactView()) { + item.show = !item.show; + } + }; + + 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); + } + + item.keepUnread = !item.keepUnread; + }; + + this.orderBy = function () { + if (SettingsResource.get('oldestFirst')) { + return 'id'; + } else { + return '-id'; + } + }; + + this.isCompactView = function () { + return SettingsResource.get('compact'); + }; + + 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 () { + // 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 = SettingsResource.get('oldestFirst'); + var self = this; + + ItemResource.autoPage(type, id, oldestFirst).success(function (data) { + Publisher.publishAll(data); + + if (data.items.length > 0) { + self.isAutoPagingEnabled = true; + } + + if (self.isAutoPagingEnabled && self.autoPageAgain) { + self.autoPage(); + } + }).error(function () { + self.isAutoPagingEnabled = true; + }); + }; + + this.getRelativeDate = function (timestamp) { + if (timestamp !== undefined && timestamp !== '') { + var languageCode = SettingsResource.get('language'); + var date = + moment.unix(timestamp).locale(languageCode).fromNow() + ''; + return date; + } else { + return ''; + } + }; + +}]); +app.controller('NavigationController', +["$route", "FEED_TYPE", "FeedResource", "FolderResource", "ItemResource", "SettingsResource", "Publisher", "$rootScope", "$location", "$q", function ($route, FEED_TYPE, FeedResource, FolderResource, ItemResource, + SettingsResource, Publisher, $rootScope, $location, $q) { + 'use strict'; + + this.feedError = ''; + this.folderError = ''; + + this.getFeeds = function () { + return FeedResource.getAll(); + }; + + this.getFolders = function () { + return FolderResource.getAll(); + }; + + this.markFolderRead = function (folderId) { + FeedResource.markFolderRead(folderId); + + FeedResource.getByFolderId(folderId).forEach(function (feed) { + ItemResource.markFeedRead(feed.id); + }); + }; + + this.markFeedRead = function (feedId) { + ItemResource.markFeedRead(feedId); + FeedResource.markFeedRead(feedId); + }; + + this.markRead = function () { + ItemResource.markRead(); + FeedResource.markRead(); + }; + + this.isShowAll = function () { + return SettingsResource.get('showAll'); + }; + + this.getFeedsOfFolder = function (folderId) { + return FeedResource.getByFolderId(folderId); + }; + + this.getUnreadCount = function () { + return FeedResource.getUnreadCount(); + }; + + this.getFeedUnreadCount = function (feedId) { + var feed = FeedResource.getById(feedId); + if (feed !== undefined) { + return feed.unreadCount; + } else { + return 0; + } + }; + + this.getFolderUnreadCount= function (folderId) { + return FeedResource.getFolderUnreadCount(folderId); + }; + + this.getStarredCount = function () { + return ItemResource.getStarredCount(); + }; + + this.toggleFolder = function (folderName) { + FolderResource.toggleOpen(folderName); + }; + + this.hasFeeds = function (folderId) { + return FeedResource.getFolderUnreadCount(folderId) !== undefined; + }; + + this.subFeedActive = function (folderId) { + var type = $route.current.$$route.type; + + if (type === FEED_TYPE.FEED) { + var feed = FeedResource.getById($route.current.params.id); + + if (feed !== undefined && feed.folderId === folderId) { + return true; + } + } + + return false; + }; + + this.isSubscriptionsActive = function () { + return $route.current && + $route.current.$$route.type === FEED_TYPE.SUBSCRIPTIONS; + }; + + this.isStarredActive = function () { + return $route.current && + $route.current.$$route.type === FEED_TYPE.STARRED; + }; + + this.isFolderActive = function (folderId) { + var currentId = parseInt($route.current.params.id, 10); + return $route.current && + $route.current.$$route.type === FEED_TYPE.FOLDER && + currentId === folderId; + }; + + this.isFeedActive = function (feedId) { + var currentId = parseInt($route.current.params.id, 10); + return $route.current && + $route.current.$$route.type === FEED_TYPE.FEED && + currentId === feedId; + }; + + this.folderNameExists = function (folderName) { + folderName = folderName || ''; + return FolderResource.get(folderName.trim()) !== undefined; + }; + + this.feedUrlExists = function (url) { + url = url || ''; + url = url.trim(); + return FeedResource.get(url) !== undefined || + FeedResource.get('http://' + url) !== undefined; + }; + + this.createFeed = function (feed) { + var self = this; + this.newFolder = false; + this.addingFeed = true; + + var newFolder = feed.newFolder; + var existingFolder = feed.existingFolder || {id: 0}; + + // we dont need to create a new folder + if (newFolder === undefined) { + // this is set to display the feed in any folder, even if the folder + // is closed or has no unread articles + existingFolder.getsFeed = true; + + FeedResource.create(feed.url, existingFolder.id, undefined) + .then(function (data) { + + Publisher.publishAll(data); + + // set folder as default + $location.path('/items/feeds/' + data.feeds[0].id + '/'); + + }).finally(function () { + existingFolder.getsFeed = undefined; + feed.url = ''; + self.addingFeed = false; + }); + + } else { + // create folder first and then the feed + FolderResource.create(newFolder).then(function (data) { + + Publisher.publishAll(data); + + // set the created folder on scope so its preselected for the + // next addition + feed.existingFolder = FolderResource.get(data.folders[0].name); + feed.newFolder = undefined; + self.createFeed(feed); + }); + } + }; + + this.createFolder = function (folder) { + var self = this; + this.addingFolder = true; + FolderResource.create(folder.name).then(function (data) { + Publisher.publishAll(data); + }).finally(function () { + self.addingFolder = false; + folder.name = ''; + }); + }; + + this.moveFeed = function (feedId, folderId) { + var reload = false; + var feed = FeedResource.getById(feedId); + + if (feed.folderId === folderId) { + return; + } + + if (this.isFolderActive(feed.folderId) || + this.isFolderActive(folderId)) { + reload = true; + } + + FeedResource.move(feedId, folderId); + + if (reload) { + $route.reload(); + } + }; + + this.renameFeed = function (feed) { + FeedResource.rename(feed.id, feed.title); + feed.editing = false; + }; + + this.renameFolder = function (folder, name) { + folder.renameError = ''; + this.renamingFolder = true; + var self = this; + + if (folder.name === name) { + folder.renameError = ''; + folder.editing = false; + this.renamingFolder = false; + } else { + FolderResource.rename(folder.name, name).then(function () { + folder.renameError = ''; + folder.editing = false; + }, function (message) { + folder.renameError = message; + }).finally(function () { + self.renamingFolder = false; + }); + } + }; + + this.reversiblyDeleteFeed = function (feed) { + FeedResource.reversiblyDelete(feed.id).finally(function () { + $route.reload(); + }); + }; + + this.undoDeleteFeed = function (feed) { + FeedResource.undoDelete(feed.id).finally(function () { + $route.reload(); + }); + }; + + this.deleteFeed = function (feed) { + FeedResource.delete(feed.url); + }; + + + this.reversiblyDeleteFolder = function (folder) { + $q.all( + FeedResource.reversiblyDeleteFolder(folder.id), + FolderResource.reversiblyDelete(folder.name) + ).finally(function () { + $route.reload(); + }); + }; + + this.undoDeleteFolder = function (folder) { + $q.all( + FeedResource.undoDeleteFolder(folder.id), + FolderResource.undoDelete(folder.name) + ).finally(function () { + $route.reload(); + }); + }; + + this.deleteFolder = function (folder) { + FeedResource.deleteFolder(folder.id); + FolderResource.delete(folder.name); + }; + + var self = this; + $rootScope.$on('moveFeedToFolder', function (scope, data) { + self.moveFeed(data.feedId, data.folderId); + }); + +}]); +app.controller('SettingsController', +["$route", "$q", "SettingsResource", "ItemResource", "OPMLParser", "OPMLImporter", "Publisher", function ($route, $q, SettingsResource, ItemResource, OPMLParser, + OPMLImporter, Publisher) { + 'use strict'; + + this.isOPMLImporting = false; + this.isArticlesImporting = false; + this.opmlImportError = false; + this.articleImportError = false; + + 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 (content) { + this.opmlImportError = false; + this.articleImportError = false; + + try { + this.isOPMLImporting = false; + var parsedContent = OPMLParser.parse(content); + + var self = this; + var jobSize = 5; + + OPMLImporter.importFolders(parsedContent) + .then(function (feedQueue) { + return OPMLImporter.importFeedQueue(feedQueue, jobSize); + }).finally(function () { + self.isOPMLImporting = false; + }); + + } catch (error) { + this.isOPMLImporting = false; + this.opmlImportError = true; + } + }; + + 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).success(function (data) { + Publisher.publishAll(data); + }).finally(function () { + self.isArticlesImporting = false; + }); + + } catch (error) { + this.articleImportError = true; + this.isArticlesImporting = false; + } + }; + +}]); +app.filter('trustUrl', ["$sce", function ($sce) { + 'use strict'; + + return function (url) { + return $sce.trustAsResourceUrl(url); + }; +}]); +app.filter('unreadCountFormatter', function () { + 'use strict'; + + return function (unreadCount) { + if (unreadCount > 999) { + return '999+'; + } + return unreadCount; + }; +}); +app.factory('FeedResource', ["Resource", "$http", "BASE_URL", "$q", function (Resource, $http, BASE_URL, $q) { + 'use strict'; + + var FeedResource = function ($http, BASE_URL, $q) { + Resource.call(this, $http, BASE_URL, 'url'); + this.ids = {}; + this.unreadCount = 0; + this.folderUnreadCount = {}; + this.folderIds = {}; + this.$q = $q; + }; + + FeedResource.prototype = Object.create(Resource.prototype); + + FeedResource.prototype.receive = function (data) { + Resource.prototype.receive.call(this, data); + this.updateUnreadCache(); + this.updateFolderCache(); + }; + + + FeedResource.prototype.updateUnreadCache = function () { + this.unreadCount = 0; + this.folderUnreadCount = {}; + + var self = this; + this.values.forEach(function (feed) { + if (feed.unreadCount) { + self.unreadCount += feed.unreadCount; + } + if (feed.folderId !== undefined) { + self.folderUnreadCount[feed.folderId] = + self.folderUnreadCount[feed.folderId] || 0; + self.folderUnreadCount[feed.folderId] += feed.unreadCount; + } + }); + }; + + + FeedResource.prototype.updateFolderCache = function () { + this.folderIds = {}; + + var self = this; + this.values.forEach(function (feed) { + self.folderIds[feed.folderId] = + self.folderIds[feed.folderId] || []; + self.folderIds[feed.folderId].push(feed); + }); + }; + + + FeedResource.prototype.add = function (value) { + Resource.prototype.add.call(this, value); + if (value.id !== undefined) { + this.ids[value.id] = this.hashMap[value.url]; + } + }; + + + FeedResource.prototype.markRead = function () { + this.values.forEach(function (feed) { + feed.unreadCount = 0; + }); + + this.unreadCount = 0; + this.folderUnreadCount = {}; + }; + + + FeedResource.prototype.markFeedRead = function (feedId) { + this.ids[feedId].unreadCount = 0; + this.updateUnreadCache(); + }; + + + FeedResource.prototype.markFolderRead = function (folderId) { + this.values.forEach(function (feed) { + if (feed.folderId === folderId) { + feed.unreadCount = 0; + } + }); + + this.updateUnreadCache(); + }; + + + FeedResource.prototype.markItemOfFeedRead = function (feedId) { + this.ids[feedId].unreadCount -= 1; + this.updateUnreadCache(); + }; + + + FeedResource.prototype.markItemsOfFeedsRead = function (feedIds) { + var self = this; + feedIds.forEach(function (feedId) { + self.ids[feedId].unreadCount -= 1; + }); + + this.updateUnreadCache(); + }; + + + FeedResource.prototype.markItemOfFeedUnread = function (feedId) { + this.ids[feedId].unreadCount += 1; + this.updateUnreadCache(); + }; + + + FeedResource.prototype.getUnreadCount = function () { + return this.unreadCount; + }; + + + FeedResource.prototype.getFolderUnreadCount = function (folderId) { + return this.folderUnreadCount[folderId]; + }; + + + FeedResource.prototype.getByFolderId = function (folderId) { + return this.folderIds[folderId] || []; + }; + + + FeedResource.prototype.getById = function (feedId) { + return this.ids[feedId]; + }; + + + FeedResource.prototype.rename = function (id, title) { + return this.http({ + method: 'POST', + url: this.BASE_URL + '/feeds/' + id + '/rename', + data: { + feedTitle: title + } + }); + }; + + + FeedResource.prototype.move = function (feedId, folderId) { + var feed = this.getById(feedId); + feed.folderId = folderId; + + this.updateFolderCache(); + this.updateUnreadCache(); + + return this.http({ + method: 'POST', + url: this.BASE_URL + '/feeds/' + feed.id + '/move', + data: { + parentFolderId: folderId + } + }); + + }; + + + FeedResource.prototype.create = function (url, folderId, title) { + url = url.trim(); + if (!url.startsWith('http')) { + url = 'http://' + url; + } + + if (title !== undefined) { + title = title.trim(); + } + + var feed = { + url: url, + folderId: folderId || 0, + title: title || url, + unreadCount: 0 + }; + + this.add(feed); + this.updateFolderCache(); + + var deferred = this.$q.defer(); + + this.http({ + method: 'POST', + url: this.BASE_URL + '/feeds', + data: { + url: url, + parentFolderId: folderId || 0, + title: title + } + }).success(function (data) { + deferred.resolve(data); + }).error(function (data) { + feed.faviconLink = ''; + feed.error = data.message; + deferred.reject(); + }); + + return deferred.promise; + }; + + + FeedResource.prototype.reversiblyDelete = function (id, updateCache) { + var feed = this.getById(id); + + if (feed) { + feed.deleted = true; + } + + if (updateCache !== false) { + this.updateUnreadCache(); + } + + return this.http.delete(this.BASE_URL + '/feeds/' + id); + }; + + + FeedResource.prototype.reversiblyDeleteFolder = function (folderId) { + var self = this; + var promises = []; + this.getByFolderId(folderId).forEach(function (feed) { + promises.push(self.reversiblyDelete(feed.id, false)); + }); + + this.updateUnreadCache(); + + var deferred = this.$q.all(promises); + return deferred.promise; + }; + + + FeedResource.prototype.delete = function (url, updateCache) { + var feed = this.get(url); + if (feed.id) { + delete this.ids[feed.id]; + } + + Resource.prototype.delete.call(this, url); + + if (updateCache !== false) { + this.updateUnreadCache(); + this.updateFolderCache(); + } + + return feed; + }; + + + FeedResource.prototype.deleteFolder = function (folderId) { + var self = this; + this.getByFolderId(folderId).forEach(function (feed) { + self.delete(feed.url, false); + }); + + this.updateUnreadCache(); + this.updateFolderCache(); + }; + + + FeedResource.prototype.undoDelete = function (id, updateCache) { + var feed = this.getById(id); + + if (feed) { + feed.deleted = false; + } + + if (updateCache !== false) { + this.updateUnreadCache(); + } + + return this.http.post(this.BASE_URL + '/feeds/' + id + '/restore'); + }; + + + FeedResource.prototype.undoDeleteFolder = function (folderId) { + var self = this; + var promises = []; + + this.getByFolderId(folderId).forEach(function (feed) { + promises.push(self.undoDelete(feed.id, false)); + }); + + this.updateUnreadCache(); + + var deferred = this.$q.all(promises); + return deferred.promise; + }; + + + return new FeedResource($http, BASE_URL, $q); +}]); +app.factory('FolderResource', ["Resource", "$http", "BASE_URL", "$q", function (Resource, $http, BASE_URL, $q) { + 'use strict'; + + var FolderResource = function ($http, BASE_URL, $q) { + Resource.call(this, $http, BASE_URL, 'name'); + this.deleted = null; + this.$q = $q; + }; + + FolderResource.prototype = Object.create(Resource.prototype); + + + FolderResource.prototype.toggleOpen = function (folderName) { + var folder = this.get(folderName); + folder.opened = !folder.opened; + + return this.http({ + url: this.BASE_URL + '/folders/' + folder.id + '/open', + method: 'POST', + data: { + folderId: folder.id, + open: folder.opened + } + }); + }; + + + FolderResource.prototype.rename = function (folderName, toFolderName) { + var folder = this.get(folderName); + var deferred = this.$q.defer(); + var self = this; + + this.http({ + url: this.BASE_URL + '/folders/' + folder.id + '/rename', + method: 'POST', + data: { + folderName: toFolderName + } + }).success(function () { + folder.name = toFolderName; + delete self.hashMap[folderName]; + self.hashMap[toFolderName] = folder; + + deferred.resolve(); + }).error(function (data) { + deferred.reject(data.message); + }); + + return deferred.promise; + }; + + + FolderResource.prototype.create = function (folderName) { + folderName = folderName.trim(); + var folder = { + name: folderName + }; + + this.add(folder); + + var deferred = this.$q.defer(); + + this.http({ + url: this.BASE_URL + '/folders', + method: 'POST', + data: { + folderName: folderName + } + }).success(function (data) { + deferred.resolve(data); + }).error(function (data) { + folder.error = data.message; + }); |