diff --git a/www/common/media-tag.js b/www/common/media-tag.js index 27683c54e..1ba9a1f53 100644 --- a/www/common/media-tag.js +++ b/www/common/media-tag.js @@ -127,16 +127,27 @@ // Download a blob from href - var download = function (src, _cb) { + var download = function (src, _cb, progressCb) { var cb = function (e, res) { _cb(e, res); cb = function () {}; }; + var progress = function (offset) { + progressCb(offset * 100); + }; + var xhr = new XMLHttpRequest(); xhr.open('GET', src, true); xhr.responseType = 'arraybuffer'; + xhr.addEventListener("progress", function (evt) { + if (evt.lengthComputable) { + var percentComplete = evt.loaded / evt.total; + progress(percentComplete); + } + }, false); + xhr.onerror = function () { return void cb("XHR_ERROR"); }; xhr.onload = function () { // Error? @@ -453,9 +464,13 @@ end(u8Decrypted); }, function (progress) { emit('progress', { - progress: progress + progress: 50+0.5*progress }); }); + }, function (progress) { + emit('progress', { + progress: 0.5*progress + }); }); return mediaObject; diff --git a/www/file/app-file.less b/www/file/app-file.less index 4ac94ca33..d6e8ad69c 100644 --- a/www/file/app-file.less +++ b/www/file/app-file.less @@ -64,7 +64,49 @@ } } - #cp-app-file-upload-form, #cp-app-file-download-form { + #cp-app-file-download-form { + padding: 0px; + margin: 0px; + + position: relative; + display: block; + max-width: 90vw; + height: 150px; + width: ~"min(90vw, 600px)"; + .cp-app-file-progress-container { + margin-top: 5px; + height: 40px; + font-size: 20px; + border: 1px solid @colortheme_logo-2; + background: white; + color: @cryptpad_text_col; + display: flex; + justify-content: space-between; + position: relative; + .cp-app-file-progress-dl { + border-right: 1px solid @cryptpad_text_col; + } + .cp-app-file-progress-dl, .cp-app-file-progress-dc { + width: 50%; + display: inline-flex; + align-items: center; + justify-content: center; + z-index: 2; + } + .cp-app-file-progress { + z-index: 1; + position: absolute; + top: 0; + left: 0; + bottom: 0; + background: @colortheme_logo-2; + } + } + .cp-app-file-progress-txt { + margin-left: 30px; + } + } + #cp-app-file-upload-form { padding: 0px; margin: 0px; @@ -159,4 +201,4 @@ } } -} \ No newline at end of file +} diff --git a/www/file/inner.html b/www/file/inner.html index d474ee117..a3e5070e4 100644 --- a/www/file/inner.html +++ b/www/file/inner.html @@ -16,11 +16,7 @@ -
+ diff --git a/www/file/inner.js b/www/file/inner.js index b2aef53ed..8b3f12682 100644 --- a/www/file/inner.js +++ b/www/file/inner.js @@ -8,6 +8,7 @@ define([ '/common/common-util.js', '/common/common-hash.js', '/common/common-interface.js', + '/common/hyperscript.js', '/customize/messages.js', '/file/file-crypto.js', @@ -29,6 +30,7 @@ define([ Util, Hash, UI, + h, Messages, FileCrypto, MediaTag) @@ -47,8 +49,6 @@ define([ var $dlform = $('#cp-app-file-download-form'); var $dlview = $('#cp-app-file-download-view'); var $label = $form.find('label'); - var $dllabel = $dlform.find('label span'); - var $progress = $('#cp-app-file-dlprogress'); var $bar = $('.cp-toolbar-container'); var $body = $('body'); @@ -88,142 +88,172 @@ define([ var toolbar = APP.toolbar = Toolbar.create(configTb); if (!uploadMode) { - var hexFileName = secret.channel; - var src = fileHost + Hash.getBlobPathFromHex(hexFileName); - var key = secret.keys && secret.keys.cryptKey; - var cryptKey = Nacl.util.encodeBase64(key); - - FileCrypto.fetchDecryptedMetadata(src, key, function (e, metadata) { - if (e) { - if (e === 'XHR_ERROR') { - return void UI.errorLoadingScreen(Messages.download_resourceNotAvailable, false, function () { - common.gotoURL('/file/'); - }); + (function () { + Messages.download = "Download"; // XXX + Messages.decrypt = "Decrypt"; // XXX + + var progress = h('div.cp-app-file-progress'); + var progressTxt = h('span.cp-app-file-progress-txt'); + var $progress = $(progress); + var $progressTxt = $(progressTxt); + var downloadEl = h('span.cp-app-file-progress-dl', Messages.download); + var decryptEl = h('span.cp-app-file-progress-dc', Messages.decrypt); + var progressContainer = h('div.cp-app-file-progress-container', [ + downloadEl, + decryptEl, + progress + ]); + + var hexFileName = secret.channel; + var src = fileHost + Hash.getBlobPathFromHex(hexFileName); + var key = secret.keys && secret.keys.cryptKey; + var cryptKey = Nacl.util.encodeBase64(key); + + FileCrypto.fetchDecryptedMetadata(src, key, function (e, metadata) { + if (e) { + if (e === 'XHR_ERROR') { + return void UI.errorLoadingScreen(Messages.download_resourceNotAvailable, false, function () { + common.gotoURL('/file/'); + }); + } + return void console.error(e); } - return void console.error(e); - } - - // Add pad attributes when the file is saved in the drive - Title.onTitleChange(function () { - var owners = metadata.owners; - if (owners) { common.setPadAttribute('owners', owners); } - common.setPadAttribute('fileType', metadata.type); - }); - $(document).on('cpPadStored', function () { - var owners = metadata.owners; - if (owners) { common.setPadAttribute('owners', owners); } - common.setPadAttribute('fileType', metadata.type); - }); - - // Save to the drive or update the acces time - var title = document.title = metadata.name; - Title.updateTitle(title || Title.defaultTitle); - - var owners = metadata.owners; - if (owners) { - common.setPadAttribute('owners', owners); - } - if (metadata.type) { - common.setPadAttribute('fileType', metadata.type); - } - - toolbar.addElement(['pageTitle'], { - pageTitle: title, - title: Title.getTitleConfig(), - }); - toolbar.$drawer.append(common.createButton('forget', true)); - toolbar.$drawer.append(common.createButton('properties', true)); - if (common.isLoggedIn()) { - toolbar.$drawer.append(common.createButton('hashtag', true)); - } - toolbar.$file.show(); - - var displayFile = function (ev, sizeMb, CB) { - var called_back; - var cb = function (e) { - if (called_back) { return; } - called_back = true; - if (CB) { CB(e); } - }; - var $mt = $dlview.find('media-tag'); - $mt.attr('src', src); - $mt.attr('data-crypto-key', 'cryptpad:'+cryptKey); + // Add pad attributes when the file is saved in the drive + Title.onTitleChange(function () { + var owners = metadata.owners; + if (owners) { common.setPadAttribute('owners', owners); } + common.setPadAttribute('fileType', metadata.type); + }); + $(document).on('cpPadStored', function () { + var owners = metadata.owners; + if (owners) { common.setPadAttribute('owners', owners); } + common.setPadAttribute('fileType', metadata.type); + }); - var rightsideDisplayed = false; + // Save to the drive or update the acces time + var title = document.title = metadata.name; + Title.updateTitle(title || Title.defaultTitle); - MediaTag($mt[0]).on('complete', function (decrypted) { - $dlview.show(); - $dlform.hide(); - var $dlButton = $dlview.find('media-tag button'); - if (ev) { $dlButton.click(); } + var owners = metadata.owners; + if (owners) { + common.setPadAttribute('owners', owners); + } + if (metadata.type) { + common.setPadAttribute('fileType', metadata.type); + } - if (!rightsideDisplayed) { - toolbar.$drawer - .append(common.createButton('export', true, {}, function () { - saveAs(decrypted.content, decrypted.metadata.name); - })); - rightsideDisplayed = true; - } + toolbar.addElement(['pageTitle'], { + pageTitle: title, + title: Title.getTitleConfig(), + }); + toolbar.$drawer.append(common.createButton('forget', true)); + toolbar.$drawer.append(common.createButton('properties', true)); + if (common.isLoggedIn()) { + toolbar.$drawer.append(common.createButton('hashtag', true)); + } + toolbar.$file.show(); + + var displayFile = function (ev, sizeMb, CB) { + var called_back; + var cb = function (e) { + if (called_back) { return; } + called_back = true; + if (CB) { CB(e); } + }; + + var $mt = $dlview.find('media-tag'); + $mt.attr('src', src); + $mt.attr('data-crypto-key', 'cryptpad:'+cryptKey); + + var rightsideDisplayed = false; + + MediaTag($mt[0]).on('complete', function (decrypted) { + $dlview.show(); + $dlform.hide(); + var $dlButton = $dlview.find('media-tag button'); + if (ev) { $dlButton.click(); } + + if (!rightsideDisplayed) { + toolbar.$drawer + .append(common.createButton('export', true, {}, function () { + saveAs(decrypted.content, decrypted.metadata.name); + })); + rightsideDisplayed = true; + } + + // make pdfs big + var toolbarHeight = $('#cp-toolbar').height(); + var $another_iframe = $('media-tag iframe').css({ + 'height': 'calc(100vh - ' + toolbarHeight + 'px)', + 'width': '100vw', + 'position': 'absolute', + 'bottom': 0, + 'left': 0, + 'border': 0 + }); - // make pdfs big - var toolbarHeight = $('#cp-toolbar').height(); - var $another_iframe = $('media-tag iframe').css({ - 'height': 'calc(100vh - ' + toolbarHeight + 'px)', - 'width': '100vw', - 'position': 'absolute', - 'bottom': 0, - 'left': 0, - 'border': 0 + if ($another_iframe.length) { + $another_iframe.load(function () { + cb(); + }); + } else { + cb(); + } + }).on('progress', function (data) { + if (data.progress > 75) { return; } + var p = data.progress +'%'; + $progress.width(p); + $progressTxt.text(Math.floor(data.progress) + '%'); + }).on('error', function (err) { + console.error(err); }); + }; - if ($another_iframe.length) { - $another_iframe.load(function () { - cb(); + // XXX Update "download_button" key to use "download" first and "decrypt" second + var todoBigFile = function (sizeMb) { + $dlform.show(); + UI.removeLoadingScreen(); + var button = h('button.btn.btn-primary', { + title: Messages.download_button + }, Messages.download_button); + $dlform.append([ + h('h2', Util.fixHTML(metadata.name)), + h('div.cp-button-container', [ + button, + progressTxt + ]), + ]); + + // don't display the size if you don't know it. + if (typeof(sizeMb) === 'number') { + $dlform.find('h2').append(' - ' + + Messages._getKey('formattedMB', [sizeMb])); + } + var decrypting = false; + var onClick = function (ev) { + if (decrypting) { return; } + decrypting = true; + $(button).prop('disabled', 'disabled'); + $dlform.append(progressContainer); + displayFile(ev, sizeMb, function (err) { + $appContainer.css('background-color', + common.getAppConfig().appBackgroundColor); + if (err) { UI.alert(err); } }); - } else { - cb(); + }; + if (typeof(sizeMb) === 'number' && sizeMb < 5) { return void onClick(); } + $(button).click(onClick); + }; + common.getFileSize(hexFileName, function (e, data) { + if (e) { + return void UI.errorLoadingScreen(e); } - }).on('progress', function (data) { - var p = data.progress +'%'; - $progress.width(p); - }).on('error', function (err) { - console.error(err); + var size = Util.bytesToMegabytes(data); + return void todoBigFile(size); }); - }; - - var todoBigFile = function (sizeMb) { - $dlform.show(); - UI.removeLoadingScreen(); - $dllabel.append($('