diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 21cd34472..c9d070863 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -659,6 +659,14 @@ define([ }; mailbox.onEvent = Util.mkEvent(); + // Universal + var universal = common.universal = {}; + universal.execCommand = function (data, cb) { + postMessage("UNIVERSAL_COMMAND", data, cb); + }; + universal.onEvent = Util.mkEvent(); + + // Pad RPC var pad = common.padRpc = {}; pad.joinPad = function (data) { @@ -1097,6 +1105,8 @@ define([ CURSOR_EVENT: common.cursor.onEvent.fire, // Mailbox MAILBOX_EVENT: common.mailbox.onEvent.fire, + // Universal + UNIVERSAL_EVENT: common.universal.onEvent.fire, // Pad PAD_READY: common.padRpc.onReadyEvent.fire, PAD_MESSAGE: common.padRpc.onMessageEvent.fire, diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 2499e1007..2d21cc18c 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -13,6 +13,7 @@ define([ '/common/outer/cursor.js', '/common/outer/onlyoffice.js', '/common/outer/mailbox.js', + '/common/outer/profile.js', '/common/outer/network-config.js', '/customize/application_config.js', @@ -23,7 +24,7 @@ define([ '/bower_components/nthen/index.js', '/bower_components/saferphore/index.js', ], function (Sortify, UserObject, ProxyManager, Migrate, Hash, Util, Constants, Feedback, Realtime, Messaging, Messenger, - Cursor, OnlyOffice, Mailbox, NetConfig, AppConfig, + Cursor, OnlyOffice, Mailbox, Profile, NetConfig, AppConfig, Crypto, ChainPad, CpNetflux, Listmap, nThen, Saferphore) { var create = function () { @@ -35,7 +36,9 @@ define([ var storeHash; - var store = window.CryptPad_AsyncStore = {}; + var store = window.CryptPad_AsyncStore = { + modules: {} + }; var onSync = function (cb) { nThen(function (waitFor) { @@ -656,6 +659,9 @@ define([ }); });*/ } + if (store.profile) { + store.profile.setName(value); + } store.proxy[Constants.displayNameKey] = value; broadcast([clientId], "UPDATE_METADATA"); if (store.messenger) { store.messenger.updateMyData(); } @@ -994,6 +1000,39 @@ define([ cb(); }; + // Universal + Store.universal = { + execCommand: function (clientId, obj, cb) { + var type = obj.type; + var data = obj.data; + if (store.modules[type]) { + store.modules[type].execCommand(clientId, data, cb); + } else { + return void cb({error: type + ' is disabled'}); + } + } + }; + var loadUniversal = function (Module, type, waitFor) { + if (store.modules[type]) { return; } + store.modules[type] = Module.init({ + store: store, + updateMetadata: function () { + broadcast([], "UPDATE_METADATA"); + }, + pinPads: function (data, cb) { Store.pinPads(null, data, cb); }, + }, waitFor, function (ev, data, clients) { + clients.forEach(function (cId) { + postMessage(cId, 'UNIVERSAL_EVENT', { + type: type, + data: { + ev: ev, + data: data + } + }); + }); + }); + }; + // Messenger Store.messenger = { execCommand: function (clientId, data, cb) { @@ -1394,6 +1433,11 @@ define([ try { store.mailbox.removeClient(clientId); } catch (e) { console.error(e); } + Object.keys(store.modules).forEach(function (key) { + try { + store.modules[key].removeClient(clientId); + } catch (e) { console.error(e); } + }); Object.keys(Store.channels).forEach(function (chanId) { var chanIdx = Store.channels[chanId].clients.indexOf(clientId); @@ -1469,6 +1513,24 @@ define([ }); }; +/* + var loadProfile = function (waitFor) { + store.profile = Profile.init({ + store: store, + updateMetadata: function () { + broadcast([], "UPDATE_METADATA"); + }, + pinPads: function (data, cb) { Store.pinPads(null, data, cb); }, + }, waitFor, function (ev, data, clients) { + clients.forEach(function (cId) { + postMessage(cId, 'PROFILE_EVENT', { + ev: ev, + data: data + }); + }); + }); + }; +*/ var loadCursor = function () { store.cursor = Cursor.init(store, function (ev, data, clients) { clients.forEach(function (cId) { @@ -1618,6 +1680,7 @@ define([ loadCursor(); loadOnlyOffice(); loadMailbox(waitFor); + loadUniversal(Profile, 'profile', waitFor); cleanFriendRequests(); }).nThen(function () { var requestLogin = function () { diff --git a/www/common/outer/store-rpc.js b/www/common/outer/store-rpc.js index 40c446c48..ca9208f71 100644 --- a/www/common/outer/store-rpc.js +++ b/www/common/outer/store-rpc.js @@ -68,6 +68,8 @@ define([ CURSOR_COMMAND: Store.cursor.execCommand, // Mailbox MAILBOX_COMMAND: Store.mailbox.execCommand, + // Universal + UNIVERSAL_COMMAND: Store.universal.execCommand, // Pad SEND_PAD_MSG: Store.sendPadMsg, JOIN_PAD: Store.joinPad, diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 9a5ba5730..29f84ea66 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -329,7 +329,7 @@ define([ for (var k in additionalPriv) { metaObj.priv[k] = additionalPriv[k]; } if (cfg.addData) { - cfg.addData(metaObj.priv, Cryptpad); + cfg.addData(metaObj.priv, Cryptpad, metaObj.user); } sframeChan.event('EV_METADATA_UPDATE', metaObj); @@ -872,6 +872,13 @@ define([ Cryptpad.cursor.execCommand(data, cb); }); + Cryptpad.universal.onEvent.reg(function (data) { + sframeChan.event('EV_UNIVERSAL_EVENT', data); + }); + sframeChan.on('Q_UNIVERSAL_COMMAND', function (data, cb) { + Cryptpad.universal.execCommand(data, cb); + }); + Cryptpad.mailbox.onEvent.reg(function (data) { sframeChan.event('EV_MAILBOX_EVENT', data); }); diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 38ea38f27..032a4c9e7 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -168,6 +168,31 @@ define([ }); }; + // Universal direct channel + var modules = {}; + funcs.makeUniversal = function (type, cfg) { + if (modules[type]) { return; } + var sframeChan = funcs.getSframeChannel(); + modules[type] = { + onEvent: cfg.onEvent || function () {} + }; + return { + execCommand: function (cmd, data, cb) { + sframeChan.query("Q_UNIVERSAL_COMMAND", { + type: type, + data: { + cmd: cmd, + data: data + } + }, function (err, obj) { + if (err) { return void cb({error: err}); } + cb(obj); + }); + } + }; + }; + + // Chat var padChatChannel; // common-ui-elements needs to be able to get the chat channel to put it in metadata when @@ -575,6 +600,12 @@ define([ }); }); + ctx.sframeChan.on('EV_UNIVERSAL_EVENT', function (obj) { + var type = obj.type; + if (!type || !modules[type]) { return; } + modules[type].onEvent(obj.data); + }); + ctx.metadataMgr.onReady(waitFor()); funcs.addShortcuts(); diff --git a/www/profile/app-profile.less b/www/profile/app-profile.less index ec41c4e31..852b11421 100644 --- a/www/profile/app-profile.less +++ b/www/profile/app-profile.less @@ -99,10 +99,23 @@ } .cp-app-profile-link { font-size: 25px; + vertical-align: middle; } .cp-app-profile-displayname, .cp-app-profile-link { line-height: 40px; } + .cp-app-profile-link-code { + display: none; + } + & > button:empty { + margin-left: 25px; + } + } + + .cp-app-profile-friend-request { + flex: 0; + width: 400px; + margin-top: 10px; } // I tried using flexbox but messed with how the pencil icon was displayed @@ -116,10 +129,16 @@ #cp-app-profile-description { position: relative; font-size: 16px; - border: 1px solid #DDD; margin-bottom: 20px; + .cp-app-profile-description-code { + display: none; + } .cp-app-profile-description-rendered { + border: 1px solid #DDD; padding: 0 15px; + &:empty { + display: none; + } } .cp-app-profile-description-ok, .cp-app-profile-description-spin { position: absolute; @@ -133,7 +152,6 @@ height: 300px; } .CodeMirror { - border: 1px solid #DDD; font-family: monospace; font-size: 16px; line-height: initial; @@ -144,6 +162,13 @@ line-height: inherit; } } + .cp-app-profile-description-edit { + & > button { + span { + margin-left: 10px; + } + } + } } #cp-app-profile-create { height: 100%; diff --git a/www/profile/inner.js b/www/profile/inner.js index 3dcd91f1d..d7bb6bfee 100644 --- a/www/profile/inner.js +++ b/www/profile/inner.js @@ -8,6 +8,7 @@ define([ '/common/common-util.js', '/common/common-interface.js', '/common/common-realtime.js', + '/common/hyperscript.js', '/customize/messages.js', '/customize/application_config.js', '/bower_components/marked/marked.min.js', @@ -33,6 +34,7 @@ define([ Util, UI, Realtime, + h, Messages, AppConfig, Marked, @@ -75,7 +77,6 @@ define([ var LINK_ID = "cp-app-profile-link"; var AVATAR_ID = "cp-app-profile-avatar"; var DESCRIPTION_ID = "cp-app-profile-description"; - var PUBKEY_ID = "cp-app-profile-pubkey"; var CREATE_ID = "cp-app-profile-create"; var HEADER_ID = "cp-app-profile-header"; var HEADER_RIGHT_ID = "cp-app-profile-rightside"; @@ -85,98 +86,6 @@ define([ var common; var sFrameChan; - var createEditableInput = function ($block, name, ph, getValue, setValue, fallbackValue) { - fallbackValue = fallbackValue || ''; // don't ever display 'null' or 'undefined' - var lastVal; - getValue(function (value) { - lastVal = value; - var $input = $('', { - 'id': name+'Input', - placeholder: ph - }).val(value); - 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); } - lastVal = newVal; - UI.log(Messages._getKey('profile_fieldSaved', [newVal || fallbackValue])); - editing = false; - }); - }; - $input.on('keyup', function (e) { - if (e.which === 13) { return void todo(); } - if (e.which === 27) { - $input.val(lastVal); - } - }); - $input.focus(function () { - $input.width(''); - }); - $input.focusout(todo); - $block.append($input); - }); - }; - -/* jshint ignore:start */ - var isFriend = function (proxy, edKey) { - var friends = Util.find(proxy, ['friends']); - return typeof(edKey) === 'string' && friends && (edKey in friends); - }; - - var addCreateInviteLinkButton = function ($container) { - return; - /*var obj = APP.lm.proxy; - - var proxy = Cryptpad.getProxy(); - var userViewHash = Util.find(proxy, ['profile', 'view']); - - var edKey = obj.edKey; - var curveKey = obj.curveKey; - - if (!APP.readOnly || !curveKey || !edKey || userViewHash === window.location.hash.slice(1) || isFriend(proxy, edKey)) { - //console.log("edit mode or missing curve key, or you're viewing your own profile"); - return; - } - - // sanitize user inputs - - var unsafeName = obj.name || ''; - console.log(unsafeName); - var name = Util.fixHTML(unsafeName) || Messages.anonymous; - console.log(name); - - console.log("Creating invite button"); - $("