From 19ff8a345df331d2b400ff0901663faa60aeb42f Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 28 Jun 2017 16:59:35 +0200 Subject: [PATCH 1/2] Avatar upload in the profile app --- www/common/cryptpad-common.js | 72 ++++++++++++++++++- www/common/diffMarked.js | 1 - www/profile/main.js | 130 ++++++++++++++++++++++++++-------- www/profile/main.less | 29 ++++++-- 4 files changed, 195 insertions(+), 37 deletions(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index d1c830d3d..859083224 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -12,12 +12,13 @@ define([ '/common/common-metadata.js', '/common/common-codemirror.js', '/common/common-file.js', + '/file/file-crypto.js', '/common/clipboard.js', '/common/pinpad.js', '/customize/application_config.js' ], function ($, Config, Messages, Store, Util, Hash, UI, History, UserList, Title, Metadata, - CodeMirror, Files, Clipboard, Pinpad, AppConfig) { + CodeMirror, Files, FileCrypto, Clipboard, Pinpad, AppConfig) { /* This file exposes functionality which is specific to Cryptpad, but not to any particular pad type. This includes functions for committing metadata @@ -974,9 +975,14 @@ define([ var ev = { target: data.target }; + if (data.filter && !data.filter(file)) { + common.log('TODO: invalid avatar (type or size)'); + return; + } data.FM.handleFile(file, ev); if (callback) { callback(); } }); + if (data.accept) { $input.attr('accept', data.accept); } button.click(function () { $input.click(); }); break; case 'template': @@ -1129,6 +1135,70 @@ define([ return button; }; + common.avatarAllowedTypes = [ + 'image/png', + 'image/jpeg', + 'image/jpg', + 'image/gif', + ]; + common.displayAvatar = function ($container, href) { + var MutationObserver = window.MutationObserver; + $container.html(''); + if (href) { + var parsed = common.parsePadUrl(href); + var secret = common.getSecrets('file', parsed.hash); + if (secret.keys && secret.channel) { + var cryptKey = secret.keys && secret.keys.fileKeyStr; + var hexFileName = common.base64ToHex(secret.channel); + var src = common.getBlobPathFromHex(hexFileName); + common.getFileSize(href, function (e, data) { + if (e) { return void console.error(e); } + if (typeof data !== "number") { return; } + if (common.bytesToMegabytes(data) > 0.5) { return; } + var $img = $('').appendTo($container); + $img.attr('src', src); + $img.attr('data-crypto-key', 'cryptpad:' + cryptKey); + require(['/common/media-tag.js'], function (MediaTag) { + MediaTag.CryptoFilter.setAllowedMediaTypes(common.avatarAllowedTypes); + MediaTag($img[0]); + var observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === 'childList' && mutation.addedNodes.length) { + console.log(mutation); + if (mutation.addedNodes.length > 1 || + mutation.addedNodes[0].nodeName !== 'IMG') { + $img.remove(); + return; + //TODO display default avatar + } + var $image = $img.find('img'); + var onLoad = function () { + var w = $image.width(); + var h = $image.height(); + if (w>h) { + $image.css('max-height', '100%'); + $img.css('flex-direction', 'row'); + return; + } + $image.css('max-width', '100%'); + $img.css('flex-direction', 'column'); + }; + if ($image[0].complete) { onLoad(); } + $image.on('load', onLoad); + } + }); + }); + observer.observe($img[0], { + attributes: false, + childList: true, + characterData: false + }); + }); + }); + } + } + }; + // Create a button with a dropdown menu // input is a config object with parameters: // - container (optional): the dropdown container (span) diff --git a/www/common/diffMarked.js b/www/common/diffMarked.js index d760c0f5c..6d27920aa 100644 --- a/www/common/diffMarked.js +++ b/www/common/diffMarked.js @@ -156,7 +156,6 @@ define([ MediaTag(el); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { - console.log(mutation); if (mutation.type === 'childList') { var list_values = [].slice.call(el.children); mediaMap[el.getAttribute('src')] = list_values; diff --git a/www/profile/main.js b/www/profile/main.js index f170d1bc2..eb836d024 100644 --- a/www/profile/main.js +++ b/www/profile/main.js @@ -196,51 +196,105 @@ define([ cb(); }; var rt = APP.lm.realtime; - var placeholder = "URL"; //TODO + var placeholder = "URL"; //XXX createEditableInput($block, LINK_ID, placeholder, getValue, setValue, rt); }; var addAvatar = function ($container) { var $block = $('
', {id: AVATAR_ID}).appendTo($container); var $span = $('').appendTo($block); - if (APP.lm.proxy.avatar) { - //var file = APP.lm.proxy.avatar; - var $img = $('').appendTo($span); - $img.attr('src', '/blob/45/45170bcd64aae1726b0b0e06c4360181a08bad9596640863'); - $img.attr('data-crypto-key', 'cryptpad:5vs/ciPzSAyHeP6XRwxpFZt/cjkRC+EE2CRw+/xfcVI='); - require(['/common/media-tag.js'], function (MediaTag) { - var allowedMediaTypes = [ - 'image/png', - 'image/jpeg', - 'image/jpg', - 'image/gif', - ]; - MediaTag.CryptoFilter.setAllowedMediaTypes(allowedMediaTypes); - MediaTag($img[0]); + var allowedMediaTypes = Cryptpad.avatarAllowedTypes; + var displayAvatar = function () { + $span.html(''); + if (!APP.lm.proxy.avatar) { + $('', { + src: '/customize/images/avatar.png', + title: 'Avatar', // XXX + alt: 'Avatar' + }).appendTo($span); + return; + } + Cryptpad.displayAvatar($span, APP.lm.proxy.avatar); + + if (APP.readOnly) { return; } + + var $delButton = $('