summaryrefslogtreecommitdiffstats
path: root/apps/files/js/filelist.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/js/filelist.js')
-rw-r--r--apps/files/js/filelist.js314
1 files changed, 155 insertions, 159 deletions
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 159d008e6e6..43cb3bac64b 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -30,6 +30,7 @@
* @param {Object} [options.dragOptions] drag options, disabled by default
* @param {Object} [options.folderDropOptions] folder drop options, disabled by default
* @param {boolean} [options.detailsViewEnabled=true] whether to enable details view
+ * @param {boolean} [options.enableUpload=false] whether to enable uploader
* @param {OC.Files.Client} [options.filesClient] files client to use
*/
var FileList = function($el, options) {
@@ -189,6 +190,11 @@
_folderDropOptions: null,
/**
+ * @type OC.Uploader
+ */
+ _uploader: null,
+
+ /**
* Initialize the file list and its components
*
* @param $el container element with existing markup for the #controls
@@ -328,8 +334,6 @@
this.$el.find('.selectedActions a').tooltip({placement:'top'});
- this.setupUploadEvents();
-
this.$container.on('scroll', _.bind(this._onScroll, this));
if (options.scrollTo) {
@@ -338,6 +342,20 @@
});
}
+ if (options.enableUpload) {
+ // TODO: auto-create this element
+ var $uploadEl = this.$el.find('#file_upload_start');
+ if ($uploadEl.exists()) {
+ this._uploader = new OC.Uploader($uploadEl, {
+ fileList: this,
+ filesClient: this.filesClient,
+ dropZone: $('#content')
+ });
+
+ this.setupUploadEvents(this._uploader);
+ }
+ }
+
OC.Plugins.attach('OCA.Files.FileList', this);
},
@@ -1420,7 +1438,10 @@
return;
}
this._setCurrentDir(targetDir, changeUrl, fileId);
- return this.reload().then(function(success){
+
+ // discard finished uploads list, we'll get it through a regular reload
+ this._uploads = {};
+ this.reload().then(function(success){
if (!success) {
self.changeDirectory(currentDir, true);
}
@@ -1660,6 +1681,24 @@
return OCA.Files.Files.getDownloadUrl(files, dir || this.getCurrentDirectory(), isDir);
},
+ getUploadUrl: function(fileName, dir) {
+ if (_.isUndefined(dir)) {
+ dir = this.getCurrentDirectory();
+ }
+
+ var pathSections = dir.split('/');
+ if (!_.isUndefined(fileName)) {
+ pathSections.push(fileName);
+ }
+ var encodedPath = '';
+ _.each(pathSections, function(section) {
+ if (section !== '') {
+ encodedPath += '/' + encodeURIComponent(section);
+ }
+ });
+ return OC.linkToRemoteBase('webdav') + encodedPath;
+ },
+
/**
* Generates a preview URL based on the URL space.
* @param urlSpec attributes for the URL
@@ -2121,19 +2160,11 @@
)
.done(function() {
// TODO: error handling / conflicts
- self.filesClient.getFileInfo(
- targetPath, {
- properties: self._getWebdavProperties()
- }
- )
- .then(function(status, data) {
- self.add(data, {animate: true, scrollTo: true});
- deferred.resolve(status, data);
- })
- .fail(function(status) {
- OC.Notification.showTemporary(t('files', 'Could not create file "{file}"', {file: name}));
- deferred.reject(status);
- });
+ self.addAndFetchFileInfo(targetPath, '', {scrollTo: true}).then(function(status, data) {
+ deferred.resolve(status, data);
+ }, function() {
+ OC.Notification.showTemporary(t('files', 'Could not create file "{file}"', {file: name}));
+ });
})
.fail(function(status) {
if (status === 412) {
@@ -2174,32 +2205,19 @@
var targetPath = this.getCurrentDirectory() + '/' + name;
this.filesClient.createDirectory(targetPath)
- .done(function(createStatus) {
- self.filesClient.getFileInfo(
- targetPath, {
- properties: self._getWebdavProperties()
- }
- )
- .done(function(status, data) {
- self.add(data, {animate: true, scrollTo: true});
- deferred.resolve(status, data);
- })
- .fail(function() {
- OC.Notification.showTemporary(t('files', 'Could not create folder "{dir}"', {dir: name}));
- deferred.reject(createStatus);
- });
+ .done(function() {
+ self.addAndFetchFileInfo(targetPath, '', {scrollTo:true}).then(function(status, data) {
+ deferred.resolve(status, data);
+ }, function() {
+ OC.Notification.showTemporary(t('files', 'Could not create folder "{dir}"', {dir: name}));
+ });
})
.fail(function(createStatus) {
// method not allowed, folder might exist already
if (createStatus === 405) {
- self.filesClient.getFileInfo(
- targetPath, {
- properties: self._getWebdavProperties()
- }
- )
+ // add it to the list, for completeness
+ self.addAndFetchFileInfo(targetPath, '', {scrollTo:true})
.done(function(status, data) {
- // add it to the list, for completeness
- self.add(data, {animate: true, scrollTo: true});
OC.Notification.showTemporary(
t('files', 'Could not create folder "{dir}" because it already exists', {dir: name})
);
@@ -2222,6 +2240,60 @@
},
/**
+ * Add file into the list by fetching its information from the server first.
+ *
+ * If the given directory does not match the current directory, nothing will
+ * be fetched.
+ *
+ * @param {String} fileName file name
+ * @param {String} [dir] optional directory, defaults to the current one
+ * @param {Object} options same options as #add
+ * @return {Promise} promise that resolves with the file info, or an
+ * already resolved Promise if no info was fetched. The promise rejects
+ * if the file was not found or an error occurred.
+ *
+ * @since 9.0
+ */
+ addAndFetchFileInfo: function(fileName, dir, options) {
+ var self = this;
+ var deferred = $.Deferred();
+ if (_.isUndefined(dir)) {
+ dir = this.getCurrentDirectory();
+ } else {
+ dir = dir || '/';
+ }
+
+ var targetPath = OC.joinPaths(dir, fileName);
+
+ if ((OC.dirname(targetPath) || '/') !== this.getCurrentDirectory()) {
+ // no need to fetch information
+ deferred.resolve();
+ return deferred.promise();
+ }
+
+ var addOptions = _.extend({
+ animate: true,
+ scrollTo: false
+ }, options || {});
+
+ this.filesClient.getFileInfo(targetPath, {
+ properties: this._getWebdavProperties()
+ })
+ .then(function(status, data) {
+ // remove first to avoid duplicates
+ self.remove(data.name);
+ self.add(data, addOptions);
+ deferred.resolve(status, data);
+ })
+ .fail(function(status) {
+ OC.Notification.showTemporary(t('files', 'Could not create file "{file}"', {file: name}));
+ deferred.reject(status);
+ });
+
+ return deferred.promise();
+ },
+
+ /**
* Returns whether the given file name exists in the list
*
* @param {string} file file name
@@ -2590,18 +2662,16 @@
/**
* Setup file upload events related to the file-upload plugin
*/
- setupUploadEvents: function() {
+ setupUploadEvents: function($uploadEl) {
var self = this;
- // handle upload events
- var fileUploadStart = this.$el;
- var delegatedElement = '#file_upload_start';
+ self._uploads = {};
// detect the progress bar resize
- fileUploadStart.on('resized', this._onResize);
+ $uploadEl.on('resized', this._onResize);
- fileUploadStart.on('fileuploaddrop', delegatedElement, function(e, data) {
- OC.Upload.log('filelist handle fileuploaddrop', e, data);
+ $uploadEl.on('fileuploaddrop', function(e, data) {
+ self._uploader.log('filelist handle fileuploaddrop', e, data);
if (self.$el.hasClass('hidden')) {
// do not upload to invisible lists
@@ -2664,13 +2734,8 @@
}
}
});
- fileUploadStart.on('fileuploadadd', function(e, data) {
- OC.Upload.log('filelist handle fileuploadadd', e, data);
-
- //finish delete if we are uploading a deleted file
- if (self.deleteFiles && self.deleteFiles.indexOf(data.files[0].name)!==-1) {
- self.finishDelete(null, true); //delete file before continuing
- }
+ $uploadEl.on('fileuploadadd', function(e, data) {
+ self._uploader.log('filelist handle fileuploadadd', e, data);
// add ui visualization to existing folder
if (data.context && data.context.data('type') === 'dir') {
@@ -2692,126 +2757,57 @@
}
}
+ if (!data.targetDir) {
+ data.targetDir = self.getCurrentDirectory();
+ }
+
});
/*
* when file upload done successfully add row to filelist
* update counter when uploading to sub folder
*/
- fileUploadStart.on('fileuploaddone', function(e, data) {
- OC.Upload.log('filelist handle fileuploaddone', e, data);
+ $uploadEl.on('fileuploaddone', function(e, data) {
+ self._uploader.log('filelist handle fileuploaddone', e, data);
- var response;
- if (typeof data.result === 'string') {
- response = data.result;
- } else {
- // fetch response from iframe
- response = data.result[0].body.innerText;
+ var status = data.jqXHR.status;
+ if (status < 200 || status >= 300) {
+ // error was handled in OC.Uploads already
+ return;
}
- var result = JSON.parse(response);
-
- if (typeof result[0] !== 'undefined' && result[0].status === 'success') {
- var file = result[0];
- var size = 0;
-
- if (data.context && data.context.data('type') === 'dir') {
-
- // update upload counter ui
- var uploadText = data.context.find('.uploadtext');
- var currentUploads = parseInt(uploadText.attr('currentUploads'), 10);
- currentUploads -= 1;
- uploadText.attr('currentUploads', currentUploads);
- var translatedText = n('files', 'Uploading %n file', 'Uploading %n files', currentUploads);
- if (currentUploads === 0) {
- self.showFileBusyState(uploadText.closest('tr'), false);
- uploadText.text(translatedText);
- uploadText.hide();
- } else {
- uploadText.text(translatedText);
- }
-
- // update folder size
- size = parseInt(data.context.data('size'), 10);
- size += parseInt(file.size, 10);
- data.context.attr('data-size', size);
- data.context.find('td.filesize').text(humanFileSize(size));
- } else {
- // only append new file if uploaded into the current folder
- if (file.directory !== self.getCurrentDirectory()) {
- // Uploading folders actually uploads a list of files
- // for which the target directory (file.directory) might lie deeper
- // than the current directory
-
- var fileDirectory = file.directory.replace('/','').replace(/\/$/, "");
- var currentDirectory = self.getCurrentDirectory().replace('/','').replace(/\/$/, "") + '/';
-
- if (currentDirectory !== '/') {
- // abort if fileDirectory does not start with current one
- if (fileDirectory.indexOf(currentDirectory) !== 0) {
- return;
- }
-
- // remove the current directory part
- fileDirectory = fileDirectory.substr(currentDirectory.length);
- }
-
- // only take the first section of the path
- fileDirectory = fileDirectory.split('/');
-
- var fd;
- // if the first section exists / is a subdir
- if (fileDirectory.length) {
- fileDirectory = fileDirectory[0];
-
- // See whether it is already in the list
- fd = self.findFileEl(fileDirectory);
- if (fd.length === 0) {
- var dir = {
- name: fileDirectory,
- type: 'dir',
- mimetype: 'httpd/unix-directory',
- permissions: file.permissions,
- size: 0,
- id: file.parentId
- };
- fd = self.add(dir, {insert: true});
- }
-
- // update folder size
- size = parseInt(fd.attr('data-size'), 10);
- size += parseInt(file.size, 10);
- fd.attr('data-size', size);
- fd.find('td.filesize').text(OC.Util.humanFileSize(size));
- }
-
- return;
- }
-
- // add as stand-alone row to filelist
- size = t('files', 'Pending');
- if (data.files[0].size>=0) {
- size=data.files[0].size;
- }
- //should the file exist in the list remove it
- self.remove(file.name);
- // create new file context
- data.context = self.add(file, {animate: true});
- }
+ var upload = self._uploader.getUpload(data);
+ var fileName = upload.getFileName();
+ var fetchInfoPromise = self.addAndFetchFileInfo(fileName, upload.getFullPath());
+ if (!self._uploads) {
+ self._uploads = {};
+ }
+ if (OC.isSamePath(OC.dirname(upload.getFullPath() + '/'), self.getCurrentDirectory())) {
+ self._uploads[fileName] = fetchInfoPromise;
}
});
- fileUploadStart.on('fileuploadstop', function() {
- OC.Upload.log('filelist handle fileuploadstop');
-
- //cleanup uploading to a dir
- var uploadText = self.$fileList.find('tr .uploadtext');
- self.showFileBusyState(uploadText.closest('tr'), false);
- uploadText.fadeOut();
- uploadText.attr('currentUploads', 0);
-
+ $uploadEl.on('fileuploadcreatedfolder', function(e, fullPath) {
+ self.addAndFetchFileInfo(OC.basename(fullPath), OC.dirname(fullPath));
+ });
+ $uploadEl.on('fileuploadstop', function() {
+ self._uploader.log('filelist handle fileuploadstop');
+
+ // prepare list of uploaded file names in the current directory
+ // and discard the other ones
+ var promises = _.values(self._uploads);
+ var fileNames = _.keys(self._uploads);
+ self._uploads = [];
+
+ // as soon as all info is fetched
+ $.when.apply($, promises).then(function() {
+ // highlight uploaded files
+ self.highlightFiles(fileNames);
+ });
self.updateStorageStatistics();
});
- fileUploadStart.on('fileuploadfail', function(e, data) {
- OC.Upload.log('filelist handle fileuploadfail', e, data);
+ $uploadEl.on('fileuploadfail', function(e, data) {
+ self._uploader.log('filelist handle fileuploadfail', e, data);
+
+ self._uploads = [];
//if user pressed cancel hide upload chrome
if (data.errorThrown === 'abort') {