From 6f020b67ca1a0f4f18197983e5da18282158d20f Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 26 Oct 2017 12:31:16 +0200 Subject: [PATCH] Add thumbnails to framework apps --- .../src/less2/include/icon-colors.less | 13 +++++++++ www/code/inner.js | 13 ++++++++- www/common/common-thumbnail.js | 29 ++++++++++++------- www/common/sframe-app-framework.js | 13 ++++----- www/common/sframe-common-interface.js | 1 + www/drive/app-drive.less | 23 ++++++++++----- www/drive/inner.js | 10 +++++-- www/pad/inner.js | 20 ++++++++++++- www/slide/inner.js | 26 +++++++++++++++-- 9 files changed, 116 insertions(+), 32 deletions(-) diff --git a/customize.dist/src/less2/include/icon-colors.less b/customize.dist/src/less2/include/icon-colors.less index 345a48a9a..db9de2a14 100644 --- a/customize.dist/src/less2/include/icon-colors.less +++ b/customize.dist/src/less2/include/icon-colors.less @@ -13,5 +13,18 @@ .cp-icon-color-profile { color: @colortheme_settings-bg; } .cp-icon-color-default { color: @colortheme_default-bg; } .cp-icon-color-todo { color:@colortheme_todo-bg; } + + .cp-border-color-pad { border-color: @colortheme_pad-bg !important; } + .cp-border-color-code { border-color: @colortheme_code-bg !important; } + .cp-border-color-slide { border-color: @colortheme_slide-bg !important; } + .cp-border-color-poll { border-color: @colortheme_poll-bg !important; } + .cp-border-color-file { border-color: @colortheme_file-bg !important; } + .cp-border-color-contacts { border-color: @colortheme_friends-bg !important; } + .cp-border-color-whiteboard { border-color: @colortheme_whiteboard-bg !important; } + .cp-border-color-drive { border-color: @colortheme_drive-bg !important; } + .cp-border-color-settings { border-color: @colortheme_settings-bg !important; } + .cp-border-color-profile { border-color: @colortheme_settings-bg !important; } + .cp-border-color-default { border-color: @colortheme_default-bg !important; } + .cp-border-color-todo { border-color:@colortheme_todo-bg !important; } } diff --git a/www/code/inner.js b/www/code/inner.js index 7fd66721e..7296d07d3 100644 --- a/www/code/inner.js +++ b/www/code/inner.js @@ -346,7 +346,18 @@ define([ Framework.create({ toolbarContainer: '#cme_toolbox', contentContainer: '#cp-app-code-editor', - getThumbnailContainer: getThumbnailContainer + thumbnail: { + getContainer: getThumbnailContainer, + filter: function (el, before) { + if (before) { + $(el).parents().css('overflow', 'visible'); + $(el).css('max-height', Math.max(600, $(el).width()) + 'px'); + return; + } + $(el).parents().css('overflow', ''); + $(el).css('max-height', ''); + } + } }, waitFor(function (fw) { framework = fw; })); nThen(function (waitFor) { diff --git a/www/common/common-thumbnail.js b/www/common/common-thumbnail.js index a2deea346..2ab07cb75 100644 --- a/www/common/common-thumbnail.js +++ b/www/common/common-thumbnail.js @@ -4,6 +4,7 @@ define([ var Nacl = window.nacl; var Thumb = { dimension: 100, + padDimension: 200 }; var supportedTypes = [ @@ -46,25 +47,28 @@ define([ var h = type === 'video' ? img.videoHeight : img.height; var w = type === 'video' ? img.videoWidth : img.width; - var dim = Thumb.dimension; + var dim = type === 'pad' ? Thumb.padDimension : Thumb.dimension; + // if the image is too small, don't bother making a thumbnail - if (h <= dim && w <= dim) { + /*if (h <= dim && w <= dim) { return { x: Math.floor((dim - w) / 2), w: w, y: Math.floor((dim - h) / 2), h : h }; - } + }*/ // the image is taller than it is wide, so scale to that. var r = dim / (h > w? h: w); // ratio + if (h <= dim && w <= dim) { r = 1; } var d; if (h > w) { var newW = Math.floor(w*r); d = Math.floor((dim - newW) / 2); return { + dim: dim, x: d, w: newW, y: 0, @@ -74,6 +78,7 @@ define([ var newH = Math.floor(h*r); d = Math.floor((dim - newH) / 2); return { + dim: dim, x: 0, w: dim, y: d, @@ -88,8 +93,8 @@ define([ var c2 = document.createElement('canvas'); if (!D) { return void cb('ERROR'); } - c2.width = Thumb.dimension; - c2.height = Thumb.dimension; + c2.width = D.dim; + c2.height = D.dim; var ctx = c2.getContext('2d'); ctx.drawImage(canvas, D.x, D.y, D.w, D.h); @@ -147,7 +152,8 @@ define([ PDFJS.getDocument(url).promise .then(function (doc) { return doc.getPage(1).then(makeThumb).then(function (canvas) { - cb(void 0, canvas.toDataURL()); + var D = getResizedDimensions(canvas, 'pdf'); + Thumb.fromCanvas(canvas, D, cb); }); }).catch(function () { cb('ERROR'); @@ -165,17 +171,20 @@ define([ }; window.html2canvas = undefined; - Thumb.fromDOM = function (element, cb) { + Thumb.fromDOM = function (opts, cb) { + var element = opts.getContainer(); var todo = function () { - html2canvas(element, { + if (opts.filter) { opts.filter(element, true); } + window.html2canvas(element, { allowTaint: true, onrendered: function (canvas) { - var D = getResizedDimensions(canvas, 'image'); + if (opts.filter) { opts.filter(element, false); } + var D = getResizedDimensions(canvas, 'pad'); Thumb.fromCanvas(canvas, D, cb); } }); }; - if (html2canvas) { return void todo(); } + if (window.html2canvas) { return void todo(); } require(['/bower_components/html2canvas/build/html2canvas.min.js'], todo); }; diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index 3f4772514..b6dfb6e58 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -268,10 +268,11 @@ define([ Cryptpad.removeLoadingScreen(emitResize); - if (options.getThumbnailContainer) { + if (options.thumbnail) { var oldThumbnailState; var privateDat = cpNfInner.metadataMgr.getPrivateData(); - var hash = privateDat.availableHashes.editHash || privateDat.availableHashes.viewHash; + var hash = privateDat.availableHashes.editHash || + privateDat.availableHashes.viewHash; var href = privateDat.pathname + '#' + hash; var mkThumbnail = function () { if (!hash) { return; } @@ -279,13 +280,9 @@ define([ if (!cpNfInner.chainpad) { return; } var content = cpNfInner.chainpad.getUserDoc(); if (content === oldThumbnailState) { return; } - var el = options.getThumbnailContainer(); - if (!el) { return; } - $(el).parents().css('overflow', 'visible'); - Thumb.fromDOM(el, function (err, b64) { + Thumb.fromDOM(options.thumbnail, function (err, b64) { oldThumbnailState = content; - $(el).parents().css('overflow', ''); - SFUI.setPadThumbnail(href, b64) + SFUI.setPadThumbnail(href, b64); }); }; window.setInterval(mkThumbnail, 5000); diff --git a/www/common/sframe-common-interface.js b/www/common/sframe-common-interface.js index 6835039cb..e023e8f11 100644 --- a/www/common/sframe-common-interface.js +++ b/www/common/sframe-common-interface.js @@ -70,6 +70,7 @@ define([ // We can only create thumbnails for files here since we can't easily decrypt pads return void whenNewThumb(); } + if (!v) { return; } if (v === 'EMPTY') { return; } addThumbnail(err, v, $container, cb); }); diff --git a/www/drive/app-drive.less b/www/drive/app-drive.less index 8def8763a..2cc04be9c 100644 --- a/www/drive/app-drive.less +++ b/www/drive/app-drive.less @@ -58,13 +58,15 @@ min-height: auto; } .cp-app-drive-element-name { width: 100%; - height: 48px; - margin: 8px 0; + height: 24px; + margin: 0; display: inline-block; + font-size: 14px; //align-items: center; //justify-content: center; overflow: hidden; - //text-overflow: ellipsis; + white-space: nowrap; + text-overflow: ellipsis; word-wrap: break-word; } .cp-app-drive-element-truncated { @@ -83,8 +85,8 @@ min-height: auto; .fa { display: block; margin: auto; - font-size: 48px; - margin: 8px 0; + font-size: 64px; + margin: 18px 0; text-align: center; &.listonly { display: none; @@ -518,10 +520,15 @@ span { } } .cp-app-drive-element-thumbnail { - max-width: 64px; - max-height: 64px; + max-width: 100px; + max-height: 100px; & ~ .fa { - display: none; + display: inline; + font-size: 17px; + position: absolute; + top: 3px; + left: 3px; + margin: 0; } } } diff --git a/www/drive/inner.js b/www/drive/inner.js index fe06dca69..5bcc70f45 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -1145,6 +1145,10 @@ define([ if (!data) { return void logError("No data for the file", element); } var hrefData = Cryptpad.parsePadUrl(data.href); + if (hrefData.type) { + $span.addClass('cp-border-color-'+hrefData.type); + } + var $state = $('', {'class': 'cp-app-drive-element-state'}); if (hrefData.hashData && hrefData.hashData.mode === 'view') { var $ro = $readonlyIcon.clone().appendTo($state); @@ -1161,6 +1165,7 @@ define([ var $name = $('', {'class': 'cp-app-drive-element-name'}).text(name); $span.append($name); $span.append($state); + $span.attr('title', name); var type = Messages.type[hrefData.type] || hrefData.type; common.displayThumbnail(data.href, $span, function ($thumb) { @@ -1199,6 +1204,7 @@ define([ var $files = $('', { 'class': 'cp-app-drive-element-files cp-app-drive-element-list' }).text(files); + $span.attr('title', key); $span.append($name).append($state).append($subfolders).append($files); }; @@ -2197,7 +2203,7 @@ define([ } $content.append($info).append($dirContent); - var $truncated = $('', {'class': 'cp-app-drive-element-truncated'}).text('...'); + /*var $truncated = $('', {'class': 'cp-app-drive-element-truncated'}).text('...'); $content.find('.cp-app-drive-element').each(function (idx, el) { var $name = $(el).find('.cp-app-drive-element-name'); if ($name.length === 0) { return; } @@ -2206,7 +2212,7 @@ define([ $tr.attr('title', $name.text()); $(el).append($tr); } - }); + });*/ $content.scrollTop(s); appStatus.ready(true); diff --git a/www/pad/inner.js b/www/pad/inner.js index edbb3c25a..34340c0a8 100644 --- a/www/pad/inner.js +++ b/www/pad/inner.js @@ -552,7 +552,25 @@ define([ nThen(function (waitFor) { Framework.create({ toolbarContainer: '#cke_1_toolbox', - contentContainer: '#cke_1_contents' + contentContainer: '#cke_1_contents', + thumbnail: { + getContainer: function () { return $('iframe').contents().find('html')[0]; }, + filter: function (el, before) { + if (before) { + $(el).parents().css('overflow', 'visible'); + $(el).css('max-width', '1200px'); + $(el).css('max-height', Math.max(600, $(el).width()) + 'px'); + $(el).css('overflow', 'hidden'); + $(el).find('body').css('background-color', 'transparent'); + return; + } + $(el).parents().css('overflow', ''); + $(el).css('max-width', ''); + $(el).css('max-height', ''); + $(el).css('overflow', ''); + $(el).find('body').css('background-color', '#fff'); + } + } }, waitFor(function (fw) { window.APP.framework = framework = fw; })); nThen(function (waitFor) { diff --git a/www/slide/inner.js b/www/slide/inner.js index 2dd47105f..7c706ede2 100644 --- a/www/slide/inner.js +++ b/www/slide/inner.js @@ -467,6 +467,17 @@ define([ framework.start(); }; + var getThumbnailContainer = function () { + var $codeMirror = $('.CodeMirror'); + var $c = $('#cp-app-slide-editor'); + if ($c.hasClass('cp-app-slide-preview')) { + return $('.cp-app-slide-frame').first()[0]; + } + if ($codeMirror.length) { + return $codeMirror[0]; + } + }; + var main = function () { var CodeMirror; var editor; @@ -474,10 +485,21 @@ define([ var framework; nThen(function (waitFor) { - Framework.create({ toolbarContainer: '#cme_toolbox', - contentContainer: '#cp-app-slide-editor' + contentContainer: '#cp-app-slide-editor', + thumbnail: { + getContainer: getThumbnailContainer, + filter: function (el, before) { + var metadataMgr = framework._.cpNfInner.metadataMgr; + var metadata = metadataMgr.getMetadata(); + if (before) { + $(el).css('background-color', metadata.backColor || '#000'); + return; + } + $(el).css('background-color', ''); + } + } }, waitFor(function (fw) { framework = fw; })); nThen(function (waitFor) {