diff --git a/lib/Lufi/Controller/Files.pm b/lib/Lufi/Controller/Files.pm index e20d94e..664dcfd 100644 --- a/lib/Lufi/Controller/Files.pm +++ b/lib/Lufi/Controller/Files.pm @@ -42,12 +42,36 @@ sub upload { $c->app->log->debug('Got message'); + if (defined($json->{cancel}) && $json->{cancel}) { + my $f = Lufi::DB::File->new(app => $c->app)->from_short($json->{id}); + if ($f && $f->mod_token && $f->mod_token eq $json->{mod_token}) { + $f = $f->delete(); + return $ws->send(to_json( + { + action => 'cancel', + success => $f->deleted ? true : false, + msg => $f->deleted ? 'Lufi::DB::File->delete() was successfull' : 'Lufi::DB::File->delete() failed', + i => $json->{i} + } + )); + } else { + return $ws->send(to_json( + { + action => 'cancel', + success => false, + msg => 'Lufi::DB::File not found or invalid mod_token', + i => $json->{i} + } + )); + } + } + my $stop = 0; # Check if stop_upload file is present if ($c->stop_upload) { $stop = 1; - $c->send(decode('UTF-8', encode_json( + return $ws->send(decode('UTF-8', encode_json( { success => false, msg => $c->l('Sorry, uploading is disabled.'), @@ -60,7 +84,7 @@ sub upload { elsif (defined $c->config('max_file_size')) { if ($json->{size} > $c->config('max_file_size')) { $stop = 1; - $c->send(decode('UTF-8', encode_json( + return $ws->send(decode('UTF-8', encode_json( { success => false, msg => $c->l('Your file is too big: %1 (maximum size allowed: %2)', format_bytes($json->{size}), format_bytes($c->config('max_file_size'))), @@ -73,7 +97,7 @@ sub upload { # Check that we have enough space (multiplying by 2 since it's encrypted, it takes more place that the original file) elsif ($json->{part} == 0 && ($json->{size} * 2) >= dfportable($c->config('upload_dir'))->{bavail}) { $stop = 1; - $c->send(decode('UTF-8', encode_json( + return $ws->send(decode('UTF-8', encode_json( { success => false, msg => $c->l('No enough space available on the server for this file (size: %1).', format_bytes($json->{size})), diff --git a/lib/Lufi/DB/File.pm b/lib/Lufi/DB/File.pm index bf8a165..e0c562c 100644 --- a/lib/Lufi/DB/File.pm +++ b/lib/Lufi/DB/File.pm @@ -131,7 +131,7 @@ sub new { =over 1 -=item B : C<$c-Edelet> +=item B : C<$c-Edelete> =item B : none diff --git a/themes/default/lib/Lufi/I18N/lufi.pot b/themes/default/lib/Lufi/I18N/lufi.pot index 49dd8ba..eae4be0 100644 --- a/themes/default/lib/Lufi/I18N/lufi.pot +++ b/themes/default/lib/Lufi/I18N/lufi.pot @@ -78,7 +78,7 @@ msgstr "" msgid "Click here to refresh the page and restart the download." msgstr "" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/index.html.ep:119 msgid "Click to open the file browser" msgstr "" @@ -90,6 +90,10 @@ msgstr "" msgid "Comma-separated email addresses" msgstr "" +#: themes/default/templates/index.html.ep:133 +msgid "Compressing zip file…" +msgstr "" + #: themes/default/templates/partial/index.js.ep:14 msgid "Copy all links to clipboard" msgstr "" @@ -98,15 +102,15 @@ msgstr "" msgid "Copy to clipboard" msgstr "" -#: lib/Lufi/Controller/Files.pm:461 +#: lib/Lufi/Controller/Files.pm:485 msgid "Could not delete the file. You are not authenticated." msgstr "" -#: lib/Lufi/Controller/Files.pm:443 +#: lib/Lufi/Controller/Files.pm:467 msgid "Could not find the file. Are you sure of the URL and the token?" msgstr "" -#: lib/Lufi/Controller/Files.pm:354 +#: lib/Lufi/Controller/Files.pm:378 msgid "Could not find the file. Are you sure of the URL?" msgstr "" @@ -150,7 +154,7 @@ msgstr "" msgid "Drag and drop files in the appropriate area or use the traditional way to send files and the files will be chunked, encrypted and sent to the server. You will get two links per file: a download link, that you give to the people you want to share the file with and a deletion link, allowing you to delete the file whenever you want." msgstr "" -#: themes/default/templates/index.html.ep:104 +#: themes/default/templates/index.html.ep:115 msgid "Drop files here" msgstr "" @@ -170,15 +174,15 @@ msgstr "" msgid "Encrypting part XX1 of XX2" msgstr "" -#: lib/Lufi/Controller/Files.pm:243 +#: lib/Lufi/Controller/Files.pm:267 msgid "Error: the file existed but was deleted." msgstr "" -#: lib/Lufi/Controller/Files.pm:323 +#: lib/Lufi/Controller/Files.pm:347 msgid "Error: the file has not been sent entirely." msgstr "" -#: lib/Lufi/Controller/Files.pm:333 +#: lib/Lufi/Controller/Files.pm:357 msgid "Error: unable to find the file. Are you sure of your URL?" msgstr "" @@ -194,7 +198,7 @@ msgstr "" msgid "Export localStorage data" msgstr "" -#: lib/Lufi/Controller/Files.pm:425 +#: lib/Lufi/Controller/Files.pm:449 msgid "File deleted" msgstr "" @@ -294,8 +298,12 @@ msgstr "" msgid "My files" msgstr "" +#: themes/default/templates/index.html.ep:106 +msgid "Name of the zip file" +msgstr "" + #. (format_bytes($json->{size}) -#: lib/Lufi/Controller/Files.pm:79 +#: lib/Lufi/Controller/Files.pm:103 msgid "No enough space available on the server for this file (size: %1)." msgstr "" @@ -373,7 +381,7 @@ msgstr "" msgid "Sorry, the uploading is currently disabled. Please try again later." msgstr "" -#: lib/Lufi/Controller/Files.pm:53 +#: lib/Lufi/Controller/Files.pm:77 msgid "Sorry, uploading is disabled." msgstr "" @@ -397,7 +405,7 @@ msgstr "" msgid "The email subject can't be empty." msgstr "" -#: lib/Lufi/Controller/Files.pm:422 +#: lib/Lufi/Controller/Files.pm:446 msgid "The file has already been deleted" msgstr "" @@ -422,11 +430,11 @@ msgstr "" msgid "The original (and only for now) author is Luc Didry." msgstr "" -#: lib/Lufi/Controller/Files.pm:190 +#: lib/Lufi/Controller/Files.pm:214 msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator." msgstr "" -#: lib/Lufi/Controller/Files.pm:249 +#: lib/Lufi/Controller/Files.pm:273 msgid "This file has been deactivated by the admins. Contact them to know why." msgstr "" @@ -439,17 +447,17 @@ msgid "Unable to copy the link(s) to your clipboard" msgstr "" #. ($short) -#: lib/Lufi/Controller/Files.pm:393 +#: lib/Lufi/Controller/Files.pm:417 msgid "Unable to get counter for %1. The file does not exists. It will be removed from your localStorage." msgstr "" #. ($short) -#: lib/Lufi/Controller/Files.pm:383 +#: lib/Lufi/Controller/Files.pm:407 msgid "Unable to get counter for %1. The token is invalid." msgstr "" #. ($short) -#: lib/Lufi/Controller/Files.pm:403 +#: lib/Lufi/Controller/Files.pm:427 msgid "Unable to get counter for %1. You are not authenticated." msgstr "" @@ -457,11 +465,15 @@ msgstr "" msgid "Upload files" msgstr "" +#: themes/default/templates/index.html.ep:110 +msgid "Upload generated zip file" +msgstr "" + #: themes/default/templates/files.html.ep:30 msgid "Uploaded at" msgstr "" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/index.html.ep:142 msgid "Uploaded files" msgstr "" @@ -514,18 +526,14 @@ msgid "Your browser has not enough entropy to generate a strong encryption key. msgstr "" #. (format_bytes($json->{size}) -#: lib/Lufi/Controller/Files.pm:66 +#: lib/Lufi/Controller/Files.pm:90 msgid "Your file is too big: %1 (maximum size allowed: %2)" msgstr "" -#: lib/Lufi/Controller/Files.pm:305 +#: lib/Lufi/Controller/Files.pm:329 msgid "Your password is not valid. Please refresh the page to retry." msgstr "" -#: themes/default/templates/index.html.ep:112 -msgid "Zip archive creation…" -msgstr "" - #. (format_bytes($keys[$i]) #: themes/default/templates/delays.html.ep:20 msgid "between %1 and %2, the file will be kept %3 day(s)." @@ -554,6 +562,6 @@ msgstr "" msgid "no time limit" msgstr "" -#: themes/default/templates/index.html.ep:106 +#: themes/default/templates/index.html.ep:117 msgid "or" msgstr "" diff --git a/themes/default/public/css/lufi.css b/themes/default/public/css/lufi.css index 7b96ea9..0b3d146 100644 --- a/themes/default/public/css/lufi.css +++ b/themes/default/public/css/lufi.css @@ -140,6 +140,69 @@ nav .btn-flat { nav .btn-flat:focus { background-color: rgba(0,0,0,0.1) !important; } + +/* pulse animation from Materialize CSS 1.0.0 */ +button.pulse { + margin-left: 1em; +} +.pulse { + overflow: initial; + position: relative; +} +.pulse::before { + content: ''; + display: block; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + background-color: inherit; + border-radius: inherit; + -webkit-transition: opacity .3s, -webkit-transform .3s; + transition: opacity .3s, -webkit-transform .3s; + transition: opacity .3s, transform .3s; + transition: opacity .3s, transform .3s, -webkit-transform .3s; + -webkit-animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite; + animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite; + z-index: -1; +} + +@-webkit-keyframes pulse-animation { + 0% { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } + 50% { + opacity: 0; + -webkit-transform: scale(1.5); + transform: scale(1.5); + } + 100% { + opacity: 0; + -webkit-transform: scale(1.5); + transform: scale(1.5); + } +} + +@keyframes pulse-animation { + 0% { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } + 50% { + opacity: 0; + -webkit-transform: scale(1.5); + transform: scale(1.5); + } + 100% { + opacity: 0; + -webkit-transform: scale(1.5); + transform: scale(1.5); + } +} .white-background { background-color: #FFF; } diff --git a/themes/default/public/js/lufi-up.js b/themes/default/public/js/lufi-up.js index 0a4d3b7..67f86bb 100644 --- a/themes/default/public/js/lufi-up.js +++ b/themes/default/public/js/lufi-up.js @@ -1,10 +1,16 @@ // vim:set sw=4 ts=4 sts=4 ft=javascript expandtab: +// total file counter window.fc = 0; +// Cancelled files indexes +window.cancelled = []; // Set websocket window.ws = spawnWebsocket(0, function() {return null;}); // Use slice of 2MB window.sliceLength = 2000000; +// Global zip objects for currently created zip file +window.zip = null; +window.zipSize = 0; // Copy a link to clipboard function copyToClipboard(txt) { @@ -78,7 +84,7 @@ function destroyBlock(el) { var l = $('#results li'); if (a.length === 0) { $('#misc').empty(); - if (l.length === 0) { + if (l.length === 0 && window.fileList === null) { $('#results').hide(); } } else { @@ -86,6 +92,86 @@ function destroyBlock(el) { } } +// When clicking on del at first view checkbox +function firstViewClicking() { + if ($('#first-view').attr('data-checked') && $('#first-view').attr('data-checked') === 'data-checked') { + $('#first-view').attr('data-checked', null); + } else { + $('#first-view').attr('data-checked', 'data-checked'); + } +} + +// When clicking on zip checkbox +function zipClicking () { + if ($('#zip-files').attr('data-checked') && $('#zip-files').attr('data-checked') === 'data-checked') { + window.zipSize = 0; + window.zip = null; + $('#zip-files').attr('data-checked', null); + $('#zipname').val('documents.zip'); + $('#zipname-input').addClass('hide'); + $('#zipping').addClass('hide'); + $('#zip-parts').html(''); + $('#delete-day').attr('disabled', null); + $('#first-view').attr('disabled', null); + } else { + $('#zip-files').attr('data-checked', 'data-checked'); + $('#zipname-input').removeClass('hide'); + $('#zip-size').text(filesize(window.zipSize)); + } +} + +// Get the zip file name +function getZipname() { + var zipname = $('#zipname').val(); + if (zipname === '') { + zipname = 'documents.zip'; + } + if (!zipname.endsWith('.zip')) { + if (zipname.endsWith('.')) { + zipname += 'zip'; + } else { + zipname += '.zip'; + } + } + + return zipname; +} + +// Update the zip name +function updateZipname() { + $('#zip-name').text(getZipname()); +} + +// Create blob from zip +function uploadZip(e) { + e.preventDefault(); + var delay = $('#delete-day'); + var del_at_first_view = $('#first-view'); + $('#zip-files').attr('disabled', 'disabled'); + + $('#zip-compressing').removeClass('hide'); + window.zip.generateAsync({type:"blob"}) + .then(function(zipFile) { + // if $('#zipping') is hidden, the zipping has been aborted + if (!$('#zipping').hasClass('hide')) { + $('#zipping').addClass('hide'); + $('#zipname-input').addClass('hide'); + $('#zip-compressing').addClass('hide'); + $('#results').show(); + + var zipname = getZipname(); + var file = new File([zipFile], zipname, {type: 'application/zip'}); + + if (window.fileList === undefined || window.fileList === null) { + window.fileList = [file]; + uploadFile(0, delay.val(), del_at_first_view.is(':checked')); + } else { + window.fileList.push(file); + } + } + }); +} + // Update the mail link function updateMailLink() { var a = $('.link-input'); @@ -105,29 +191,33 @@ function handleFiles(f) { var del_at_first_view = $('#first-view'); delay.attr('disabled', 'disabled'); - zip_files.attr('disabled', 'disabled'); del_at_first_view.attr('disabled', 'disabled'); if (zip_files.is(':checked')) { - var zip = new JSZip(); - $('#zipping').show(); - for (var i = 0; i < f.length; i++) { - var element = f.item(i); - zip.file(element.name, element); + if (window.zip === null) { + window.zip = new JSZip(); } - zip.generateAsync({type:"blob"}) - .then(function(zipFile) { - $('#zipping').hide(); - $('#results').show(); - var file = new File([zipFile], 'documents.zip', {type: 'application/zip'}); + $('#zipping').removeClass('hide'); + for (var i = 0; i < f.length; i++) { + var element = f.item(i); + var filename = element.name; + var origname = filename; + var counter = 0; + while (typeof(window.zip.files[filename]) !== 'undefined') { + counter += 1; + filename = origname.substring(0, origname.lastIndexOf('.')) + '_(' + counter + ')' + origname.substring(origname.lastIndexOf('.')); + } - if (window.fileList === undefined || window.fileList === null) { - window.fileList = [file]; - uploadFile(0, delay.val(), del_at_first_view.is(':checked')); - } else { - window.fileList.push(file); - } - }); + window.zip.file(filename, element); + + window.zipSize += element.size; + $('#zip-size').text(filesize(window.zipSize)); + $('#zip-parts').append([ + '
  • ', + '— ', filename, ' (', filesize(element.size), ')', + '
  • ' + ].join('')); + } } else { if (window.fileList === undefined || window.fileList === null) { window.fileList = Array.prototype.slice.call(f); @@ -183,198 +273,256 @@ function uploadFile(i, delay, del_at_first_view) { r.prepend(w); $('#destroy-'+window.fc).on('click', function(event) { event.preventDefault(); - destroyBlock(this) + window.cancelled.push(i); + destroyBlock(this); }); - sliceAndUpload(randomkey, i, parts, 0, delay, del_at_first_view, null); + sliceAndUpload(randomkey, i, parts, 0, delay, del_at_first_view, null, null); } // Get a slice of file and send it -function sliceAndUpload(randomkey, i, parts, j, delay, del_at_first_view, short) { - var file = window.fileList[i]; - var slice = file.slice(j * window.sliceLength, (j + 1) * window.sliceLength, file.type); - var fr = new FileReader(); - fr.onloadend = function() { - var sl = $('#parts-'+window.fc); - - // Get the binary result, different result in IE browsers (see default.html.ep line 27:48) - if (isIE == true){ - var bin = fr.content; - } else { - var bin = fr.result; - } - - // Transform it in base64 - var b = window.btoa(bin); - - // Encrypt it - sl.html(i18n.encrypting.replace(/XX1(.*)XX2/, (j+1)+'$1'+parts)); - var encrypted = sjcl.encrypt(randomkey, b); - - // Prepare json - var data = { - // number of parts - total: parts, - // part X of total - part: j, - size: file.size, - name: file.name, - type: file.type, - delay: delay, - del_at_first_view: del_at_first_view, - zipped: $('#zip-files').is(':checked'), +function sliceAndUpload(randomkey, i, parts, j, delay, del_at_first_view, short, mod_token) { + if (mod_token !== null && window.cancelled.includes(i)) { + var data = JSON.stringify({ id: short, - // number of the sent file in the queue + mod_token: mod_token, + cancel: true, i: i - }; - if ($('#file_pwd').length === 1) { - var pwd = $('#file_pwd').val(); - if (pwd !== undefined && pwd !== null && pwd !== '') { - data['file_pwd'] = $('#file_pwd').val(); - } - } - data = JSON.stringify(data); - - console.log('sending slice '+(j + 1)+'/'+parts+' of file '+file.name); - - sl.html(i18n.sending.replace(/XX1(.*)XX2/, (j+1)+'$1'+parts)); - + })+'XXMOJOXXuseless'; // Verify that we have a websocket and send json if (window.ws.readyState === 3) { window.ws = spawnWebsocket(0, function() { - window.ws.send(data+'XXMOJOXX'+JSON.stringify(encrypted)); + window.ws.send(data); }); } else { window.ws.onclose = function() { console.log('Websocket closed, waiting 10sec.'); - window.ws = spawnWebsocket(0, function() { - console.log('sending again slice '+(j + 1)+'/'+parts+' of file '+file.name); - window.ws.send(data+'XXMOJOXX'+JSON.stringify(encrypted)); - }); + window.ws = spawnWebsocket(0, function() {return null;}); }; window.ws.onerror = function() { console.log('Error on Websocket, waiting 10sec.'); - window.ws = spawnWebsocket(0, function() { - console.log('sending again slice '+(j + 1)+'/'+parts+' of file '+file.name); - window.ws.send(data+'XXMOJOXX'+JSON.stringify(encrypted)); - }); + window.ws = spawnWebsocket(0, function() {return null;}); }; - window.ws.send(data+'XXMOJOXX'+JSON.stringify(encrypted)); + window.ws.send(data); } + } else { + var file = window.fileList[i]; + var slice = file.slice(j * window.sliceLength, (j + 1) * window.sliceLength, file.type); + var fr = new FileReader(); + fr.onloadend = function() { + var sl = $('#parts-'+window.fc); + + // Get the binary result, different result in IE browsers (see default.html.ep line 27:48) + if (isIE == true){ + var bin = fr.content; + } else { + var bin = fr.result; + } + + // Transform it in base64 + var b = window.btoa(bin); + + // Encrypt it + sl.html(i18n.encrypting.replace(/XX1(.*)XX2/, (j+1)+'$1'+parts)); + var encrypted = sjcl.encrypt(randomkey, b); + + // Prepare json + var data = { + // number of parts + total: parts, + // part X of total + part: j, + size: file.size, + name: file.name, + type: file.type, + delay: delay, + del_at_first_view: del_at_first_view, + zipped: $('#zip-files').is(':checked'), + id: short, + // number of the sent file in the queue + i: i + }; + if ($('#file_pwd').length === 1) { + var pwd = $('#file_pwd').val(); + if (pwd !== undefined && pwd !== null && pwd !== '') { + data['file_pwd'] = $('#file_pwd').val(); + } + } + data = JSON.stringify(data)+'XXMOJOXX'+JSON.stringify(encrypted);; + + console.log('sending slice '+(j + 1)+'/'+parts+' of file '+file.name); + + sl.html(i18n.sending.replace(/XX1(.*)XX2/, (j+1)+'$1'+parts)); + + // Verify that we have a websocket and send json + if (window.ws.readyState === 3) { + window.ws = spawnWebsocket(0, function() { + window.ws.send(data); + }); + } else { + window.ws.onclose = function() { + console.log('Websocket closed, waiting 10sec.'); + window.ws = spawnWebsocket(0, function() { + console.log('sending again slice '+(j + 1)+'/'+parts+' of file '+file.name); + window.ws.send(data); + }); + }; + window.ws.onerror = function() { + console.log('Error on Websocket, waiting 10sec.'); + window.ws = spawnWebsocket(0, function() { + console.log('sending again slice '+(j + 1)+'/'+parts+' of file '+file.name); + window.ws.send(data); + }); + }; + window.ws.send(data); + } + } + fr.readAsBinaryString(slice); } - fr.readAsBinaryString(slice); } // Update the progress bar function updateProgressBar(data) { - var i = data.i; - var sent_delay = data.sent_delay; - var del_at_first_view = data.del_at_first_view; - if (data.success) { - var j = data.j; - var delay = data.delay; - var parts = data.parts; - var short = data.short; - var created_at = data.created_at; - - console.log('getting response for slice '+(j + 1)+'/'+parts+' of file '+data.name+' ('+data.duration+' sec)'); - - var dp = $('#progress-'+window.fc); - var key = dp.attr('data-key'); - - if (j + 1 === parts) { - // - window.ws.onclose = function() { - console.log('Connection is closed.'); - }; - window.ws.onerror = function() { - console.log('Error on WebSocket connection but file has been fully send, so we don\'t care.'); - } - - $('#parts-'+window.fc).remove(); - var n = $('#name-'+window.fc); - var s = $('#size-'+window.fc); - var d = $('
    '); - var url = baseURL+'r/'+short+'#'+key; - var del_url = actionURL+'d/'+short+'/'+data.token; - var links = encodeURIComponent('["'+short+'"]'); - var limit = (delay === 0) ? i18n.noLimit : i18n.expiration+' '+moment.unix(delay * 86400 + created_at).locale(window.navigator.language).format('LLLL'); - n.html(n.html()+' '+s.html()+'
    '+limit); - d.html(['
    ', - '
    ', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '
    ', - '
    ', - '', - '', - '', - '', - '', - '
    ', - '
    '].join('')); - s.remove(); - - var p2 = dp.parent(); - var p1 = p2.parent(); - - p2.remove(); - p1.append(d); - - $('#copyurl-'+window.fc).on('click', function(e) { - e.preventDefault(); - copyToClipboard(url); - }); - $("input[type='text']").on("click", function () { - $(this).select(); - }); - // Add copy all and mailto buttons - var misc = $('#misc'); - if (misc.html() === '') { - misc.html(''+i18n.copyAll+' '+i18n.mailTo+''); - $('#copyall').on('click', copyAllToClipboard); - } else { - updateMailLink(); - } - - // Add the file to localStorage - addItem(data.name, url, data.size, del_at_first_view, created_at, delay, data.short, data.token); - - // Upload next file - window.fc++; - i++; - if (i < window.fileList.length) { - uploadFile(i, sent_delay, del_at_first_view); - } else { - // We have finished - window.fileList = null; - window.onbeforeunload = null; - $('#zip-files').attr('disabled', null); - $('#delete-day').attr('disabled', null); - $('#first-view').attr('disabled', null); - } + if (typeof(data.action) !== 'undefined' && data.action === 'cancel') { + if (data.success) { + console.log('Upload successfully cancelled'); } else { - j++; - // Update progress bar - var percent = Math.round(100 * j/parts); - dp.removeClass(); - dp.addClass('determinate'); - dp.addClass('width-'+percent); - dp.attr('aria-valuenow', percent); + console.log('Upload cancellation failed: ' + data.msg); + } + + // Remove the cancelled index + window.cancelled.splice(window.cancelled.indexOf(window.fc), 1); + + // Upload next file + window.fc++; + data.i++; + if (data.i < window.fileList.length) { + uploadFile(data.i, $('#delete-day').val(), $('#first-view').is(':checked')); + } else { + // We have finished + window.cancelled = []; + window.fileList = null; + window.onbeforeunload = null; + $('#delete-day').attr('disabled', null); + $('#first-view').attr('disabled', null); + if ($('#zip-files').is(':checked')) { + $('label[for="zip-files"]').click(); + } - // Encrypt and upload next slice - sliceAndUpload(key, i, parts, j, delay, del_at_first_view, short); } } else { - addAlertOnFile(data.msg, i, delay, del_at_first_view); + var i = data.i; + var sent_delay = data.sent_delay; + var del_at_first_view = data.del_at_first_view; + if (data.success) { + var j = data.j; + var delay = data.delay; + var parts = data.parts; + var short = data.short; + var created_at = data.created_at; + + console.log('getting response for slice '+(j + 1)+'/'+parts+' of file '+data.name+' ('+data.duration+' sec)'); + + var dp = $('#progress-'+window.fc); + var key = dp.attr('data-key'); + + if (j + 1 === parts) { + // + window.ws.onclose = function() { + console.log('Connection is closed.'); + }; + window.ws.onerror = function() { + console.log('Error on WebSocket connection but file has been fully send, so we don\'t care.'); + } + + $('#parts-'+window.fc).remove(); + var n = $('#name-'+window.fc); + var s = $('#size-'+window.fc); + var d = $('
    '); + var url = baseURL+'r/'+short+'#'+key; + var del_url = actionURL+'d/'+short+'/'+data.token; + var links = encodeURIComponent('["'+short+'"]'); + var limit = (delay === 0) ? i18n.noLimit : i18n.expiration+' '+moment.unix(delay * 86400 + created_at).locale(window.navigator.language).format('LLLL'); + n.html(n.html()+' '+s.html()+'
    '+limit); + d.html(['
    ', + '
    ', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '
    ', + '
    ', + '', + '', + '', + '', + '', + '
    ', + '
    '].join('')); + s.remove(); + + var p2 = dp.parent(); + var p1 = p2.parent(); + + p2.remove(); + p1.append(d); + + $('#copyurl-'+window.fc).on('click', function(e) { + e.preventDefault(); + copyToClipboard(url); + }); + $("input[type='text']").on("click", function () { + $(this).select(); + }); + // Add copy all and mailto buttons + var misc = $('#misc'); + if (misc.html() === '') { + misc.html(''+i18n.copyAll+' '+i18n.mailTo+''); + $('#copyall').on('click', copyAllToClipboard); + } else { + updateMailLink(); + } + + // Add the file to localStorage + addItem(data.name, url, data.size, del_at_first_view, created_at, delay, data.short, data.token); + + // Upload next file + window.fc++; + i++; + if (i < window.fileList.length) { + uploadFile(i, sent_delay, del_at_first_view); + } else { + // We have finished + window.fileList = null; + window.onbeforeunload = null; + $('#delete-day').attr('disabled', null); + $('#first-view').attr('disabled', null); + if ($('#zip-files').is(':checked')) { + $('label[for="zip-files"]').click(); + } + + } + } else { + j++; + // Update progress bar + var percent = Math.round(100 * j/parts); + dp.removeClass(); + dp.addClass('determinate'); + dp.addClass('width-'+percent); + dp.attr('aria-valuenow', percent); + + // Encrypt and upload next slice + sliceAndUpload(key, i, parts, j, delay, del_at_first_view, short, data.token); + } + } else { + addAlertOnFile(data.msg, i, delay, del_at_first_view); + } } } @@ -463,7 +611,10 @@ function bindDropZone() { } // When it's ready -$(document).ready(function(){ +$(document).ready(function() { + $('#zip-files').prop('checked', false); + $('#first-view').prop('checked', false); + $('#zipname').val('documents.zip'); if (!sjcl.random.isReady(10)) { var loop = setInterval(function() { if (!sjcl.random.isReady(10)) { @@ -480,18 +631,12 @@ $(document).ready(function(){ if (maxSize > 0) { $('#max-file-size').text(i18n.maxSize.replace('XXX', filesize(maxSize))); } - $('label[for="first-view"]').on('click', function(){ - if ($('#first-view').attr('data-checked') && $('#first-view').attr('data-checked') === 'data-checked') { - $('#first-view').attr('data-checked', null); - } else { - $('#first-view').attr('data-checked', 'data-checked'); - } - }); - $('label[for="zip-files"]').on('click', function(){ - if ($('#zip-files').attr('data-checked') && $('#zip-files').attr('data-checked') === 'data-checked') { - $('#zip-files').attr('data-checked', null); - } else { - $('#zip-files').attr('data-checked', 'data-checked'); - } + $('label[for="first-view"]').on('click', firstViewClicking); + $('label[for="zip-files"]').on('click', zipClicking); + $('#zipname').on('input', updateZipname); + $('#uploadZip').on('click', uploadZip); + $('#reset-zipping').on('click', function() { + window.zip = null; + $('label[for="zip-files"]').click(); }); }); diff --git a/themes/default/templates/index.html.ep b/themes/default/templates/index.html.ep index 7de6bae..ae47fcf 100644 --- a/themes/default/templates/index.html.ep +++ b/themes/default/templates/index.html.ep @@ -99,6 +99,17 @@
    % } +
    +
    +
    + + +
    +
    + +

    <%= l('Drop files here') %>

    @@ -109,7 +120,24 @@
    -

    <%= l('Zip archive creation…') %>

    +
    +
    +
    + + + +
    + documents.zip () +

    + + <%= l('Compressing zip file…') %> +

    +
      +
    +
    +
    +
    +

    <%= l('Uploaded files') %>