Deduplicate code between File and MediaTag

pull/1/head
yflory 4 years ago
parent 1c4ddf6e7b
commit 43ad4f0a84

@ -64,26 +64,7 @@
} }
} }
.markdown_cryptpad() { .mediatag_cryptpad() {
word-wrap: break-word;
h1, h2, h3, h4, h5, h6 {
font-weight: bold;
padding-bottom: 0.3em;
border-bottom: 1px solid #eee;
}
li {
min-height: 22px;
}
.todo-list-item {
list-style: none;
position: relative;
.fa {
position: absolute;
margin-left: -17px;
margin-top: 4px;
}
}
media-tag { media-tag {
cursor: pointer; cursor: pointer;
* { * {
@ -126,6 +107,30 @@
display: inline-block; display: inline-block;
border: 1px solid #BBB; border: 1px solid #BBB;
} }
}
.markdown_cryptpad() {
word-wrap: break-word;
h1, h2, h3, h4, h5, h6 {
font-weight: bold;
padding-bottom: 0.3em;
border-bottom: 1px solid #eee;
}
li {
min-height: 22px;
}
.todo-list-item {
list-style: none;
position: relative;
.fa {
position: absolute;
margin-left: -17px;
margin-top: 4px;
}
}
.mediatag_cryptpad();
pre.markmap { pre.markmap {
border: 1px solid #ddd; border: 1px solid #ddd;

@ -1,6 +1,7 @@
@import (reference) "./colortheme-all.less"; @import (reference) "./colortheme-all.less";
@import (reference) "./variables.less"; @import (reference) "./variables.less";
@import (reference) "./browser.less"; @import (reference) "./browser.less";
@import (reference) "./markdown.less";
.modals-ui-elements_main() { .modals-ui-elements_main() {
--LessLoader_require: LessLoader_currentFile(); --LessLoader_require: LessLoader_currentFile();
@ -214,6 +215,7 @@
flex: 1; flex: 1;
min-width: 0; min-width: 0;
overflow: auto; overflow: auto;
.mediatag_cryptpad();
media-tag { media-tag {
& > * { & > * {
max-width: 100%; max-width: 100%;

@ -3,9 +3,9 @@ define([
'/common/common-util.js', '/common/common-util.js',
'/common/visible.js', '/common/visible.js',
'/common/common-hash.js', '/common/common-hash.js',
'/file/file-crypto.js', '/common/media-tag.js',
'/bower_components/tweetnacl/nacl-fast.min.js', '/bower_components/tweetnacl/nacl-fast.min.js',
], function ($, Util, Visible, Hash, FileCrypto) { ], function ($, Util, Visible, Hash, MediaTag) {
var Nacl = window.nacl; var Nacl = window.nacl;
var Thumb = { var Thumb = {
dimension: 100, dimension: 100,
@ -314,7 +314,7 @@ define([
var hexFileName = secret.channel; var hexFileName = secret.channel;
var src = fileHost + Hash.getBlobPathFromHex(hexFileName); var src = fileHost + Hash.getBlobPathFromHex(hexFileName);
var key = secret.keys && secret.keys.cryptKey; var key = secret.keys && secret.keys.cryptKey;
FileCrypto.fetchDecryptedMetadata(src, key, function (e, metadata) { MediaTag.fetchDecryptedMetadata(src, key, function (e, metadata) {
if (e) { if (e) {
if (e === 'XHR_ERROR') { return; } if (e === 'XHR_ERROR') { return; }
return console.error(e); return console.error(e);

@ -125,7 +125,6 @@ var factory = function () {
}; };
var makeProgressBar = function (cfg, mediaObject) { var makeProgressBar = function (cfg, mediaObject) {
// XXX CSP: we'll need to add style in cryptpad's less
if (mediaObject.bar) { return; } if (mediaObject.bar) { return; }
mediaObject.bar = true; mediaObject.bar = true;
var style = (function(){/* var style = (function(){/*
@ -151,10 +150,10 @@ var factory = function () {
} }
.mediatag-progress-text { .mediatag-progress-text {
height: 25px; height: 25px;
width: 50px;
margin-left: 5px; margin-left: 5px;
line-height: 25px; line-height: 25px;
vertical-align: top; vertical-align: top;
width: auto;
display: inline-block; display: inline-block;
color: #3F4141; color: #3F4141;
font-weight: bold; font-weight: bold;
@ -618,6 +617,7 @@ var factory = function () {
var handlers = cfg.handlers || { var handlers = cfg.handlers || {
'progress': [], 'progress': [],
'complete': [], 'complete': [],
'metadata': [],
'error': [] 'error': []
}; };
@ -700,8 +700,7 @@ var factory = function () {
if (errDecryption) { if (errDecryption) {
return void reject(errDecryption); return void reject(errDecryption);
} }
// XXX emit 'metadata' u8Decrypted.metadata emit('metadata', u8Decrypted.metadata);
// Cache and display the decrypted blob
resolve(u8Decrypted); resolve(u8Decrypted);
}, function (progress) { }, function (progress) {
emit('progress', { emit('progress', {
@ -736,10 +735,11 @@ var factory = function () {
var maxSize = typeof(config.maxDownloadSize) === "number" ? config.maxDownloadSize var maxSize = typeof(config.maxDownloadSize) === "number" ? config.maxDownloadSize
: (5 * 1024 * 1024); : (5 * 1024 * 1024);
fetchDecryptedMetadata(src, strKey, function (err, md) {
if (err) { return void error(err); }
cfg.metadata = md;
emit('metadata', md);
getFileSize(src, function (err, size) { getFileSize(src, function (err, size) {
if (err) {
return void error(err);
}
// If the size is smaller than the autodownload limit, load the blob. // If the size is smaller than the autodownload limit, load the blob.
// If the blob is already loaded or being loaded, don't show the button. // If the blob is already loaded or being loaded, don't show the button.
if (!size || size < maxSize || getCache()) { if (!size || size < maxSize || getCache()) {
@ -747,10 +747,6 @@ var factory = function () {
return void dl(); return void dl();
} }
var sizeMb = Math.round(10 * size / 1024 / 1024) / 10; var sizeMb = Math.round(10 * size / 1024 / 1024) / 10;
fetchDecryptedMetadata(src, strKey, function (err, md) {
if (err) { return void error(err); }
cfg.metadata = md;
// XXX emit 'metadata'
makeDownloadButton(cfg, mediaObject, sizeMb, dl); makeDownloadButton(cfg, mediaObject, sizeMb, dl);
}); });
}); });
@ -765,6 +761,8 @@ var factory = function () {
config[key] = value; config[key] = value;
}; };
init.fetchDecryptedMetadata = fetchDecryptedMetadata;
return init; return init;
}; };

@ -1,5 +1,6 @@
@import (reference) '../../customize/src/less2/include/tokenfield.less'; @import (reference) '../../customize/src/less2/include/tokenfield.less';
@import (reference) '../../customize/src/less2/include/framework.less'; @import (reference) '../../customize/src/less2/include/framework.less';
@import (reference) '../../customize/src/less2/include/markdown.less';
&.cp-app-file { &.cp-app-file {
@ -47,6 +48,7 @@
z-index: -1; z-index: -1;
} }
.mediatag_cryptpad();
media-tag { media-tag {
img { img {
max-width: 100%; max-width: 100%;
@ -198,6 +200,9 @@
max-height: 100%; max-height: 100%;
max-width: 100%; max-width: 100%;
} }
&:empty {
display: none !important;
}
} }
} }

@ -48,69 +48,6 @@ define([
return new Blob(chunks); return new Blob(chunks);
}; };
var concatBuffer = function (a, b) { // TODO make this not so ugly
return new Uint8Array(slice(a).concat(slice(b)));
};
var fetchMetadata = function (src, cb) {
var done = false;
var CB = function (err, res) {
if (done) { return; }
done = true;
cb(err, res);
};
var xhr = new XMLHttpRequest();
xhr.open("GET", src, true);
xhr.setRequestHeader('Range', 'bytes=0-1');
xhr.responseType = 'arraybuffer';
xhr.onerror= function () { return CB('XHR_ERROR'); };
xhr.onload = function () {
if (/^4/.test('' + this.status)) { return CB('XHR_ERROR'); }
var res = new Uint8Array(xhr.response);
var size = decodePrefix(res);
var xhr2 = new XMLHttpRequest();
xhr2.open("GET", src, true);
xhr2.setRequestHeader('Range', 'bytes=2-' + (size + 2));
xhr2.responseType = 'arraybuffer';
xhr2.onload = function () {
if (/^4/.test('' + this.status)) { return CB('XHR_ERROR'); }
var res2 = new Uint8Array(xhr2.response);
var all = concatBuffer(res, res2);
CB(void 0, all);
};
xhr2.send(null);
};
xhr.send(null);
};
var decryptMetadata = function (u8, key) {
var prefix = u8.subarray(0, 2);
var metadataLength = decodePrefix(prefix);
var metaBox = new Uint8Array(u8.subarray(2, 2 + metadataLength));
var metaChunk = Nacl.secretbox.open(metaBox, createNonce(), key);
try {
return JSON.parse(Nacl.util.encodeUTF8(metaChunk));
}
catch (e) { return null; }
};
var fetchDecryptedMetadata = function (src, key, cb) {
if (typeof(src) !== 'string') {
return window.setTimeout(function () {
cb('NO_SOURCE');
});
}
fetchMetadata(src, function (e, buffer) {
if (e) { return cb(e); }
cb(void 0, decryptMetadata(buffer, key));
});
};
var decrypt = function (u8, key, done, progress) { var decrypt = function (u8, key, done, progress) {
var MAX = u8.length; var MAX = u8.length;
var _progress = function (offset) { var _progress = function (offset) {
@ -268,8 +205,5 @@ define([
encrypt: encrypt, encrypt: encrypt,
joinChunks: joinChunks, joinChunks: joinChunks,
computeEncryptedSize: computeEncryptedSize, computeEncryptedSize: computeEncryptedSize,
decryptMetadata: decryptMetadata,
fetchMetadata: fetchMetadata,
fetchDecryptedMetadata: fetchDecryptedMetadata,
}; };
}); });

@ -16,7 +16,6 @@
<label for="cp-app-file-upfile" class="btn btn-primary cp-app-file-block unselectable" data-localization-title="upload_choose" <label for="cp-app-file-upfile" class="btn btn-primary cp-app-file-block unselectable" data-localization-title="upload_choose"
data-localization="upload_choose"></label> data-localization="upload_choose"></label>
</div> </div>
<div id="cp-app-file-download-form" style="display: none;"> </div>
<div id="cp-app-file-download-view" style="display: none;"> <div id="cp-app-file-download-view" style="display: none;">
<media-tag id="cp-app-file-view"></media-tag> <media-tag id="cp-app-file-view"></media-tag>
</div> </div>

@ -43,7 +43,6 @@ define([
var andThen = function (common) { var andThen = function (common) {
var $appContainer = $('#cp-app-file-content'); var $appContainer = $('#cp-app-file-content');
var $form = $('#cp-app-file-upload-form'); var $form = $('#cp-app-file-upload-form');
var $dlform = $('#cp-app-file-download-form');
var $dlview = $('#cp-app-file-download-view'); var $dlview = $('#cp-app-file-download-view');
var $label = $form.find('label'); var $label = $form.find('label');
var $bar = $('.cp-toolbar-container'); var $bar = $('.cp-toolbar-container');
@ -86,36 +85,44 @@ define([
if (!uploadMode) { if (!uploadMode) {
(function () { (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 hexFileName = secret.channel;
var src = fileHost + Hash.getBlobPathFromHex(hexFileName); var src = fileHost + Hash.getBlobPathFromHex(hexFileName);
var key = secret.keys && secret.keys.cryptKey; var key = secret.keys && secret.keys.cryptKey;
var cryptKey = Nacl.util.encodeBase64(key); var cryptKey = Nacl.util.encodeBase64(key);
FileCrypto.fetchDecryptedMetadata(src, key, function (e, metadata) { var $mt = $dlview.find('media-tag');
if (e) { $mt.attr('src', src);
if (e === 'XHR_ERROR') { $mt.attr('data-crypto-key', 'cryptpad:'+cryptKey);
return void UI.errorLoadingScreen(Messages.download_resourceNotAvailable, false, function () { $mt.css('transform', 'scale(2)');
common.gotoURL('/file/');
}); var rightsideDisplayed = false;
} var metadataReceived = false;
return void console.error(e); UI.removeLoadingScreen();
$dlview.show();
MediaTag($mt[0]).on('complete', function (decrypted) {
$mt.css('transform', '');
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();
$('media-tag iframe').css({
'height': 'calc(100vh - ' + toolbarHeight + 'px)',
'width': '100vw',
'position': 'absolute',
'bottom': 0,
'left': 0,
'border': 0
});
}).on('metadata', function (metadata) {
if (metadataReceived) { return; }
metadataReceived = true;
// Add pad attributes when the file is saved in the drive // Add pad attributes when the file is saved in the drive
Title.onTitleChange(function () { Title.onTitleChange(function () {
var owners = metadata.owners; var owners = metadata.owners;
@ -150,106 +157,11 @@ define([
toolbar.$drawer.append(common.createButton('hashtag', true)); toolbar.$drawer.append(common.createButton('hashtag', true));
} }
toolbar.$file.show(); 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], {
force: true // Download starts automatically
}).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
});
if ($another_iframe.length) {
$another_iframe.load(function () {
cb();
});
} else {
cb();
}
}).on('progress', function (data) {
var p = data.progress +'%';
$progress.width(p);
$progressTxt.text(Math.floor(data.progress) + '%');
}).on('error', function (err) { }).on('error', function (err) {
console.error(err);
});
};
// 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', $appContainer.css('background-color',
common.getAppConfig().appBackgroundColor); common.getAppConfig().appBackgroundColor);
if (err) { UI.alert(err); } UI.warn(Messages.error);
}); console.error(err);
};
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);
}
var size = Util.bytesToMegabytes(data);
return void todoBigFile(size);
});
}); });
})(); })();
return; return;

@ -478,7 +478,7 @@ define([
var list_values = slice(el.children) var list_values = slice(el.children)
.map(function (el) { return el.outerHTML; }) .map(function (el) { return el.outerHTML; })
.join(''); .join('');
mediaMap[el.getAttribute('src')] = list_values; mediaTagMap[el.getAttribute('src')] = list_values;
if (mediaObject.complete) { observer.disconnect(); } if (mediaObject.complete) { observer.disconnect(); }
} }
}); });

Loading…
Cancel
Save