aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/js/files.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/js/files.js')
-rw-r--r--apps/files/js/files.js273
1 files changed, 195 insertions, 78 deletions
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 0b10fa8c63a..1ec4c4ec7ab 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -1,10 +1,59 @@
-Files={
+/*
+ * Copyright (c) 2014
+ *
+ * This file is licensed under the Affero General Public License version 3
+ * or later.
+ *
+ * See the COPYING-README file.
+ *
+ */
+
+/* global OC, t, n, FileList, FileActions */
+/* global getURLParameter, isPublic */
+var Files = {
+ // file space size sync
+ _updateStorageStatistics: function() {
+ Files._updateStorageStatisticsTimeout = null;
+ var currentDir = FileList.getCurrentDirectory(),
+ state = Files.updateStorageStatistics;
+ if (state.dir){
+ if (state.dir === currentDir) {
+ return;
+ }
+ // cancel previous call, as it was for another dir
+ state.call.abort();
+ }
+ state.dir = currentDir;
+ state.call = $.getJSON(OC.filePath('files','ajax','getstoragestats.php') + '?dir=' + encodeURIComponent(currentDir),function(response) {
+ state.dir = null;
+ state.call = null;
+ Files.updateMaxUploadFilesize(response);
+ });
+ },
+ updateStorageStatistics: function(force) {
+ if (!OC.currentUser) {
+ return;
+ }
+
+ // debounce to prevent calling too often
+ if (Files._updateStorageStatisticsTimeout) {
+ clearTimeout(Files._updateStorageStatisticsTimeout);
+ }
+ if (force) {
+ Files._updateStorageStatistics();
+ }
+ else {
+ Files._updateStorageStatisticsTimeout = setTimeout(Files._updateStorageStatistics, 250);
+ }
+ },
+
updateMaxUploadFilesize:function(response) {
if (response === undefined) {
return;
}
if (response.data !== undefined && response.data.uploadMaxFilesize !== undefined) {
$('#max_upload').val(response.data.uploadMaxFilesize);
+ $('#free_space').val(response.data.freeSpace);
$('#upload.button').attr('original-title', response.data.maxHumanFilesize);
$('#usedSpacePercent').val(response.data.usedSpacePercent);
Files.displayStorageWarnings();
@@ -20,17 +69,36 @@ Files={
}
},
- isFileNameValid:function (name) {
- if (name === '.') {
- throw t('files', '\'.\' is an invalid file name.');
- } else if (name.length === 0) {
- throw t('files', 'File name cannot be empty.');
+
+ /**
+ * Fix path name by removing double slash at the beginning, if any
+ */
+ fixPath: function(fileName) {
+ if (fileName.substr(0, 2) == '//') {
+ return fileName.substr(1);
}
+ return fileName;
+ },
+ /**
+ * Checks whether the given file name is valid.
+ * @param name file name to check
+ * @return true if the file name is valid.
+ * Throws a string exception with an error message if
+ * the file name is not valid
+ */
+ isFileNameValid: function (name) {
+ var trimmedName = name.trim();
+ if (trimmedName === '.' || trimmedName === '..') {
+ throw t('files', '"{name}" is an invalid file name.', {name: name});
+ } else if (trimmedName.length === 0) {
+ throw t('files', 'File name cannot be empty.');
+ }
// check for invalid characters
- var invalid_characters = ['\\', '/', '<', '>', ':', '"', '|', '?', '*'];
+ var invalid_characters =
+ ['\\', '/', '<', '>', ':', '"', '|', '?', '*', '\n'];
for (var i = 0; i < invalid_characters.length; i++) {
- if (name.indexOf(invalid_characters[i]) !== -1) {
+ if (trimmedName.indexOf(invalid_characters[i]) !== -1) {
throw t('files', "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed.");
}
}
@@ -235,7 +303,7 @@ $(document).ready(function() {
procesSelection();
} else {
var filename=$(this).parent().parent().attr('data-file');
- var tr=$('tr[data-file="'+filename+'"]');
+ var tr = FileList.findFileEl(filename);
var renaming=tr.data('renaming');
if (!renaming && !FileList.isLoading(filename)) {
FileActions.currentFile = $(this).parent();
@@ -337,33 +405,29 @@ $(document).ready(function() {
Files.resizeBreadcrumbs(width, true);
// display storage warnings
- setTimeout ( "Files.displayStorageWarnings()", 100 );
+ setTimeout(Files.displayStorageWarnings, 100);
OC.Notification.setDefault(Files.displayStorageWarnings);
- // file space size sync
- function update_storage_statistics() {
- $.getJSON(OC.filePath('files','ajax','getstoragestats.php'),function(response) {
- Files.updateMaxUploadFilesize(response);
- });
- }
-
- // start on load - we ask the server every 5 minutes
- var update_storage_statistics_interval = 5*60*1000;
- var update_storage_statistics_interval_id = setInterval(update_storage_statistics, update_storage_statistics_interval);
-
- // Use jquery-visibility to de-/re-activate file stats sync
- if ($.support.pageVisibility) {
- $(document).on({
- 'show.visibility': function() {
- if (!update_storage_statistics_interval_id) {
- update_storage_statistics_interval_id = setInterval(update_storage_statistics, update_storage_statistics_interval);
+ // only possible at the moment if user is logged in
+ if (OC.currentUser) {
+ // start on load - we ask the server every 5 minutes
+ var updateStorageStatisticsInterval = 5*60*1000;
+ var updateStorageStatisticsIntervalId = setInterval(Files.updateStorageStatistics, updateStorageStatisticsInterval);
+
+ // Use jquery-visibility to de-/re-activate file stats sync
+ if ($.support.pageVisibility) {
+ $(document).on({
+ 'show.visibility': function() {
+ if (!updateStorageStatisticsIntervalId) {
+ updateStorageStatisticsIntervalId = setInterval(Files.updateStorageStatistics, updateStorageStatisticsInterval);
+ }
+ },
+ 'hide.visibility': function() {
+ clearInterval(updateStorageStatisticsIntervalId);
+ updateStorageStatisticsIntervalId = 0;
}
- },
- 'hide.visibility': function() {
- clearInterval(update_storage_statistics_interval_id);
- update_storage_statistics_interval_id = 0;
- }
- });
+ });
+ }
}
//scroll to and highlight preselected file
@@ -404,6 +468,7 @@ function scanFiles(force, dir, users) {
scannerEventSource.listen('done',function(count) {
scanFiles.scanning=false;
console.log('done after ' + count + ' files');
+ Files.updateStorageStatistics();
});
scannerEventSource.listen('user',function(user) {
console.log('scanning files for ' + user);
@@ -449,7 +514,7 @@ var createDragShadow = function(event) {
var dir=$('#dir').val();
$(selectedFiles).each(function(i,elem) {
- var newtr = $('<tr/>').attr('data-dir', dir).attr('data-filename', elem.name);
+ var newtr = $('<tr/>').attr('data-dir', dir).attr('data-filename', elem.name).attr('data-origin', elem.origin);
newtr.append($('<td/>').addClass('filename').text(elem.name));
newtr.append($('<td/>').addClass('size').text(humanFileSize(elem.size)));
tbody.append(newtr);
@@ -457,9 +522,9 @@ var createDragShadow = function(event) {
newtr.find('td.filename').attr('style','background-image:url('+OC.imagePath('core', 'filetypes/folder.png')+')');
} else {
var path = getPathForPreview(elem.name);
- lazyLoadPreview(path, elem.mime, function(previewpath) {
+ Files.lazyLoadPreview(path, elem.mime, function(previewpath) {
newtr.find('td.filename').attr('style','background-image:url('+previewpath+')');
- });
+ }, null, null, elem.etag);
}
});
@@ -467,13 +532,30 @@ var createDragShadow = function(event) {
};
//options for file drag/drop
+//start&stop handlers needs some cleaning up
var dragOptions={
revert: 'invalid', revertDuration: 300,
- opacity: 0.7, zIndex: 100, appendTo: 'body', cursorAt: { left: -5, top: -5 },
+ opacity: 0.7, zIndex: 100, appendTo: 'body', cursorAt: { left: 24, top: 18 },
helper: createDragShadow, cursor: 'move',
- stop: function(event, ui) {
- $('#fileList tr td.filename').addClass('ui-draggable');
- }
+ start: function(event, ui){
+ var $selectedFiles = $('td.filename input:checkbox:checked');
+ if($selectedFiles.length > 1){
+ $selectedFiles.parents('tr').fadeTo(250, 0.2);
+ }
+ else{
+ $(this).fadeTo(250, 0.2);
+ }
+ },
+ stop: function(event, ui) {
+ var $selectedFiles = $('td.filename input:checkbox:checked');
+ if($selectedFiles.length > 1){
+ $selectedFiles.parents('tr').fadeTo(250, 1);
+ }
+ else{
+ $(this).fadeTo(250, 1);
+ }
+ $('#fileList tr td.filename').addClass('ui-draggable');
+ }
};
// sane browsers support using the distance option
if ( $('html.ie').length === 0) {
@@ -481,6 +563,7 @@ if ( $('html.ie').length === 0) {
}
var folderDropOptions={
+ hoverClass: "canDrop",
drop: function( event, ui ) {
//don't allow moving a file into a selected folder
if ($(event.target).parents('tr').find('td input:first').prop('checked') === true) {
@@ -493,14 +576,21 @@ var folderDropOptions={
$(files).each(function(i,row) {
var dir = $(row).data('dir');
var file = $(row).data('filename');
+ //slapdash selector, tracking down our original element that the clone budded off of.
+ var origin = $('tr[data-id=' + $(row).data('origin') + ']');
+ var td = origin.children('td.filename');
+ var oldBackgroundImage = td.css('background-image');
+ td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')');
$.post(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: dir+'/'+target }, function(result) {
if (result) {
if (result.status === 'success') {
//recalculate folder size
- var oldSize = $('#fileList tr[data-file="'+target+'"]').data('size');
- var newSize = oldSize + $('#fileList tr[data-file="'+file+'"]').data('size');
- $('#fileList tr[data-file="'+target+'"]').data('size', newSize);
- $('#fileList tr[data-file="'+target+'"]').find('td.filesize').text(humanFileSize(newSize));
+ var oldFile = FileList.findFileEl(target);
+ var newFile = FileList.findFileEl(file);
+ var oldSize = oldFile.data('size');
+ var newSize = oldSize + newFile.data('size');
+ oldFile.data('size', newSize);
+ oldFile.find('td.filesize').text(humanFileSize(newSize));
FileList.remove(file);
procesSelection();
@@ -513,6 +603,7 @@ var folderDropOptions={
} else {
OC.dialogs.alert(t('files', 'Error moving file'), t('files', 'Error'));
}
+ td.css('background-image', oldBackgroundImage);
});
});
},
@@ -537,6 +628,11 @@ var crumbDropOptions={
$(files).each(function(i,row) {
var dir = $(row).data('dir');
var file = $(row).data('filename');
+ //slapdash selector, tracking down our original element that the clone budded off of.
+ var origin = $('tr[data-id=' + $(row).data('origin') + ']');
+ var td = origin.children('td.filename');
+ var oldBackgroundImage = td.css('background-image');
+ td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')');
$.post(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: target }, function(result) {
if (result) {
if (result.status === 'success') {
@@ -551,6 +647,7 @@ var crumbDropOptions={
} else {
OC.dialogs.alert(t('files', 'Error moving file'), t('files', 'Error'));
}
+ td.css('background-image', oldBackgroundImage);
});
});
},
@@ -566,21 +663,22 @@ function procesSelection() {
return el.type==='dir';
});
if (selectedFiles.length === 0 && selectedFolders.length === 0) {
- $('#headerName>span.name').text(t('files','Name'));
+ $('#headerName span.name').text(t('files','Name'));
$('#headerSize').text(t('files','Size'));
$('#modified').text(t('files','Modified'));
$('table').removeClass('multiselect');
$('.selectedActions').hide();
+ $('#select_all').removeAttr('checked');
}
else {
$('.selectedActions').show();
var totalSize = 0;
for(var i=0; i<selectedFiles.length; i++) {
totalSize+=selectedFiles[i].size;
- };
+ }
for(var i=0; i<selectedFolders.length; i++) {
totalSize+=selectedFolders[i].size;
- };
+ }
$('#headerSize').text(humanFileSize(totalSize));
var selection = '';
if (selectedFolders.length > 0) {
@@ -592,7 +690,7 @@ function procesSelection() {
if (selectedFiles.length>0) {
selection += n('files', '%n file', '%n files', selectedFiles.length);
}
- $('#headerName>span.name').text(selection);
+ $('#headerName span.name').text(selection);
$('#modified').text('');
$('table').addClass('multiselect');
}
@@ -615,7 +713,9 @@ function getSelectedFilesTrash(property) {
name:$(element).attr('data-file'),
mime:$(element).data('mime'),
type:$(element).data('type'),
- size:$(element).data('size')
+ size:$(element).data('size'),
+ etag:$(element).data('etag'),
+ origin: $(element).data('id')
};
if (property) {
files.push(file[property]);
@@ -626,26 +726,28 @@ function getSelectedFilesTrash(property) {
return files;
}
-function getMimeIcon(mime, ready) {
- if (getMimeIcon.cache[mime]) {
- ready(getMimeIcon.cache[mime]);
+Files.getMimeIcon = function(mime, ready) {
+ if (Files.getMimeIcon.cache[mime]) {
+ ready(Files.getMimeIcon.cache[mime]);
} else {
$.get( OC.filePath('files','ajax','mimeicon.php'), {mime: mime}, function(path) {
- getMimeIcon.cache[mime]=path;
- ready(getMimeIcon.cache[mime]);
+ Files.getMimeIcon.cache[mime]=path;
+ ready(Files.getMimeIcon.cache[mime]);
});
}
}
-getMimeIcon.cache={};
+Files.getMimeIcon.cache={};
function getPathForPreview(name) {
var path = $('#dir').val() + '/' + name;
return path;
}
-function lazyLoadPreview(path, mime, ready, width, height) {
+Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
// get mime icon url
- getMimeIcon(mime, function(iconURL) {
+ Files.getMimeIcon(mime, function(iconURL) {
+ var urlSpec = {};
+ var previewURL;
ready(iconURL); // set mimeicon URL
// now try getting a preview thumbnail URL
@@ -655,30 +757,44 @@ function lazyLoadPreview(path, mime, ready, width, height) {
if ( ! height ) {
height = $('#filestable').data('preview-y');
}
- if ( $('#publicUploadButtonMock').length ) {
- var previewURL = OC.Router.generate('core_ajax_public_preview', {file: path, x:width, y:height, t:$('#dirToken').val()});
+ // note: the order of arguments must match the one
+ // from the server's template so that the browser
+ // knows it's the same file for caching
+ urlSpec.x = width;
+ urlSpec.y = height;
+ urlSpec.file = Files.fixPath(path);
+
+ if (etag){
+ // use etag as cache buster
+ urlSpec.c = etag;
+ }
+ else {
+ console.warn('Files.lazyLoadPreview(): missing etag argument');
+ }
+
+ if ( $('#isPublic').length ) {
+ urlSpec.t = $('#dirToken').val();
+ previewURL = OC.Router.generate('core_ajax_public_preview', urlSpec);
} else {
- var previewURL = OC.Router.generate('core_ajax_preview', {file: path, x:width, y:height});
- }
- $.get(previewURL, function() {
- previewURL = previewURL.replace('(', '%28');
- previewURL = previewURL.replace(')', '%29');
- previewURL += '&reload=true';
-
- // preload image to prevent delay
- // this will make the browser cache the image
- var img = new Image();
- img.onload = function(){
- //set preview thumbnail URL
- ready(previewURL);
- }
- img.src = previewURL;
- });
+ previewURL = OC.Router.generate('core_ajax_preview', urlSpec);
+ }
+ previewURL = previewURL.replace('(', '%28');
+ previewURL = previewURL.replace(')', '%29');
+
+ // preload image to prevent delay
+ // this will make the browser cache the image
+ var img = new Image();
+ img.onload = function(){
+ //set preview thumbnail URL
+ ready(previewURL);
+ }
+ img.src = previewURL;
});
-}
+};
function getUniqueName(name) {
- if ($('tr[data-file="'+name+'"]').exists()) {
+ if (FileList.findFileEl(name).exists()) {
+ var numMatch;
var parts=name.split('.');
var extension = "";
if (parts.length > 1) {
@@ -712,7 +828,7 @@ function checkTrashStatus() {
function onClickBreadcrumb(e) {
var $el = $(e.target).closest('.crumb'),
- $targetDir = $el.data('dir');
+ $targetDir = $el.data('dir'),
isPublic = !!$('#isPublic').val();
if ($targetDir !== undefined && !isPublic) {
@@ -720,3 +836,4 @@ function onClickBreadcrumb(e) {
FileList.changeDirectory(decodeURIComponent($targetDir));
}
}
+