diff --git a/www/profile/index.html b/www/profile/index.html new file mode 100644 index 000000000..9aed29ca5 --- /dev/null +++ b/www/profile/index.html @@ -0,0 +1,20 @@ + + + + + Cryptpad: Zero Knowledge, Collaborative Real Time Editing + + + + + + + + + + + + diff --git a/www/profile/main.js b/www/profile/main.js new file mode 100644 index 000000000..c1ce4c6f5 --- /dev/null +++ b/www/profile/main.js @@ -0,0 +1,369 @@ +require.config({ + paths: { + cm: '/bower_components/codemirror' + } +}); +define([ + 'jquery', + '/common/cryptpad-common.js', + '/bower_components/chainpad-listmap/chainpad-listmap.js', + '/bower_components/chainpad-crypto/crypto.js', + '/bower_components/marked/marked.min.js', + 'cm/lib/codemirror', + 'cm/mode/markdown/markdown', + '/bower_components/tweetnacl/nacl-fast.min.js', + 'less!/profile/main.less', +], function ($, Cryptpad, Listmap, Crypto, Marked, CodeMirror) { + + var APP = window.APP = { + Cryptpad: Cryptpad, + _onRefresh: [] + }; + + $(window.document).on('decryption', function (e) { + var decrypted = e.originalEvent; + if (decrypted.callback) { decrypted.callback(); } + }) + .on('decryptionError', function (e) { + var error = e.originalEvent; + Cryptpad.alert(error.message); + }); + + // Marked + var renderer = new Marked.Renderer(); + Marked.setOptions({ + renderer: renderer, + sanitize: true + }); + // Tasks list + var checkedTaskItemPtn = /^\s*\[x\]\s*/; + var uncheckedTaskItemPtn = /^\s*\[ \]\s*/; + renderer.listitem = function (text) { + var isCheckedTaskItem = checkedTaskItemPtn.test(text); + var isUncheckedTaskItem = uncheckedTaskItemPtn.test(text); + if (isCheckedTaskItem) { + text = text.replace(checkedTaskItemPtn, + ' ') + '\n'; + } + if (isUncheckedTaskItem) { + text = text.replace(uncheckedTaskItemPtn, + ' ') + '\n'; + } + var cls = (isCheckedTaskItem || isUncheckedTaskItem) ? ' class="todo-list-item"' : ''; + return '' + text + '\n'; + }; + /*renderer.image = function (href, title, text) { + if (href.slice(0,6) === '/file/') { + var parsed = Cryptpad.parsePadUrl(href); + var hexFileName = Cryptpad.base64ToHex(parsed.hashData.channel); + var src = '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName; + var mt = ''; + mt += ''; + return mt; + } + var out = '' + text + '' : '>'; + return out; + };*/ + + var Messages = Cryptpad.Messages; + + var DISPLAYNAME_ID = "displayName"; + var LINK_ID = "link"; + var AVATAR_ID = "avatar"; + var DESCRIPTION_ID = "description"; + var PUBKEY_ID = "pubKey"; + var CREATE_ID = "createProfile"; + var HEADER_ID = "header"; + var HEADER_RIGHT_ID = "rightside"; + + var createEditableInput = function ($block, name, ph, getValue, setValue, realtime) { + var lastVal; + getValue(function (value) { + lastVal = value; + var $input = $('', { + 'id': name+'Input', + placeholder: ph + }).val(value); + var $icon = $('', {'class': 'fa fa-pencil edit'}); + var editing = false; + var todo = function () { + if (editing) { return; } + editing = true; + + var newVal = $input.val().trim(); + + if (newVal === lastVal) { + editing = false; + return; + } + + setValue(newVal, function (err) { + if (err) { return void console.error(err); } + Cryptpad.whenRealtimeSyncs(realtime, function () { + lastVal = newVal; + Cryptpad.log('TODO: '+name+' saved'); + editing = false; + }); + }); + }; + $input.on('keyup', function (e) { + if (e.which === 13) { return void todo(); } + if (e.which === 27) { + $input.val(lastVal); + } + }); + $icon.click(function () { $input.focus(); }); + $input.focus(function () { + $input.width(''); + }); + $input.focusout(todo); + $block.append($input).append($icon); + }); + }; + + /* + var addDisplayName = function ($container) { + var $block = $('
', {id: DISPLAYNAME_ID}).appendTo($container); + var getValue = function (cb) { + Cryptpad.getLastName(function (err, name) { + if (err) { return void console.error(err); } + cb(name); + }); + }; + if (APP.readOnly) { + var $span = $('', {'class': DISPLAYNAME_ID}).appendTo($block); + getValue(function (value) { + $span.text(value); + }); + return; + } + var setValue = function (value, cb) { + Cryptpad.setAttribute('username', value, function (err) { + cb(err); + }); + }; + var placeholder = Messages.anonymous; + var rt = Cryptpad.getStore().getProxy().info.realtime; + createEditableInput($block, DISPLAYNAME_ID, placeholder, 32, getValue, setValue, rt); + }; + */ + var addDisplayName = function ($container) { + var $block = $('
', {id: DISPLAYNAME_ID}).appendTo($container); + var getValue = function (cb) { + cb(APP.lm.proxy.name); + }; + var placeholder = Messages.anonymous; + if (APP.readOnly) { + var $span = $('', {'class': DISPLAYNAME_ID}).appendTo($block); + getValue(function (value) { + $span.text(value || placeholder); + }); + return; + } + var setValue = function (value, cb) { + APP.lm.proxy.name = value; + cb(); + }; + var rt = Cryptpad.getStore().getProxy().info.realtime; + createEditableInput($block, DISPLAYNAME_ID, placeholder, getValue, setValue, rt); + }; + + var addLink = function ($container) { + var $block = $('
', {id: LINK_ID}).appendTo($container); + var getValue = function (cb) { + cb(APP.lm.proxy.url); + }; + if (APP.readOnly) { + var $a = $('', { + 'class': LINK_ID, + target: '_blank', + rel: 'noreferrer noopener' + }).appendTo($block); + getValue(function (value) { + if (!value) { + return void $a.hide(); + } + $a.attr('href', value).text(value); + }); + return; + } + var setValue = function (value, cb) { + APP.lm.proxy.url = value; + cb(); + }; + var rt = APP.lm.realtime; + var placeholder = "URL"; //TODO + 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 $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]); + }); + } + if (APP.readOnly) { return; } + var $button = $('