diff options
Diffstat (limited to 'apps/files/js')
-rw-r--r-- | apps/files/js/app.js | 6 | ||||
-rw-r--r-- | apps/files/js/breadcrumb.js | 2 | ||||
-rw-r--r-- | apps/files/js/file-upload.js | 12 | ||||
-rw-r--r-- | apps/files/js/filelist.js | 124 | ||||
-rw-r--r-- | apps/files/js/files.js | 7 |
5 files changed, 130 insertions, 21 deletions
diff --git a/apps/files/js/app.js b/apps/files/js/app.js index 6f5206fcdb6..89098e3a8a3 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -24,6 +24,7 @@ initialize: function() { this.navigation = new OCA.Files.Navigation($('#app-navigation')); + var urlParams = OC.Util.History.parseUrlQuery(); var fileActions = new OCA.Files.FileActions(); // default actions fileActions.registerDefaultActions(); @@ -47,7 +48,8 @@ dragOptions: dragOptions, folderDropOptions: folderDropOptions, fileActions: fileActions, - allowLegacyActions: true + allowLegacyActions: true, + scrollTo: urlParams.scrollto } ); this.files.initialize(); @@ -58,7 +60,7 @@ this._setupEvents(); // trigger URL change event handlers - this._onPopState(OC.Util.History.parseUrlQuery()); + this._onPopState(urlParams); }, /** diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 7381fa8e432..8df9b7ee6fe 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -224,6 +224,8 @@ this.$el.find('.crumb.ellipsized') .attr('title', $crumb.attr('data-dir')) .tipsy(); + this.$el.find('.ellipsis') + .wrap('<a class="ellipsislink" href="' + encodeURI(OC.generateUrl('apps/files/?dir=' + $crumb.attr('data-dir'))) + '"></a>'); } // and all the previous ones (going backwards) firstHidden = false; diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index ff999bae4ff..460c2435642 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -427,6 +427,14 @@ OC.Upload = { data.textStatus = 'servererror'; data.errorThrown = result[0].data.message; // error message has been translated on server fu._trigger('fail', e, data); + } else { // Successful upload + // Checking that the uploaded file is the last one and contained in the current directory + if (data.files[0] === data.originalFiles[data.originalFiles.length - 1] && + result[0].directory === FileList.getCurrentDirectory()) { + // Scroll to the last uploaded file and highlight all of them + var fileList = _.pluck(data.originalFiles, 'name'); + FileList.highlightFiles(fileList); + } } }, /** @@ -621,7 +629,7 @@ OC.Upload = { }, function(result) { if (result.status === 'success') { - FileList.add(result.data, {hidden: hidden, animate: true}); + FileList.add(result.data, {hidden: hidden, animate: true, scrollTo: true}); } else { OC.dialogs.alert(result.data.message, t('core', 'Could not create file')); } @@ -637,7 +645,7 @@ OC.Upload = { }, function(result) { if (result.status === 'success') { - FileList.add(result.data, {hidden: hidden, animate: true}); + FileList.add(result.data, {hidden: hidden, animate: true, scrollTo: true}); } else { OC.dialogs.alert(result.data.message, t('core', 'Could not create folder')); } diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index fd11a80248d..1aabfb91f1f 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -110,9 +110,10 @@ * @param $el container element with existing markup for the #controls * and a table * @param options map of options, see other parameters - * @param scrollContainer scrollable container, defaults to $(window) - * @param dragOptions drag options, disabled by default - * @param folderDropOptions folder drop options, disabled by default + * @param options.scrollContainer scrollable container, defaults to $(window) + * @param options.dragOptions drag options, disabled by default + * @param options.folderDropOptions folder drop options, disabled by default + * @param options.scrollTo name of file to scroll to after the first load */ initialize: function($el, options) { var self = this; @@ -172,6 +173,12 @@ this.setupUploadEvents(); this.$container.on('scroll', _.bind(this._onScroll, this)); + + if (options.scrollTo) { + this.$fileList.one('updated', function() { + self.scrollTo(options.scrollTo); + }); + } }, /** @@ -667,6 +674,12 @@ if (extension) { nameSpan.append($('<span></span>').addClass('extension').text(extension)); } + if (fileData.extraData) { + if (fileData.extraData.charAt(0) === '/') { + fileData.extraData = fileData.extraData.substr(1); + } + nameSpan.addClass('extra-data').attr('title', fileData.extraData); + } // dirs can show the number of uploaded files if (type === 'dir') { linkElem.append($('<span></span>').attr({ @@ -715,9 +728,10 @@ * * @param fileData map of file attributes * @param options map of attributes: - * - "updateSummary": true to update the summary after adding (default), false otherwise - * - "silent": true to prevent firing events like "fileActionsReady" - * - "animate": true to animate preview loading (defaults to true here) + * @param options.updateSummary true to update the summary after adding (default), false otherwise + * @param options.silent true to prevent firing events like "fileActionsReady" + * @param options.animate true to animate preview loading (defaults to true here) + * @param options.scrollTo true to automatically scroll to the file's location * @return new tr element (not appended to the table) */ add: function(fileData, options) { @@ -766,6 +780,10 @@ }); } + if (options.scrollTo) { + this.scrollTo(fileData.name); + } + // defaults to true if not defined if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) { this.fileSummary.add(fileData, true); @@ -1523,16 +1541,15 @@ this.$table.removeClass('hidden'); }, scrollTo:function(file) { - //scroll to and highlight preselected file - var $scrollToRow = this.findFileEl(file); - if ($scrollToRow.exists()) { - $scrollToRow.addClass('searchresult'); - $(window).scrollTop($scrollToRow.position().top); - //remove highlight when hovered over - $scrollToRow.one('hover', function() { - $scrollToRow.removeClass('searchresult'); - }); + if (!_.isArray(file)) { + file = [file]; } + this.highlightFiles(file, function($tr) { + $tr.addClass('searchresult'); + $tr.one('hover', function() { + $tr.removeClass('searchresult'); + }); + }); }, filter:function(query) { this.$fileList.find('tr').each(function(i,e) { @@ -1632,6 +1649,18 @@ }, /** + * Shows a "permission denied" notification + */ + _showPermissionDeniedNotification: function() { + var message = t('core', 'You don’t have permission to upload or create files here'); + OC.Notification.show(message); + //hide notification after 10 sec + setTimeout(function() { + OC.Notification.hide(); + }, 5000); + }, + + /** * Setup file upload events related to the file-upload plugin */ setupUploadEvents: function() { @@ -1662,6 +1691,12 @@ // remember as context data.context = dropTarget; + // if permissions are specified, only allow if create permission is there + var permissions = dropTarget.data('permissions'); + if (!_.isUndefined(permissions) && (permissions & OC.PERMISSION_CREATE) === 0) { + self._showPermissionDeniedNotification(); + return false; + } var dir = dropTarget.data('file'); // if from file list, need to prepend parent dir if (dir) { @@ -1686,6 +1721,7 @@ // cancel uploads to current dir if no permission var isCreatable = (self.getDirectoryPermissions() & OC.PERMISSION_CREATE) !== 0; if (!isCreatable) { + self._showPermissionDeniedNotification(); return false; } } @@ -1856,6 +1892,62 @@ self.updateStorageStatistics(); }); + }, + + /** + * Scroll to the last file of the given list + * Highlight the list of files + * @param files array of filenames, + * @param {Function} [highlightFunction] optional function + * to be called after the scrolling is finished + */ + highlightFiles: function(files, highlightFunction) { + // Detection of the uploaded element + var filename = files[files.length - 1]; + var $fileRow = this.findFileEl(filename); + + while(!$fileRow.exists() && this._nextPage(false) !== false) { // Checking element existence + $fileRow = this.findFileEl(filename); + } + + if (!$fileRow.exists()) { // Element not present in the file list + return; + } + + var currentOffset = this.$container.scrollTop(); + var additionalOffset = this.$el.find("#controls").height()+this.$el.find("#controls").offset().top; + + // Animation + var _this = this; + this.$container.animate({ + // Scrolling to the top of the new element + scrollTop: currentOffset + $fileRow.offset().top - $fileRow.height() * 2 - additionalOffset + }, { + duration: 500, + complete: function() { + // Highlighting function + var highlightRow = highlightFunction; + + if (!highlightRow) { + highlightRow = function($fileRow) { + $fileRow.addClass("highlightUploaded"); + setTimeout(function() { + $fileRow.removeClass("highlightUploaded"); + }, 2500); + }; + } + + // Loop over uploaded files + for(var i=0; i<files.length; i++) { + var $fileRow = _this.findFileEl(files[i]); + + if($fileRow.length !== 0) { // Checking element existence + highlightRow($fileRow); + } + } + + } + }); } }; @@ -1879,7 +1971,7 @@ if (fileInfo1.type !== 'dir' && fileInfo2.type === 'dir') { return 1; } - return fileInfo1.name.localeCompare(fileInfo2.name); + return OC.Util.naturalSortCompare(fileInfo1.name, fileInfo2.name); }, /** * Compares two file infos by size. diff --git a/apps/files/js/files.js b/apps/files/js/files.js index df0c40a4405..5fcf99d24af 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -433,7 +433,12 @@ var folderDropOptions = { return false; } - var targetPath = FileList.getCurrentDirectory() + '/' + $(this).closest('tr').data('file'); + var $tr = $(this).closest('tr'); + if (($tr.data('permissions') & OC.PERMISSION_CREATE) === 0) { + FileList._showPermissionDeniedNotification(); + return false; + } + var targetPath = FileList.getCurrentDirectory() + '/' + $tr.data('file'); var files = FileList.getSelectedFiles(); if (files.length === 0) { |