diff options
-rw-r--r-- | appinfo/routes.php | 6 | ||||
-rw-r--r-- | businesslayer/feedbusinesslayer.php | 14 | ||||
-rw-r--r-- | controller/feedcontroller.php | 17 | ||||
-rw-r--r-- | css/feeds.css | 45 | ||||
-rw-r--r-- | css/owncloud6.css | 13 | ||||
-rw-r--r-- | js/app/controllers/itemcontroller.coffee | 9 | ||||
-rw-r--r-- | js/app/services/businesslayer/feedbusinesslayer.coffee | 8 | ||||
-rw-r--r-- | js/app/services/persistence.coffee | 13 | ||||
-rw-r--r-- | js/public/app.js | 38 | ||||
-rw-r--r-- | js/tests/services/businesslayer/feedbusinesslayerSpec.coffee | 11 | ||||
-rw-r--r-- | js/tests/services/persistenceSpec.coffee | 12 | ||||
-rw-r--r-- | templates/part.listfeed.php | 23 | ||||
-rw-r--r-- | tests/unit/businesslayer/FeedBusinessLayerTest.php | 22 | ||||
-rw-r--r-- | tests/unit/controller/FeedControllerTest.php | 24 |
14 files changed, 252 insertions, 3 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index bc1b7ad7d..6e21bf5f3 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -134,6 +134,12 @@ $this->create('news_feeds_move', '/feeds/{feedId}/move')->post()->action( } ); +$this->create('news_feeds_rename', '/feeds/{feedId}/rename')->post()->action( + function($params){ + App::main('FeedController', 'rename', $params, new DIContainer()); + } +); + $this->create('news_feeds_read', '/feeds/{feedId}/read')->post()->action( function($params){ App::main('FeedController', 'read', $params, new DIContainer()); diff --git a/businesslayer/feedbusinesslayer.php b/businesslayer/feedbusinesslayer.php index b7ad5987a..58a4ed578 100644 --- a/businesslayer/feedbusinesslayer.php +++ b/businesslayer/feedbusinesslayer.php @@ -226,6 +226,20 @@ class FeedBusinessLayer extends BusinessLayer { /** + * Rename a feed + * @param int $feedId the id of the feed that should be moved + * @param string $feedTitle the new title of the feed + * @param string $userId the name of the user whose feed should be renamed + * @throws BusinessLayerException if the feed does not exist + */ + public function rename($feedId, $feedTitle, $userId) { + $feed = $this->find($feedId, $userId); + $feed->setTitle($feedTitle); + $this->mapper->update($feed); + } + + + /** * Import articles * @param array $json the array with json * @param string userId the username diff --git a/controller/feedcontroller.php b/controller/feedcontroller.php index 762859627..e9561cf32 100644 --- a/controller/feedcontroller.php +++ b/controller/feedcontroller.php @@ -221,6 +221,23 @@ class FeedController extends Controller { } } + /** + * @IsAdminExemption + * @IsSubAdminExemption + * @Ajax + */ + public function rename() { + $feedId = (int) $this->params('feedId'); + $feedTitle = $this->params('feedTitle'); + $userId = $this->api->getUserId(); + + try { + $this->feedBusinessLayer->rename($feedId, $feedTitle, $userId); + return $this->renderJSON(); + } catch(BusinessLayerException $ex) { + return $this->renderJSON(array(), $ex->getMessage()); + } + } /** * @IsAdminExemption diff --git a/css/feeds.css b/css/feeds.css index b31a7c9aa..0516575fc 100644 --- a/css/feeds.css +++ b/css/feeds.css @@ -122,8 +122,8 @@ border: 0; box-shadow: none; display: none; - height: 32px; - width: 32px; + height: 30px; + width: 22px; } #app-navigation li:hover > .utils button { @@ -182,14 +182,55 @@ button.action:hover { padding-left: 0; } +#app-navigation .rename-feed > input { + width: 155px; + height: 15px; +} + .delete-icon { background-image: url('%webroot%/core/img/actions/delete.svg'); } +.rename-feed-icon { + background-image: url('%webroot%/core/img/actions/rename.svg'); +} + .mark-read-icon { background-image: url('%appswebroot%/news/img/mark_read.svg'); } +.rename-feed input { + margin: 1px 0 0px 5px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right: 0; +} + +.rename-feed button { + margin: 5px 0 5px 0; + display: inline-block; + border-bottom-left-radius: 0; + border-top-left-radius: 0; + width: 30px !important; + height: 30px !important; + padding: 0.6em; +} + +.rename-feed .action-button { + background-position: center; + background-repeat: no-repeat; +} + +.rename-feed .back-button { + border-radius: 3px; + background-image: url('%webroot%/core/img/actions/delete.svg'); +} + +.rename-feed .create-button { + border-radius: 0; + background-image: url('%appswebroot%/news/img/mark_read.svg'); +} + .rss-icon { background-image: url('%appswebroot%/news/img/rss.svg'); } diff --git a/css/owncloud6.css b/css/owncloud6.css index d59dab6a8..bde3bc7af 100644 --- a/css/owncloud6.css +++ b/css/owncloud6.css @@ -8,14 +8,25 @@ width: 299px; } +#app-navigation .rename-feed > input { + width: 215px; + height: 32px; +} + #app-navigation .progress-icon, #app-navigation .problem-icon { width: 299px; line-height: 44px; } +#app-navigation .rename-feed-icon { + padding-right: 10px; + padding-left: 5px; +} + #app-navigation .mark-read-icon { - padding-right: 40px; + padding-right: 20px; + padding-left: 5px; } #app-navigation li:hover > a { diff --git a/js/app/controllers/itemcontroller.coffee b/js/app/controllers/itemcontroller.coffee index c9a97285f..cc9898397 100644 --- a/js/app/controllers/itemcontroller.coffee +++ b/js/app/controllers/itemcontroller.coffee @@ -37,6 +37,15 @@ Language, AutoPageLoading) -> @_$scope.itemBusinessLayer = @_itemBusinessLayer @_$scope.feedBusinessLayer = @_feedBusinessLayer + @_$scope.edit = (feedId) => + feed = @_feedModel.getById(feedId) + feed.editing = true + feed.originalValue = feed.title + + @_$scope.cancel = (feedId) => + feed = @_feedModel.getById(feedId) + feed.editing = false + feed.title = feed.originalValue @_$scope.isLoading = => return @_feedLoading.isLoading() diff --git a/js/app/services/businesslayer/feedbusinesslayer.coffee b/js/app/services/businesslayer/feedbusinesslayer.coffee index fd92209ab..03ff178dd 100644 --- a/js/app/services/businesslayer/feedbusinesslayer.coffee +++ b/js/app/services/businesslayer/feedbusinesslayer.coffee @@ -66,6 +66,14 @@ FeedModel, NewLoading, _ExistsError, Utils, $rootScope, NewestItem)-> @_persistence.deleteFeed(feedId) + renameFeed: (feedId, feedTitle) -> + feed = @_feedModel.getById(feedId) + feed.editing = false + + if angular.isDefined(feed) and feedTitle != "" + @_persistence.renameFeed(feedId, feedTitle) + + markRead: (feedId) -> feed = @_feedModel.getById(feedId) newestItemId = @_newestItem.getId() diff --git a/js/app/services/persistence.coffee b/js/app/services/persistence.coffee index d51c7acb1..bfca4ccaa 100644 --- a/js/app/services/persistence.coffee +++ b/js/app/services/persistence.coffee @@ -243,6 +243,19 @@ $rootScope, $q) -> @_request.post 'news_feeds_move', params + renameFeed: (feedId, feedTitle) -> + ### + rename a feed + ### + params = + routeParams: + feedId: feedId + data: + feedTitle: feedTitle + + @_request.post 'news_feeds_rename', params + + setFeedRead: (feedId, highestItemId) -> ### sets all items of a feed as read diff --git a/js/public/app.js b/js/public/app.js index db3ccd5c7..30a8a6506 100644 --- a/js/public/app.js +++ b/js/public/app.js @@ -813,6 +813,18 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. this._autoPaging = true; this._$scope.itemBusinessLayer = this._itemBusinessLayer; this._$scope.feedBusinessLayer = this._feedBusinessLayer; + this._$scope.edit = function(feedId) { + var feed; + feed = _this._feedModel.getById(feedId); + feed.editing = true; + return feed.originalValue = feed.title; + }; + this._$scope.cancel = function(feedId) { + var feed; + feed = _this._feedModel.getById(feedId); + feed.editing = false; + return feed.title = feed.originalValue; + }; this._$scope.isLoading = function() { return _this._feedLoading.isLoading(); }; @@ -1113,6 +1125,15 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. return this._persistence.deleteFeed(feedId); }; + FeedBusinessLayer.prototype.renameFeed = function(feedId, feedTitle) { + var feed; + feed = this._feedModel.getById(feedId); + feed.editing = false; + if (angular.isDefined(feed) && feedTitle !== "") { + return this._persistence.renameFeed(feedId, feedTitle); + } + }; + FeedBusinessLayer.prototype.markRead = function(feedId) { var feed, item, newestItemId, _i, _len, _ref; feed = this._feedModel.getById(feedId); @@ -2900,6 +2921,23 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. return this._request.post('news_feeds_move', params); }; + Persistence.prototype.renameFeed = function(feedId, feedTitle) { + /* + rename a feed + */ + + var params; + params = { + routeParams: { + feedId: feedId + }, + data: { + feedTitle: feedTitle + } + }; + return this._request.post('news_feeds_rename', params); + }; + Persistence.prototype.setFeedRead = function(feedId, highestItemId) { /* sets all items of a feed as read diff --git a/js/tests/services/businesslayer/feedbusinesslayerSpec.coffee b/js/tests/services/businesslayer/feedbusinesslayerSpec.coffee index 26e5a2973..6061d8767 100644 --- a/js/tests/services/businesslayer/feedbusinesslayerSpec.coffee +++ b/js/tests/services/businesslayer/feedbusinesslayerSpec.coffee @@ -345,3 +345,14 @@ describe 'FeedBusinessLayer', -> jasmine.any(Function)) expect(callback).toHaveBeenCalled() + + it 'should make a rename feed request and disable editing', => + @persistence.renameFeed = jasmine.createSpy('Rename feed') + @FeedModel.add({id: 2, unreadCount:134, url: 'a1', folderId: 3}) + @FeedBusinessLayer.renameFeed(2, "New Title") + + expect(@persistence.renameFeed).toHaveBeenCalledWith(2, "New Title") + expect(@FeedModel.getById(2).editing).toBe(false) + + + diff --git a/js/tests/services/persistenceSpec.coffee b/js/tests/services/persistenceSpec.coffee index 38e02705a..708a68b07 100644 --- a/js/tests/services/persistenceSpec.coffee +++ b/js/tests/services/persistenceSpec.coffee @@ -178,6 +178,18 @@ describe 'Persistence', -> expect(@req.post).toHaveBeenCalledWith('news_feeds_move', params) + it 'create a correct request for renaming a feed', => + params = + data: + feedTitle: "New Feed Title" + routeParams: + feedId: 3 + + @Persistence.renameFeed(params.routeParams.feedId, params.data.feedTitle) + + expect(@req.post).toHaveBeenCalledWith('news_feeds_rename', params) + + it 'shoud send a correct request for marking all items of a feed read', => params = data: diff --git a/templates/part.listfeed.php b/templates/part.listfeed.php index ca49823f6..a01279e6b 100644 --- a/templates/part.listfeed.php +++ b/templates/part.listfeed.php @@ -16,12 +16,25 @@ scroll: true, revert: true }"> + + <div ui-if="feed.editing" class="rename-feed" ng-controller="ItemController"> + <input type="text" ng-model="feed.title" autofocus> + <button title="<?php p($l->t('Cancel')); ?>" + ng-click="cancel(feed.id)" + class="action-button back-button action"></button> + <button title="<?php p($l->t('Save')); ?>" + ng-click="feedBusinessLayer.renameFeed(feed.id, feed.title)" + class="action-button create-button action"> + </button> + </div> + <a ng-style="{ backgroundImage: feed.faviconLink }" ng-click="feedBusinessLayer.load(feed.id)" ng-class="{ 'progress-icon': !feed.id, 'problem-icon': feed.error }" + ng-hide="feed.editing" href="#" class="title" title="{{ feed.title }}" @@ -33,23 +46,33 @@ <span class="utils"> <button ng-click="feedBusinessLayer.delete(feed.id)" + ng-hide="feed.editing" class="svg action delete-icon delete-button" title="<?php p($l->t('Delete website')); ?>" ng-show="feed.id" oc-tooltip></button> <span class="unread-counter" + ng-hide="feed.editing" ng-show="feed.id && feedBusinessLayer.getUnreadCount(feed.id) > 0"> {{ unreadCountFormatter(feedBusinessLayer.getUnreadCount(feed.id)) }} </span> <button class="svg action mark-read-icon" + ng-hide="feed.editing" ng-show="feedBusinessLayer.getUnreadCount(feed.id) > 0 && feed.id" ng-click="feedBusinessLayer.markRead(feed.id)" title="<?php p($l->t('Mark read')); ?>" oc-tooltip></button> + <button class="svg action rename-feed-icon" + ng-hide="feed.editing" + ng-controller="ItemController" + ng-click="edit(feed.id)" + title="<?php p($l->t('Rename feed')); ?>" + oc-tooltip></button> + <button class="svg action delete-icon" ng-click="feedBusinessLayer.markErrorRead(feed.url)" title="<?php p($l->t('Delete website')); ?>" diff --git a/tests/unit/businesslayer/FeedBusinessLayerTest.php b/tests/unit/businesslayer/FeedBusinessLayerTest.php index 5e379525d..454a4966e 100644 --- a/tests/unit/businesslayer/FeedBusinessLayerTest.php +++ b/tests/unit/businesslayer/FeedBusinessLayerTest.php @@ -459,6 +459,28 @@ class FeedBusinessLayerTest extends \OCA\AppFramework\Utility\TestUtility { } + public function testRenameFeed(){ + $feedId = 3; + $feedTitle = "New Feed Title"; + $feed = new Feed(); + $feed->setTitle("Feed Title"); + $feed->setId($feedId); + + $this->feedMapper->expects($this->once()) + ->method('find') + ->with($this->equalTo($feedId), $this->equalTo($this->user)) + ->will($this->returnValue($feed)); + + $this->feedMapper->expects($this->once()) + ->method('update') + ->with($this->equalTo($feed)); + + $this->feedBusinessLayer->rename($feedId, $feedTitle, $this->user); + + $this->assertEquals($feedTitle, $feed->getTitle()); + } + + public function testImportArticles(){ $url = 'http://owncloud/nofeed'; diff --git a/tests/unit/controller/FeedControllerTest.php b/tests/unit/controller/FeedControllerTest.php index e3204517b..296f87b22 100644 --- a/tests/unit/controller/FeedControllerTest.php +++ b/tests/unit/controller/FeedControllerTest.php @@ -543,6 +543,30 @@ class FeedControllerTest extends ControllerTestUtility { } + public function testRename(){ + $post = array( + 'feedTitle' => "New Feed Title" + ); + $url = array( + 'feedId' => 4 + ); + $this->controller = $this->getPostController($post, $url); + + $this->api->expects($this->once()) + ->method('getUserId') + ->will($this->returnValue($this->user)); + $this->feedBusinessLayer->expects($this->once()) + ->method('rename') + ->with($this->equalTo($url['feedId']), + $this->equalTo($post['feedTitle']), + $this->equalTo($this->user)); + + $response = $this->controller->rename(); + + $this->assertTrue($response instanceof JSONResponse); + } + + public function testImportArticles() { $feed = new Feed(); |