From df103c4074ea878e0ddda296b7114c40e67dae65 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 7 Jul 2017 18:53:21 +0200 Subject: [PATCH] Messaging app --- www/common/common-messaging.js | 276 ++++++++++++++++++++++++++++++--- www/common/cryptpad-common.js | 8 +- www/friends/main.js | 8 +- www/friends/main.less | 131 ++++++++++++++++ 4 files changed, 396 insertions(+), 27 deletions(-) diff --git a/www/common/common-messaging.js b/www/common/common-messaging.js index c3e4efbd9..91552b711 100644 --- a/www/common/common-messaging.js +++ b/www/common/common-messaging.js @@ -1,18 +1,59 @@ define([ 'jquery', '/bower_components/chainpad-crypto/crypto.js', -], function ($, Crypto) { + '/common/curve.js' +], function ($, Crypto, Curve) { var Msg = {}; + var Types = { + message: 'MSG' + }; + + // TODO: pin the chat channel! + + + // TODO: new Types + // - send a rename message to the chat + // - petnames + // - close a chat / remove a friend + + // TODO + // - mute a channel (hide notifications or don't open it?) + // + var pending = {}; - Msg.getFriendList = function (common) { + var createData = Msg.createData = function (common, hash) { + var proxy = common.getProxy(); + return { + channel: hash || common.createChannelId(), + displayName: proxy[common.displayNameKey], + profile: proxy.profile.view, + edPublic: proxy.edPublic, + curvePublic: proxy.curvePublic, + avatar: proxy.profile.avatar + }; + }; + + var getFriend = function (common, pubkey) { + var proxy = common.getProxy(); + if (pubkey === proxy.edPublic) { + var data = createData(common); + delete data.channel; + return data; + } + return proxy.friends ? proxy.friends[pubkey] : undefined; + }; + + var getFriendList = Msg.getFriendList = function (common) { var proxy = common.getProxy(); return proxy.friends || {}; }; + // Messaging tools + var avatars = {}; - Msg.getFriendListUI = function (common) { + Msg.getFriendListUI = function (common, open) { var proxy = common.getProxy(); var $block = $('
'); var friends = proxy.friends || {}; @@ -26,7 +67,7 @@ define([ window.open('/profile/#' + data.profile); }); $friend.click(function () { - // TODO + open(data.edPublic); }); if (data.avatar && avatars[data.avatar]) { $friend.append(avatars[data.avatar]); @@ -59,6 +100,214 @@ define([ }); }; + var channels = Msg.channels = window.channels = {}; + + var pushMsg = function (channel, cryptMsg) { + var msg = channel.encryptor.decrypt(cryptMsg); + var parsedMsg = JSON.parse(msg); + if (parsedMsg[0] !== Types.message) { return; } + parsedMsg.shift(); + channel.messages.push([cryptMsg.slice(0,64), parsedMsg]); + }; + + var onDirectMessage = function (msg, sender) { + if (sender !== Msg.hk) { return; } + var parsed = JSON.parse(msg); + if ((parsed.validateKey || parsed.owners) && parsed.channel) { + return; + } + if (parsed.state && parsed.state === 1 && parsed.channel) { + if (channels[parsed.channel]) { + // parsed.channel is Ready + // TODO: call a function that shows that the channel is ready? (remove a spinner, ...) + // channel[parsed.channel].ready(); + channels[parsed.channel].ready = true; + } + return; + } + var chan = parsed[3]; + if (!chan || !channels[chan]) { return; } + pushMsg(channels[chan], parsed[4]); + }; + var onMessage = function (msg, sender, chan) { + if (!channels[chan.id]) { return; } + pushMsg(channels[chan.id], msg); + channels[chan.id].notify(); + channels[chan.id].refresh(); + }; + + var createChatBox = function (common, $container, edPublic) { + var data = getFriend(common, edPublic); + var proxy = common.getProxy(); + + var $header = $('
', {'class': 'header'}).appendTo($container); + $('
', {'class': 'messages'}).appendTo($container); + var $inputBlock = $('
', {'class': 'input'}).appendTo($container); + + // Input + var channel = channels[data.channel]; + var $input = $('', {type: 'text'}).appendTo($inputBlock); + var send = function () { + if (!$input.val()) { return; } + var msg = [Types.message, proxy.edPublic, +new Date(), $input.val()]; + var msgStr = JSON.stringify(msg); + var cryptMsg = channel.encryptor.encrypt(msgStr); + channel.wc.bcast(cryptMsg).then(function () { + $input.val(''); + pushMsg(channel, cryptMsg); + channel.refresh(); + }, function (err) { + console.error(err); + }); + }; + $('