Add a queue for multiple uploads in the file app

pull/1/head
yflory 8 years ago
parent ef155d8ccf
commit 1ab6eb3c5d

@ -61,6 +61,7 @@ define(function () {
out.upgrade = "Améliorer"; out.upgrade = "Améliorer";
out.upgradeTitle = "Améliorer votre compte pour augmenter la limite de stockage"; out.upgradeTitle = "Améliorer votre compte pour augmenter la limite de stockage";
out.MB = "Mo"; out.MB = "Mo";
out.KB = "Ko";
out.greenLight = "Tout fonctionne bien"; out.greenLight = "Tout fonctionne bien";
out.orangeLight = "Votre connexion est lente, ce qui réduit la qualité de l'éditeur"; out.orangeLight = "Votre connexion est lente, ce qui réduit la qualité de l'éditeur";
@ -348,6 +349,21 @@ define(function () {
out.settings_logoutEverywhere = "Se déconnecter de toutes les autres sessions."; out.settings_logoutEverywhere = "Se déconnecter de toutes les autres sessions.";
out.settings_logoutEverywhereConfirm = "Êtes-vous sûr ? Vous devrez vous reconnecter sur tous vos autres appareils."; out.settings_logoutEverywhereConfirm = "Êtes-vous sûr ? Vous devrez vous reconnecter sur tous vos autres appareils.";
out.upload_serverError = "Erreur interne: impossible d'uploader le fichier pour l'instant.";
out.upload_uploadPending = "Vous avez déjà un fichier en cours d'upload. Souhaitez-vous l'annuler et uploader ce nouveau fichier ?";
out.upload_success = "Votre fichier ({0}) a été uploadé avec succès et ajouté à votre CryptDrive.";
out.upload_notEnoughSpace = "Il n'y a pas assez d'espace libre dans votre CryptDrive pour ce fichier.";
out.upload_tooLarge = "Ce fichier dépasse la taille maximale autorisée.";
out.upload_choose = "Choisir un fichier";
out.upload_pending = "En attente";
out.upload_cancelled = "Annulé";
out.upload_name = "Nom du fichier";
out.upload_size = "Taille";
out.upload_progress = "État";
// general warnings
out.warn_notPinned = "Ce pad n'est stocké dans aucun CryptDrive. Il va expirer après 3 mois d'inactivité. <a href='/about.html#pinning'>En savoir plus...</a>";
// index.html // index.html
//about.html //about.html

@ -63,6 +63,7 @@ define(function () {
out.upgrade = "Upgrade"; out.upgrade = "Upgrade";
out.upgradeTitle = "Upgrade your account to increase the storage limit"; out.upgradeTitle = "Upgrade your account to increase the storage limit";
out.MB = "MB"; out.MB = "MB";
out.KB = "KB";
out.greenLight = "Everything is working fine"; out.greenLight = "Everything is working fine";
out.orangeLight = "Your slow connection may impact your experience"; out.orangeLight = "Your slow connection may impact your experience";
@ -236,8 +237,6 @@ define(function () {
out.fm_info_template = 'Contains all the pads stored as templates and that you can re-use when you create a new pad.'; out.fm_info_template = 'Contains all the pads stored as templates and that you can re-use when you create a new pad.';
out.fm_info_trash = 'Files deleted from the trash are also removed from "All files" and it is impossible to recover them from the file manager.'; // Same here for "All files" and "out.fm_filesDataName" out.fm_info_trash = 'Files deleted from the trash are also removed from "All files" and it is impossible to recover them from the file manager.'; // Same here for "All files" and "out.fm_filesDataName"
out.fm_info_allFiles = 'Contains all the files from "Documents", "Unsorted" and "Trash". You can\'t move or remove files from here.'; // Same here out.fm_info_allFiles = 'Contains all the files from "Documents", "Unsorted" and "Trash". You can\'t move or remove files from here.'; // Same here
out.fm_info_login = "Log in";
out.fm_info_register = "Sign up";
out.fm_info_anonymous = 'You are not logged in so these pads may be deleted (<a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">find out why</a>). ' + out.fm_info_anonymous = 'You are not logged in so these pads may be deleted (<a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">find out why</a>). ' +
'<a href="/register/">Sign up</a> or <a href="/login/">Log in</a> to keep them alive.'; '<a href="/register/">Sign up</a> or <a href="/login/">Log in</a> to keep them alive.';
out.fm_alert_backupUrl = "Backup link for this drive.<br>" + out.fm_alert_backupUrl = "Backup link for this drive.<br>" +
@ -360,6 +359,12 @@ define(function () {
out.upload_success = "Your file ({0}) has been successfully uploaded and added to your drive."; out.upload_success = "Your file ({0}) has been successfully uploaded and added to your drive.";
out.upload_notEnoughSpace = "There is not enough space for this file in your CryptDrive."; out.upload_notEnoughSpace = "There is not enough space for this file in your CryptDrive.";
out.upload_tooLarge = "This file exceeds the maximum upload size."; out.upload_tooLarge = "This file exceeds the maximum upload size.";
out.upload_choose = "Choose a file";
out.upload_pending = "Pending";
out.upload_cancelled = "Cancelled";
out.upload_name = "File name";
out.upload_size = "Size";
out.upload_progress = "Progress";
// general warnings // general warnings
out.warn_notPinned = "This pad is not in anyone's CryptDrive. It will expire after 3 months. <a href='/about.html#pinning'>Learn more...</a>"; out.warn_notPinned = "This pad is not in anyone's CryptDrive. It will expire after 3 months. <a href='/about.html#pinning'>Learn more...</a>";

@ -13,7 +13,7 @@ var RPC = module.exports;
var Store = require("./storage/file"); var Store = require("./storage/file");
var DEFAULT_LIMIT = 50 * 1024 * 1024; var DEFAULT_LIMIT = 150 * 1024 * 1024;
var isValidId = function (chan) { var isValidId = function (chan) {
return /^[a-fA-F0-9]/.test(chan) || return /^[a-fA-F0-9]/.test(chan) ||

@ -42,6 +42,8 @@
margin: auto; margin: auto;
} }
#upload-form label{ #upload-form label{
text-align: center;
line-height: 50vh;
position: relative; position: relative;
} }
@ -82,14 +84,56 @@
display: block; display: block;
} }
#status {
display: none;
width: 80vw;
margin-top: 50px;
margin-left: 10vw;
border: 1px solid black;
border-collapse: collapse;
}
#status tr:nth-child(1) {
background-color: #ccc;
border: 1px solid #999;
}
#status tr:nth-child(1) td { text-align: center; }
#status td {
border-left: 1px solid #BBB;
border-right: 1px solid #BBB;
padding: 0 10px;
}
#status .upProgress {
width: 200px;
position: relative;
text-align: center;
}
#status .progressContainer {
position: absolute;
width: 0px;
left: 5px;
top: 1px; bottom: 1px;
background-color: rgba(0,0,255,0.3);
}
#status .upCancel { text-align: center; }
#status .fa.cancel {
color: rgb(255, 0, 115);
}
</style> </style>
</head> </head>
<body> <body>
<div id="toolbar" class="toolbar-container"></div> <div id="toolbar" class="toolbar-container"></div>
<div id="upload-form" style="display: none;"> <div id="upload-form" style="display: none;">
<input type="file" name="file" id="file" class="inputfile" /> <input type="file" name="file" id="file" class="inputfile" />
<label for="file" class="block">Choose a file<span class="block" id="progress">&nbsp;</span></label> <label for="file" class="block" data-localization="upload_choose">Choose a file<span class="block" id="progress">&nbsp;</span></label>
</div> </div>
<table id="status">
<tr>
<td data-localization="upload_name">File name</td>
<td data-localization="upload_size">Size</td>
<td data-localization="upload_progress">Progress</td>
<td data-localization="cancel">Cancel</td>
</tr>
</table>
<div id="feedback" class="block hidden"> <div id="feedback" class="block hidden">
</div> </div>
</body> </body>

@ -21,8 +21,9 @@ define([
var ifrw = $('#pad-iframe')[0].contentWindow; var ifrw = $('#pad-iframe')[0].contentWindow;
var $iframe = $('#pad-iframe').contents(); var $iframe = $('#pad-iframe').contents();
var $form = $iframe.find('#upload-form'); var $form = $iframe.find('#upload-form');
var $progress = $form.find('#progress'); //var $progress = $form.find('#progress');
var $label = $form.find('label'); var $label = $form.find('label');
var $table = $iframe.find('#status');
Cryptpad.addLoadingScreen(); Cryptpad.addLoadingScreen();
@ -31,8 +32,23 @@ define([
var myFile; var myFile;
var myDataType; var myDataType;
var upload = function (blob, metadata) { var queue = {
queue: [],
inProgress: false
};
var uid = function () {
return 'file-' + String(Math.random()).substring(2);
};
var upload = function (blob, metadata, id) {
console.log(metadata); console.log(metadata);
if (queue.inProgress) { return; }
queue.inProgress = true;
var $cancelCell = $table.find('tr[id="'+id+'"]').find('.upCancel');
$cancelCell.html('-');
var u8 = new Uint8Array(blob); var u8 = new Uint8Array(blob);
var key = Nacl.randomBytes(32); var key = Nacl.randomBytes(32);
@ -56,13 +72,19 @@ define([
if (err) { throw new Error(err); } if (err) { throw new Error(err); }
if (box) { if (box) {
actual += box.length; actual += box.length;
var progress = (actual / estimate * 100) + '%'; var progressValue = (actual / estimate * 100);
console.log(progress); var progress = progressValue + '%';
return void sendChunk(box, function (e) { return void sendChunk(box, function (e) {
if (e) { return console.error(e); } if (e) { return console.error(e); }
$progress.css({ /*$progress.css({
width: progress, width: progress,
});*/
var $pv = $table.find('tr[id="'+id+'"]').find('.progressValue');
$pv.text(Math.round(progressValue*100)/100 + '%');
var $pb = $table.find('tr[id="'+id+'"]').find('.progressContainer');
$pb.css({
width: (progressValue/100)*188+'px'
}); });
next(again); next(again);
@ -82,7 +104,7 @@ define([
var b64Key = Nacl.util.encodeBase64(key); var b64Key = Nacl.util.encodeBase64(key);
Cryptpad.replaceHash(Cryptpad.getFileHashFromKeys(id, b64Key)); Cryptpad.replaceHash(Cryptpad.getFileHashFromKeys(id, b64Key));
$form.hide(); //$form.hide();
APP.toolbar.addElement(['fileshare'], {}); APP.toolbar.addElement(['fileshare'], {});
@ -94,11 +116,15 @@ define([
APP.toolbar.title.show(); APP.toolbar.title.show();
console.log(title); console.log(title);
Cryptpad.alert(Messages._getKey('upload_success', [title])); Cryptpad.alert(Messages._getKey('upload_success', [title]));
queue.inProgress = false;
queue.next();
}); });
}; };
Cryptpad.uploadStatus(estimate, function (e, pending) { Cryptpad.uploadStatus(estimate, function (e, pending) {
if (e) { if (e) {
queue.inProgress = false;
queue.next();
if (e === 'TOO_LARGE') { if (e === 'TOO_LARGE') {
return void Cryptpad.alert(Messages.upload_tooLarge); return void Cryptpad.alert(Messages.upload_tooLarge);
} }
@ -110,7 +136,7 @@ define([
} }
if (pending) { if (pending) {
// TODO queue uploads... ? // TODO keep this message in case of pending files in another window?
return void Cryptpad.confirm(Messages.upload_uploadPending, function (yes) { return void Cryptpad.confirm(Messages.upload_uploadPending, function (yes) {
if (!yes) { return; } if (!yes) { return; }
Cryptpad.uploadCancel(function (e, res) { Cryptpad.uploadCancel(function (e, res) {
@ -126,6 +152,48 @@ define([
}); });
}; };
var prettySize = function (bytes) {
var kB = Cryptpad.bytesToKilobytes(bytes);
if (kB < 1024) { return kB + Messages.KB; }
var mB = Cryptpad.bytesToMegabytes(bytes);
return mB + Messages.MB;
};
queue.next = function () {
if (queue.queue.length === 0) { return; }
if (queue.inProgress) { return; }
var file = queue.queue.shift();
upload(file.blob, file.metadata, file.id);
};
queue.push = function (obj) {
var id = uid();
obj.id = id;
queue.queue.push(obj);
$table.show();
var estimate = FileCrypto.computeEncryptedSize(obj.blob.byteLength, obj.metadata);
var $progressBar = $('<div>', {'class':'progressContainer'});
var $progressValue = $('<span>', {'class':'progressValue'}).text(Messages.upload_pending);
var $tr = $('<tr>', {id: id}).appendTo($table);
var $cancel = $('<span>', {'class': 'cancel fa fa-times'}).click(function () {
queue.queue = queue.queue.filter(function (el) { return el.id !== id });
$cancel.remove();
$tr.find('.upCancel').text('-');
$tr.find('.progressValue').text(Messages.upload_cancelled);
});
var $tr = $('<tr>', {id: id}).appendTo($table);
$('<td>').text(obj.metadata.name).appendTo($tr);
$('<td>').text(prettySize(estimate)).appendTo($tr);
$('<td>', {'class': 'upProgress'}).append($progressBar).append($progressValue).appendTo($tr);
$('<td>', {'class': 'upCancel'}).append($cancel).appendTo($tr);
queue.next();
};
var uploadMode = false; var uploadMode = false;
var andThen = function () { var andThen = function () {
@ -225,9 +293,12 @@ define([
console.log(file); console.log(file);
var reader = new FileReader(); var reader = new FileReader();
reader.onloadend = function () { reader.onloadend = function () {
upload(this.result, { queue.push({
blob: this.result,
metadata: {
name: file.name, name: file.name,
type: file.type, type: file.type,
}
}); });
}; };
reader.readAsArrayBuffer(file); reader.readAsArrayBuffer(file);

Loading…
Cancel
Save