From 60bcdc550e95fbf0104bbc9c8028777016d73663 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 19 May 2014 15:20:44 +0200 Subject: [PATCH] Fixed file actions for sharing views FileActions can now be clone to be use for separate file list views without having the side-effect of affecting the main file list view. Added "Open" action in sharing overview file lists to redirect to the regular file list when clicking on a folder. --- apps/files/js/app.js | 12 ++++++-- apps/files/js/fileactions.js | 34 ++++++++++++++-------- apps/files/js/filelist.js | 11 ++++--- apps/files_sharing/js/app.js | 19 +++++++++---- apps/files_sharing/js/share.js | 38 ++++++++++++++----------- apps/files_sharing/js/sharedfilelist.js | 17 +++++++++++ apps/files_trashbin/js/app.js | 6 ++-- core/js/share.js | 24 ++++++++++++---- 8 files changed, 112 insertions(+), 49 deletions(-) diff --git a/apps/files/js/app.js b/apps/files/js/app.js index 9155fb38cdb..6d8a9788d97 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -25,7 +25,7 @@ this.navigation = new OCA.Files.Navigation($('#app-navigation')); // TODO: ideally these should be in a separate class / app (the embedded "all files" app) - this.fileActions = OCA.Files.FileActions; + this.fileActions = OCA.Files.FileActions.clone(); this.files = OCA.Files.Files; this.fileList = new OCA.Files.FileList( @@ -36,7 +36,7 @@ } ); this.files.initialize(); - this.fileActions.registerDefaultActions(this.fileList); + this.fileActions.registerDefaultActions(); this.fileList.setFileActions(this.fileActions); // for backward compatibility, the global FileList will @@ -57,6 +57,14 @@ return this.navigation.getActiveContainer(); }, + /** + * Sets the currently active view + * @param viewId view id + */ + setActiveView: function(viewId, options) { + this.navigation.setActiveItem(viewId, options); + }, + /** * Setup events based on URL changes */ diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 9e4aeb2f338..1242fea7f99 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -31,6 +31,18 @@ this.actions[mime][name]['displayName'] = displayName; this.icons[name] = icon; }, + /** + * Clones the current file actions handler including the already + * registered actions. + */ + clone: function() { + var fileActions = _.extend({}, this); + // need to deep copy the actions as well + fileActions.actions = _.extend({}, this.actions); + fileActions.defaults = _.extend({}, this.defaults); + //fileActions.icons = _.extend({}, this.icons); + return fileActions; + }, clear: function() { this.actions = {}; this.defaults = {}; @@ -217,29 +229,29 @@ /** * Register the actions that are used by default for the files app. */ - registerDefaultActions: function(fileList) { + registerDefaultActions: function() { // TODO: try to find a way to not make it depend on fileList, // maybe get a handler or listener to trigger events on this.register('all', 'Delete', OC.PERMISSION_DELETE, function () { return OC.imagePath('core', 'actions/delete'); - }, function (filename) { - fileList.do_delete(filename); + }, function (filename, context) { + context.fileList.do_delete(filename); $('.tipsy').remove(); }); // t('files', 'Rename') this.register('all', 'Rename', OC.PERMISSION_UPDATE, function () { return OC.imagePath('core', 'actions/rename'); - }, function (filename) { - fileList.rename(filename); + }, function (filename, context) { + context.fileList.rename(filename); }); - this.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename) { - var dir = fileList.getCurrentDirectory(); + this.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) { + var dir = context.fileList.getCurrentDirectory(); if (dir !== '/') { dir = dir + '/'; } - fileList.changeDirectory(dir + filename); + context.fileList.changeDirectory(dir + filename); }); this.setDefault('dir', 'Open'); @@ -252,14 +264,12 @@ this.register(downloadScope, 'Download', OC.PERMISSION_READ, function () { return OC.imagePath('core', 'actions/download'); - }, function (filename) { - var url = fileList.getDownloadUrl(filename, fileList.getCurrentDirectory()); + }, function (filename, context) { + var url = context.fileList.getDownloadUrl(filename, context.fileList.getCurrentDirectory()); if (url) { OC.redirect(url); } }); - - fileList.$fileList.trigger(jQuery.Event("fileActionsReady")); } }; diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 08f640f6bff..d969cb57c56 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -452,7 +452,7 @@ while (count > 0 && index < this.files.length) { fileData = this.files[index]; - tr = this._renderRow(fileData, {updateSummary: false}); + tr = this._renderRow(fileData, {updateSummary: false, silent: true}); this.$fileList.append(tr); if (isAllSelected || this._selectedFiles[fileData.id]) { tr.addClass('selected'); @@ -626,7 +626,8 @@ * * @param fileData map of file attributes * @param options map of attributes: - * - "updateSummary" true to update the summary after adding (default), false otherwise + * - "updateSummary": true to update the summary after adding (default), false otherwise + * - "silent": true to prevent firing events like "fileActionsReady" * @return new tr element (not appended to the table) */ add: function(fileData, options) { @@ -729,7 +730,7 @@ } // display actions - this.fileActions.display(filenameTd, false, this); + this.fileActions.display(filenameTd, !options.silent, this); if (fileData.isPreviewAvailable) { // lazy load / newly inserted td ? @@ -790,7 +791,9 @@ }, /** - * Sets the file actions handler + * Sets the file actions handler. + * + * @param fileActions FileActions handler */ setFileActions: function(fileActions) { this.fileActions = fileActions; diff --git a/apps/files_sharing/js/app.js b/apps/files_sharing/js/app.js index 887575193d0..9808e069784 100644 --- a/apps/files_sharing/js/app.js +++ b/apps/files_sharing/js/app.js @@ -27,9 +27,7 @@ OCA.Sharing.App = { } ); - var fileActions = _.extend({}, OCA.Files.FileActions); - fileActions.registerDefaultActions(this._inFileList); - this._inFileList.setFileActions(fileActions); + this._initFileActions(this._inFileList); }, initSharingOut: function($el) { @@ -44,9 +42,18 @@ OCA.Sharing.App = { } ); - var fileActions = _.extend({}, OCA.Files.FileActions); - fileActions.registerDefaultActions(this._outFileList); - this._outFileList.setFileActions(fileActions); + this._initFileActions(this._outFileList); + }, + + _initFileActions: function(fileList) { + var fileActions = OCA.Files.FileActions.clone(); + // when the user clicks on a folder, redirect to the corresponding + // folder in the files app + fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) { + OCA.Files.App.setActiveView('files', {silent: true}); + OCA.Files.App.fileList.changeDirectory(context.$file.attr('data-path') + '/' + filename, true, true); + }); + fileList.setFileActions(fileActions); } }; diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 84c5bf57b38..28586a179a4 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -8,7 +8,6 @@ * */ -/* global FileList, FileActions */ $(document).ready(function() { var sharesLoaded = false; @@ -31,7 +30,8 @@ $(document).ready(function() { }; } - $('#fileList').on('fileActionsReady',function(){ + // use delegate to catch the case with multiple file lists + $('#content').delegate('#fileList', 'fileActionsReady',function(){ // if no share action exists because the admin disabled sharing for this user // we create a share notification action to inform the user about files // shared with him otherwise we just update the existing share action. @@ -64,44 +64,48 @@ $(document).ready(function() { } }) - // FIXME: these calls are also working on hard-coded - // list selectors... if (!sharesLoaded){ - OC.Share.loadIcons('file'); + OC.Share.loadIcons('file', $fileList); // assume that we got all shares, so switching directories // will not invalidate that list sharesLoaded = true; } else{ - OC.Share.updateIcons('file'); + OC.Share.updateIcons('file', $fileList); } }); - FileActions.register('all', 'Share', OC.PERMISSION_SHARE, OC.imagePath('core', 'actions/share'), function(filename) { - var tr = FileList.findFileEl(filename); + OCA.Files.FileActions.register( + 'all', + 'Share', + OC.PERMISSION_SHARE, + OC.imagePath('core', 'actions/share'), + function(filename, context) { + + var $tr = context.$file; var itemType = 'file'; - if ($(tr).data('type') == 'dir') { + if ($tr.data('type') === 'dir') { itemType = 'folder'; } - var possiblePermissions = $(tr).data('reshare-permissions'); + var possiblePermissions = $tr.data('reshare-permissions'); if (_.isUndefined(possiblePermissions)) { - possiblePermissions = $(tr).data('permissions'); + possiblePermissions = $tr.data('permissions'); } - var appendTo = $(tr).find('td.filename'); + var appendTo = $tr.find('td.filename'); // Check if drop down is already visible for a different file if (OC.Share.droppedDown) { - if ($(tr).data('id') != $('#dropdown').attr('data-item-source')) { + if ($tr.data('id') !== $('#dropdown').attr('data-item-source')) { OC.Share.hideDropDown(function () { - $(tr).addClass('mouseOver'); - OC.Share.showDropDown(itemType, $(tr).data('id'), appendTo, true, possiblePermissions, filename); + $tr.addClass('mouseOver'); + OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename); }); } else { OC.Share.hideDropDown(); } } else { - $(tr).addClass('mouseOver'); - OC.Share.showDropDown(itemType, $(tr).data('id'), appendTo, true, possiblePermissions, filename); + $tr.addClass('mouseOver'); + OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename); } }); } diff --git a/apps/files_sharing/js/sharedfilelist.js b/apps/files_sharing/js/sharedfilelist.js index b2a05f585bb..9d8c9e38358 100644 --- a/apps/files_sharing/js/sharedfilelist.js +++ b/apps/files_sharing/js/sharedfilelist.js @@ -47,6 +47,7 @@ $tr.find('td.date').before($sharedWith); $tr.find('td.filename input:checkbox').remove(); $tr.attr('data-path', fileData.path); + $tr.attr('data-share-id', _.pluck(fileData.shares, 'id').join(',')); return $tr; }, @@ -60,6 +61,22 @@ this._sharedWithUser = !!state; }, + updateEmptyContent: function() { + var dir = this.getCurrentDirectory(); + if (dir === '/') { + // root has special permissions + this.$el.find('#emptycontent').toggleClass('hidden', !this.isEmpty); + this.$el.find('#filestable thead th').toggleClass('hidden', this.isEmpty); + } + else { + OCA.Files.FileList.prototype.updateEmptyContent.apply(this, arguments); + } + }, + + getDirectoryPermissions: function() { + return OC.PERMISSION_READ; + }, + reload: function() { var self = this; this.showMask(); diff --git a/apps/files_trashbin/js/app.js b/apps/files_trashbin/js/app.js index aa499ae1791..cf3fb1d0d16 100644 --- a/apps/files_trashbin/js/app.js +++ b/apps/files_trashbin/js/app.js @@ -39,7 +39,8 @@ OCA.Trashbin.App = { fileActions.setDefault('dir', 'Open'); - fileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history'), function(filename) { + fileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history'), function(filename, context) { + var fileList = context.fileList; var tr = fileList.findFileEl(filename); var deleteAction = tr.children("td.date").children(".action.delete"); deleteAction.removeClass('delete-icon').addClass('progress-icon'); @@ -54,7 +55,8 @@ OCA.Trashbin.App = { fileActions.register('all', 'Delete', OC.PERMISSION_READ, function() { return OC.imagePath('core', 'actions/delete'); - }, function(filename) { + }, function(filename, context) { + var fileList = context.fileList; $('.tipsy').remove(); var tr = fileList.findFileEl(filename); var deleteAction = tr.children("td.date").children(".action.delete"); diff --git a/core/js/share.js b/core/js/share.js index d013f257579..279b1d11663 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -10,8 +10,11 @@ OC.Share={ * Loads ALL share statuses from server, stores them in OC.Share.statuses then * calls OC.Share.updateIcons() to update the files "Share" icon to "Shared" * according to their share status and share type. + * + * @param itemType item type + * @param fileList file list instance, defaults to OCA.Files.App.fileList */ - loadIcons:function(itemType) { + loadIcons:function(itemType, fileList) { // Load all share icons $.get(OC.filePath('core', 'ajax', 'share.php'), { fetch: 'getItemsSharedStatuses', itemType: itemType }, function(result) { if (result && result.status === 'success') { @@ -19,7 +22,7 @@ OC.Share={ $.each(result.data, function(item, data) { OC.Share.statuses[item] = data; }); - OC.Share.updateIcons(itemType); + OC.Share.updateIcons(itemType, fileList); } }); }, @@ -27,9 +30,18 @@ OC.Share={ * Updates the files' "Share" icons according to the known * sharing states stored in OC.Share.statuses. * (not reloaded from server) + * + * @param itemType item type + * @param fileList file list instance or file list jQuery element, + * defaults to OCA.Files.App.fileList */ - updateIcons:function(itemType){ + updateIcons:function(itemType, fileList){ var item; + var $fileList = (fileList || OCA.Files.App.fileList); + // in case the jQuery element was passed instead + if ($fileList.$fileList) { + $fileList = $fileList.$fileList; + } for (item in OC.Share.statuses){ var data = OC.Share.statuses[item]; @@ -41,9 +53,9 @@ OC.Share={ var image = OC.imagePath('core', 'actions/shared'); } if (itemType != 'file' && itemType != 'folder') { - $('a.share[data-item="'+item+'"]').css('background', 'url('+image+') no-repeat center'); + $fileList.find('a.share[data-item="'+item+'"]').css('background', 'url('+image+') no-repeat center'); } else { - var file = $('tr[data-id="'+item+'"]'); + var file = $fileList.find('tr[data-id="'+item+'"]'); if (file.length > 0) { var action = $(file).find('.fileactions .action[data-action="Share"]'); var img = action.find('img').attr('src', image); @@ -57,7 +69,7 @@ OC.Share={ // Search for possible parent folders that are shared while (path != last) { if (path == data['path'] && !data['link']) { - var actions = $('.fileactions .action[data-action="Share"]'); + var actions = $fileList.find('.fileactions .action[data-action="Share"]'); $.each(actions, function(index, action) { var img = $(action).find('img'); if (img.attr('src') != OC.imagePath('core', 'actions/public')) { -- 2.39.5