summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Calviño Sánchez <danxuliu@gmail.com>2017-09-27 08:07:20 +0200
committerDaniel Calviño Sánchez <danxuliu@gmail.com>2017-10-19 01:46:13 +0200
commit420d1b91ab0d3c9e521bf6def682fd3c58fde997 (patch)
treee871cb10a061ebffade06c37e8b79511be802a96
parenta8f1902b02d02cc2b7d624b3d7b288f8aea84fdc (diff)
downloadnextcloud-server-420d1b91ab0d3c9e521bf6def682fd3c58fde997.tar.gz
nextcloud-server-420d1b91ab0d3c9e521bf6def682fd3c58fde997.zip
Add "Favorite" action to the file actions menu
The new FileAction for the menu is essentially the same as the old inline FileAction, except for the rendering; in this case the FileAction is shown in the menu in a standard way, so there is no need to provide a custom renderer (although the menu entry text and icon change depending on whether the file is currently a favorite or not, but that can be done just with displayName and iconClass functions). Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
-rw-r--r--apps/files/css/files.scss2
-rw-r--r--apps/files/js/tagsplugin.js75
-rw-r--r--apps/files/tests/js/tagspluginspec.js56
3 files changed, 131 insertions, 2 deletions
diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss
index 7c2d3b0bb1c..4a59502bc6d 100644
--- a/apps/files/css/files.scss
+++ b/apps/files/css/files.scss
@@ -502,7 +502,7 @@ table td.filename .uploadtext {
display: inline-block;
float: left;
}
-#fileList tr td.filename .action-favorite {
+#fileList tr td.filename .action-favorite:not(.menuitem) {
display: block;
float: left;
width: 30px;
diff --git a/apps/files/js/tagsplugin.js b/apps/files/js/tagsplugin.js
index 9bd20be4bf8..22d04e9f19f 100644
--- a/apps/files/js/tagsplugin.js
+++ b/apps/files/js/tagsplugin.js
@@ -86,7 +86,7 @@
var self = this;
// register "star" action
fileActions.registerAction({
- name: 'Favorite',
+ name: 'FavoriteInline',
displayName: t('files', 'Favorite'),
mime: 'all',
permissions: OC.PERMISSION_READ,
@@ -141,6 +141,79 @@
});
}
});
+
+ fileActions.registerAction({
+ name: 'Favorite',
+ displayName: function(context) {
+ var $file = context.$file;
+ var isFavorite = $file.data('favorite') === true;
+
+ if (isFavorite) {
+ return t('files', 'Remove from favorites');
+ }
+
+ // As it is currently not possible to provide a context for
+ // the i18n strings "Add to favorites" was used instead of
+ // "Favorite" to remove the ambiguity between verb and noun
+ // when it is translated.
+ return t('files', 'Add to favorites');
+ },
+ mime: 'all',
+ order: -23,
+ permissions: OC.PERMISSION_READ,
+ iconClass: function(fileName, context) {
+ var $file = context.$file;
+ var isFavorite = $file.data('favorite') === true;
+
+ if (isFavorite) {
+ return 'icon-starred';
+ }
+
+ return 'icon-star';
+ },
+ actionHandler: function(fileName, context) {
+ var $actionEl = context.$file.find('.action-favorite');
+ var $file = context.$file;
+ var fileInfo = context.fileList.files[$file.index()];
+ var dir = context.dir || context.fileList.getCurrentDirectory();
+ var tags = $file.attr('data-tags');
+ if (_.isUndefined(tags)) {
+ tags = '';
+ }
+ tags = tags.split('|');
+ tags = _.without(tags, '');
+ var isFavorite = tags.indexOf(OC.TAG_FAVORITE) >= 0;
+ if (isFavorite) {
+ // remove tag from list
+ tags = _.without(tags, OC.TAG_FAVORITE);
+ } else {
+ tags.push(OC.TAG_FAVORITE);
+ }
+
+ // pre-toggle the star
+ toggleStar($actionEl, !isFavorite);
+
+ context.fileInfoModel.trigger('busy', context.fileInfoModel, true);
+
+ self.applyFileTags(
+ dir + '/' + fileName,
+ tags,
+ $actionEl,
+ isFavorite
+ ).then(function(result) {
+ context.fileInfoModel.trigger('busy', context.fileInfoModel, false);
+ // response from server should contain updated tags
+ var newTags = result.tags;
+ if (_.isUndefined(newTags)) {
+ newTags = tags;
+ }
+ context.fileInfoModel.set({
+ 'tags': newTags,
+ 'favorite': !isFavorite
+ });
+ });
+ }
+ });
},
_extendFileList: function(fileList) {
diff --git a/apps/files/tests/js/tagspluginspec.js b/apps/files/tests/js/tagspluginspec.js
index a4efc08aa53..e2cbaa2c4d0 100644
--- a/apps/files/tests/js/tagspluginspec.js
+++ b/apps/files/tests/js/tagspluginspec.js
@@ -123,6 +123,62 @@ describe('OCA.Files.TagsPlugin tests', function() {
expect($action.find('.icon').hasClass('icon-star')).toEqual(true);
expect($action.find('.icon').hasClass('icon-starred')).toEqual(false);
});
+ it('through FileActionsMenu sends request to server and updates icon', function() {
+ var request;
+ fileList.setFiles(testFiles);
+ var $tr = fileList.findFileEl('One.txt');
+ var $action = $tr.find('.action-favorite');
+ var $showMenuAction = $tr.find('.action-menu');
+ $showMenuAction.click();
+ var $favoriteActionInMenu = $tr.find('.fileActionsMenu .action-favorite');
+ $favoriteActionInMenu.click();
+
+ expect(fakeServer.requests.length).toEqual(1);
+ request = fakeServer.requests[0];
+ expect(JSON.parse(request.requestBody)).toEqual({
+ tags: ['tag1', 'tag2', OC.TAG_FAVORITE]
+ });
+ request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
+ tags: ['tag1', 'tag2', 'tag3', OC.TAG_FAVORITE]
+ }));
+
+ // re-read the element as it was re-inserted
+ $tr = fileList.findFileEl('One.txt');
+ $action = $tr.find('.action-favorite');
+ $showMenuAction = $tr.find('.action-menu');
+
+ expect($tr.attr('data-favorite')).toEqual('true');
+ expect($tr.attr('data-tags').split('|')).toEqual(['tag1', 'tag2', 'tag3', OC.TAG_FAVORITE]);
+ expect(fileList.files[0].tags).toEqual(['tag1', 'tag2', 'tag3', OC.TAG_FAVORITE]);
+ expect($action.find('.icon').hasClass('icon-star')).toEqual(false);
+ expect($action.find('.icon').hasClass('icon-starred')).toEqual(true);
+
+ // show again the menu and get the new action, as the menu was
+ // closed and removed (and with it, the previous action) when that
+ // action was clicked
+ $showMenuAction.click();
+ $favoriteActionInMenu = $tr.find('.fileActionsMenu .action-favorite');
+ $favoriteActionInMenu.click();
+
+ expect(fakeServer.requests.length).toEqual(2);
+ request = fakeServer.requests[1];
+ expect(JSON.parse(request.requestBody)).toEqual({
+ tags: ['tag1', 'tag2', 'tag3']
+ });
+ request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
+ tags: ['tag1', 'tag2', 'tag3']
+ }));
+
+ // re-read the element as it was re-inserted
+ $tr = fileList.findFileEl('One.txt');
+ $action = $tr.find('.action-favorite');
+
+ expect($tr.attr('data-favorite')).toBeFalsy();
+ expect($tr.attr('data-tags').split('|')).toEqual(['tag1', 'tag2', 'tag3']);
+ expect(fileList.files[0].tags).toEqual(['tag1', 'tag2', 'tag3']);
+ expect($action.find('.icon').hasClass('icon-star')).toEqual(true);
+ expect($action.find('.icon').hasClass('icon-starred')).toEqual(false);
+ });
});
describe('elementToFile', function() {
it('returns tags', function() {