From 572db0098745ff919f0d84b10d949f19248d3b60 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 1 Apr 2020 12:04:31 +0200 Subject: [PATCH] Preview multiple mediatags --- .../src/less2/include/modals-ui-elements.less | 13 ++ www/common/diffMarked.js | 13 +- www/common/drive-ui.js | 32 ++- www/common/inner/common-mediatag.js | 183 +++++++++++++----- 4 files changed, 184 insertions(+), 57 deletions(-) diff --git a/customize.dist/src/less2/include/modals-ui-elements.less b/customize.dist/src/less2/include/modals-ui-elements.less index 4a26920ab..968fa6f70 100644 --- a/customize.dist/src/less2/include/modals-ui-elements.less +++ b/customize.dist/src/less2/include/modals-ui-elements.less @@ -129,6 +129,7 @@ text-align: left; word-break: break-word; color: @cryptpad_text_col; + padding: 5px; } } .cp-spinner { @@ -136,6 +137,18 @@ border-top-color: transparent; } } + .cp-mediatag-outer { + display: flex; + height: 100%; + width: 100%; + align-items: center; + .cp-mediatag-control { + .fa { + margin: 10px; + cursor: pointer; + } + } + } } } } diff --git a/www/common/diffMarked.js b/www/common/diffMarked.js index 7268e1c87..d4fad71ea 100644 --- a/www/common/diffMarked.js +++ b/www/common/diffMarked.js @@ -289,7 +289,7 @@ define([ }; DiffMd.apply = function (newHtml, $content, common) { - var contextMenu = common.importMediaTagMenu(); + var contextMenu = common.importMediaTagMenu($content); var id = $content.attr('id'); if (!id) { throw new Error("The element must have a valid id"); } var pattern = /()<\/media-tag>/g; @@ -375,10 +375,19 @@ define([ $mt.off('dblclick'); if ($mt.find('img').length) { $mt.on('dblclick', function () { - common.getMediaTagPreview({ + var mts = [{ src: $mt.attr('src'), key: $mt.attr('data-crypto-key') + }]; + $content.find('media-tag').each(function (i, el) { + var $el = $(el); + if ($el.attr('src') === $mt.attr('src')) { return; } + mts.push({ + src: $el.attr('src'), + key: $el.attr('data-crypto-key') + }); }); + common.getMediaTagPreview(mts); }); } }); diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 482c4cf9c..adac4e353 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -1047,6 +1047,28 @@ define([ return ret; }; + var previewMediaTag = function (data) { + var mts = [{ + href: data.href, + password: data.password + }]; + $content.find('.cp-app-drive-element.cp-border-color-file').each(function (i, el) { + var path = $(el).data('path'); + var id = manager.find(path); + if (!id) { return; } + var _data = manager.getFileData(id); + if (!_data || _data.channel < 48 || _data.channel === data.channel) { return; } + mts.push({ + href: _data.href, + password: _data.password + }); + }); + common.getMediaTagPreview(mts); + }; + + // `app`: true (force open wiht the app), false (force open in preview), + // falsy (open in preview if default is not using the app) + var defaultInApp = ['application/pdf']; var openFile = function (el, isRo, app) { var data = manager.getFileData(el); if (!data || (!data.href && !data.roHref)) { @@ -1057,12 +1079,8 @@ define([ var parsed = Hash.parsePadUrl(href); if (parsed.hashData && parsed.hashData.type === 'file' && !app - && data.fileType !== "application/pdf") { - common.getMediaTagPreview({ - href: data.href, - password: data.password - }); - return; + && (defaultInApp.indexOf(data.fileType) === -1 || app === false)) { + return void previewMediaTag(data); } var priv = metadataMgr.getPrivateData(); @@ -4004,7 +4022,7 @@ define([ else if ($this.hasClass('cp-app-drive-context-preview')) { if (paths.length !== 1) { return; } el = manager.find(paths[0].path); - openFile(el); + openFile(el, null, false); } else if ($this.hasClass('cp-app-drive-context-open')) { paths.forEach(function (p) { diff --git a/www/common/inner/common-mediatag.js b/www/common/inner/common-mediatag.js index cce892290..74d54a180 100644 --- a/www/common/inner/common-mediatag.js +++ b/www/common/inner/common-mediatag.js @@ -208,38 +208,29 @@ define([ return data; }; - MT.getMediaTagPreview = function (common, config) { - config = config || {}; + MT.getMediaTagPreview = function (common, tags) { + if (!Array.isArray(tags) || !tags.length) { return; } + var i = 0; var metadataMgr = common.getMetadataMgr(); var priv = metadataMgr.getPrivateData(); - var src = config.src; - var key = config.key; - if (config.href) { - var parsed = Hash.parsePadUrl(config.href); - var secret = Hash.getSecrets(parsed.type, parsed.hash, config.password); - var host = priv.fileHost || priv.origin || ''; - src = host + Hash.getBlobPathFromHex(secret.channel); - var _key = secret.keys && secret.keys.cryptKey; - if (_key) { key = 'cryptpad:' + Nacl.util.encodeBase64(_key); } - } - if (!src || !key) { return void UI.log(Messages.error); } - - var tag = h('media-tag', { - src: src, - 'data-crypto-key': key - }); + var left, right; var $modal = UI.createModal({ id: 'cp-mediatag-preview-modal', $body: $('body') }).show().focus(); - - var $container = $modal.find('.cp-modal').append(h('div.cp-mediatag-container', [ - h('div.cp-loading-spinner-container', h('span.cp-spinner')), - tag + var $container = $modal.find('.cp-modal').append(h('div.cp-mediatag-outer', [ + h('div.cp-mediatag-control', left = h('span.fa.fa-chevron-left')), + h('div.cp-mediatag-container', [ + h('div.cp-loading-spinner-container', h('span.cp-spinner')), + ]), + h('div.cp-mediatag-control', right = h('span.fa.fa-chevron-right')), ])); + var $left = $(left); + var $right = $(right); + var $inner = $container.find('.cp-mediatag-container'); var el; var checkSize = function () { @@ -255,37 +246,124 @@ define([ $container.find('.cp-mediatag-container').css('height', 'auto'); } }; - var observer = new MutationObserver(function(mutations) { - mutations.forEach(function(mutation) { - $container.find('.cp-loading-spinner-container').remove(); - if (mutation.addedNodes.length === 1) { - el = mutation.addedNodes[0]; - if (el.readyState === 0) { - // Wait for the video to be ready before checking the size - el.onloadedmetadata = checkSize; - return; - } - if (el.complete === false) { - el.onload = checkSize; - return; + + var $spinner = $container.find('.cp-loading-spinner-container'); + + var locked = false; + var show = function (_i) { + if (locked) { return; } + locked = true; + if (_i < 0) { i = 0; } + else if (_i > tags.length -1) { i = tags.length - 1; } + else { i = _i; } + + // Show/hide controls + $left.css('visibility', ''); + $right.css('visibility', ''); + if (i === 0) { + $left.css('visibility', 'hidden'); + } + if (i === tags.length - 1) { + $right.css('visibility', 'hidden'); + } + + // Reset modal + $inner.find('media-tag').remove(); + $spinner.show(); + + // Check src and cryptkey + var cfg = tags[i]; + var src = cfg.src; + var key = cfg.key; + if (cfg.href) { + var parsed = Hash.parsePadUrl(cfg.href); + var secret = Hash.getSecrets(parsed.type, parsed.hash, cfg.password); + var host = priv.fileHost || priv.origin || ''; + src = host + Hash.getBlobPathFromHex(secret.channel); + var _key = secret.keys && secret.keys.cryptKey; + if (_key) { key = 'cryptpad:' + Nacl.util.encodeBase64(_key); } + } + if (!src || !key) { + locked = false; + $spinner.hide(); + // XXX show error + return void UI.log(Messages.error); + } + + var tag = h('media-tag', { + src: src, + 'data-crypto-key': key + }); + $inner.append(tag); + + var observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + locked = false; + $spinner.hide(); + if (mutation.addedNodes.length === 1) { + el = mutation.addedNodes[0]; + if (el.readyState === 0) { + // Wait for the video to be ready before checking the size + el.onloadedmetadata = checkSize; + return; + } + if (el.complete === false) { + el.onload = checkSize; + return; + } + setTimeout(checkSize); } - setTimeout(checkSize); - } + }); }); - }); - observer.observe(tag, { - attributes: false, - childList: true, - characterData: false - }); - MediaTag(tag).on('error', function () { - UI.log(Messages.error); - $modal.hide(); + observer.observe(tag, { + attributes: false, + childList: true, + characterData: false + }); + MediaTag(tag).on('error', function () { + locked = false; + $spinner.hide(); + UI.log(Messages.error); + // XXX show error + }); + }; + + show(i); + var previous = function () { + show(i - 1); + }; + var next = function () { + show(i + 1); + }; + $left.click(previous); + $right.click(next); + + $modal.on('keyup', function (e) { + //if (!Slide.shown) { return; } + e.stopPropagation(); + if (e.ctrlKey) { return; } + switch(e.which) { + case 33: // pageup + case 38: // up + case 37: // left + previous(); + break; + case 34: // pagedown + case 32: // space + case 40: // down + case 39: // right + next(); + break; + case 27: // esc + $modal.hide(); + break; + default: + } }); }; var mediatagContextMenu; - MT.importMediaTagMenu = function (common) { + MT.importMediaTagMenu = function (common, $container) { if (mediatagContextMenu) { return mediatagContextMenu; } // Create context menu @@ -337,10 +415,19 @@ define([ window.saveAs(media._blob.content, media.name); } else if ($(this).hasClass("cp-app-code-context-open")) { - common.getMediaTagPreview({ + var mts = [{ src: $mt.attr('src'), key: $mt.attr('data-crypto-key') + }]; + $container.find('media-tag').each(function (i, el) { + var $el = $(el); + if ($el.attr('src') === $mt.attr('src')) { return; } + mts.push({ + src: $el.attr('src'), + key: $el.attr('data-crypto-key') + }); }); + common.getMediaTagPreview(mts); } });