define([ 'jquery', '/api/config', '/common/cryptpad-common.js', '/common/common-util.js', '/common/common-hash.js', '/common/media-tag.js', '/common/tippy.min.js', '/customize/application_config.js', '/file/file-crypto.js', '/bower_components/localforage/dist/localforage.min.js', '/bower_components/tweetnacl/nacl-fast.min.js', 'css!/common/tippy.css', ], function ($, Config, Cryptpad, Util, Hash, MediaTag, Tippy, AppConfig, FileCrypto, localForage) { var UI = {}; var Messages = Cryptpad.Messages; var Nacl = window.nacl; /** * Requirements from cryptpad-common.js * getFileSize * - hrefToHexChannelId * displayAvatar * - getFirstEmojiOrCharacter * - parsePadUrl * - getSecrets * - base64ToHex * - getBlobPathFromHex * - bytesToMegabytes * createUserAdminMenu * - fixHTML * - createDropdown */ var addThumbnail = function (err, thumb, $span, cb) { var img = new Image(); img.src = thumb.slice(0,5) === 'data:' ? thumb : 'data:;base64,'+thumb; $span.find('.cp-icon').hide(); $span.prepend(img); cb($(img)); }; UI.setPadThumbnail = function (href, b64, cb) { cb = cb || $.noop; var k ='thumbnail-' + href; localForage.setItem(k, b64, cb); }; localForage.removeItem('thumbnail-/1/edit/lqg6RRnynI76LV0sR8F0YA/Nh1SNXxB5U2UjaADvODfvI5l/'); UI.displayThumbnail = function (href, $container, cb) { cb = cb || $.noop; var parsed = Hash.parsePadUrl(href); var k ='thumbnail-' + href; var whenNewThumb = function () { var secret = Hash.getSecrets('file', parsed.hash); var hexFileName = Util.base64ToHex(secret.channel); var src = Hash.getBlobPathFromHex(hexFileName); var cryptKey = secret.keys && secret.keys.fileKeyStr; var key = Nacl.util.decodeBase64(cryptKey); FileCrypto.fetchDecryptedMetadata(src, key, function (e, metadata) { if (!metadata.thumbnail) { return void localForage.setItem(k, 'EMPTY'); } localForage.setItem(k, metadata.thumbnail, function (err) { addThumbnail(err, metadata.thumbnail, $container, cb); }); }); }; localForage.getItem(k, function (err, v) { if (!v && parsed.type === 'file') { // We can only create thumbnails for files here since we can't easily decrypt pads return void whenNewThumb(); } if (v === 'EMPTY') { return; } addThumbnail(err, v, $container, cb); }); }; UI.updateTags = function (common, href) { var sframeChan = common.getSframeChannel(); sframeChan.query('Q_TAGS_GET', href || null, function (err, res) { if (err || res.error) { if (res.error === 'NO_ENTRY') { Cryptpad.alert(Messages.tags_noentry); } return void console.error(err || res.error); } Cryptpad.dialog.tagPrompt(res.data, function (tags) { if (!Array.isArray(tags)) { return; } sframeChan.event('EV_TAGS_SET', { tags: tags, href: href, }); }); }); }; UI.createButton = function (common, type, rightside, data, callback) { var AppConfig = common.getAppConfig(); var button; var size = "17px"; var sframeChan = common.getSframeChannel(); switch (type) { case 'export': button = $('