From d2c1ed5effe953b50c47aa776888972ade1046f6 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 13 Sep 2018 15:44:48 +0200 Subject: [PATCH] Implement reconnect function in the messenger --- www/common/common-messenger.js | 138 +++++++++++++++++++-------------- www/contacts/messenger-ui.js | 34 ++++++-- 2 files changed, 106 insertions(+), 66 deletions(-) diff --git a/www/common/common-messenger.js b/www/common/common-messenger.js index 51279718e..f7a54b6cf 100644 --- a/www/common/common-messenger.js +++ b/www/common/common-messenger.js @@ -76,6 +76,12 @@ define([ messenger.handlers[type].forEach(g); }; + var emit = function (ev, data) { + eachHandler('event', function (f) { + f(ev, data); + }); + }; + messenger.on = function (type, f) { var stack = messenger.handlers[type]; if (!Array.isArray(stack)) { @@ -575,72 +581,85 @@ define([ var openChannel = function (data) { var keys = data.keys; var encryptor = data.encryptor || Curve.createEncryptor(keys); - network.join(data.channel).then(function (chan) { - var channel = channels[data.channel] = { - id: data.channel, - isFriendChat: data.isFriendChat, - isPadChat: data.isPadChat, - sending: false, - encryptor: encryptor, - messages: [], - wc: chan, - userList: [], - mapId: {}, + var channel = { + id: data.channel, + isFriendChat: data.isFriendChat, + isPadChat: data.isPadChat, + sending: false, + encryptor: encryptor, + messages: [], + userList: [], + mapId: {}, + }; + + var onJoining = function (peer) { + if (peer === Msg.hk) { return; } + if (channel.userList.indexOf(peer) !== -1) { return; } + channel.userList.push(peer); + + // Join event will be sent once we are able to ID this peer + var myData = createData(proxy); + delete myData.channel; + var msg = [Types.mapId, myData, channel.wc.myID]; + var msgStr = JSON.stringify(msg); + var cryptMsg = channel.encryptor.encrypt(msgStr); + var data = { + channel: channel.id, + msg: cryptMsg }; + network.sendto(peer, JSON.stringify(data)); + }; + + var onLeaving = function (peer) { + var i = channel.userList.indexOf(peer); + while (i !== -1) { + channel.userList.splice(i, 1); + i = channel.userList.indexOf(peer); + } + // update status + var otherData = channel.mapId[peer]; + if (!otherData) { return; } + + // Make sure the leaving user is not connected with another netflux id + if (channel.userList.some(function (nId) { + return channel.mapId[nId] + && channel.mapId[nId].curvePublic === otherData.curvePublic; + })) { return; } + + // Send the notification + eachHandler('leave', function (f) { + f(otherData, channel.id); + }); + }; + + var onOpen = function (chan) { + channel.wc = chan; + channels[data.channel] = channel; + chan.on('message', function (msg, sender) { onMessage(msg, sender, chan); }); - var onJoining = function (peer) { - if (peer === Msg.hk) { return; } - if (channel.userList.indexOf(peer) !== -1) { return; } - channel.userList.push(peer); - - // Join event will be sent once we are able to ID this peer - var myData = createData(proxy); - delete myData.channel; - var msg = [Types.mapId, myData, chan.myID]; - var msgStr = JSON.stringify(msg); - var cryptMsg = channel.encryptor.encrypt(msgStr); - var data = { - channel: channel.id, - msg: cryptMsg - }; - network.sendto(peer, JSON.stringify(data)); - }; chan.members.forEach(function (peer) { if (peer === Msg.hk) { return; } if (channel.userList.indexOf(peer) !== -1) { return; } channel.userList.push(peer); }); chan.on('join', onJoining); - chan.on('leave', function (peer) { - var i = channel.userList.indexOf(peer); - while (i !== -1) { - channel.userList.splice(i, 1); - i = channel.userList.indexOf(peer); - } - // update status - var otherData = channel.mapId[peer]; - if (!otherData) { return; } - - // Make sure the leaving user is not connected with another netflux id - if (channel.userList.some(function (nId) { - return channel.mapId[nId] - && channel.mapId[nId].curvePublic === otherData.curvePublic; - })) { return; } - - // Send the notification - eachHandler('leave', function (f) { - f(otherData, channel.id); - }); - }); + chan.on('leave', onLeaving); // FIXME don't subscribe to the channel implicitly getChannelMessagesSince(channel, data, keys); - }, function (err) { + }; + network.join(data.channel).then(onOpen, function (err) { console.error(err); }); + network.on('reconnect', function () { + if (!channels[data.channel]) { return; } + network.join(data.channel).then(onOpen, function (err) { + console.error(err); + }); + }); }; messenger.getFriendList = function (cb) { @@ -805,9 +824,7 @@ define([ // TODO load rooms }).nThen(function () { ready = true; - eachHandler('event', function (f) { - f('READY'); - }); + emit('READY'); }); }; init(); @@ -883,9 +900,7 @@ define([ var openPadChat = function (data, cb) { var channel = data.channel; if (getChannel(channel)) { - eachHandler('event', function (f) { - f('PADCHAT_READY', channel); - }); + emit('PADCHAT_READY', channel); return void cb(); } var keys = data.secret && data.secret.keys; @@ -901,13 +916,18 @@ define([ }; openChannel(chanData); joining[channel] = function () { - eachHandler('event', function (f) { - f('PADCHAT_READY', channel); - }); + emit('PADCHAT_READY', channel); }; cb(); }; + network.on('disconnect', function () { + emit('DISCONNECT'); + }); + network.on('reconnect', function () { + emit('RECONNECT'); + }); + messenger.execCommand = function (obj, cb) { var cmd = obj.cmd; var data = obj.data; diff --git a/www/contacts/messenger-ui.js b/www/contacts/messenger-ui.js index ae469902e..9a67ea648 100644 --- a/www/contacts/messenger-ui.js +++ b/www/contacts/messenger-ui.js @@ -122,6 +122,12 @@ define([ find.inList(id).removeClass('cp-app-contacts-notify'); }; + var onResize = function () { + // Don't update the width if we are in the contacts app + if (!toolbar) { return; } + var w = $userlist[0].offsetWidth - $userlist[0].clientWidth; + $userlist.css('width', (68 + w)+'px'); + }; var reorderRooms = function () { var channels = Object.keys(state.channels).sort(function (a, b) { var m1 = state.channels[a].messages.slice(-1)[0]; @@ -136,14 +142,10 @@ define([ }); // Make sure the width is correct even if there is a scrollbar - var w = $userlist[0].offsetWidth - $userlist[0].clientWidth; - $userlist.css('width', (68 + w)+'px'); + onResize(); }; - $(window).on('resize', function () { - var w = $userlist[0].offsetWidth - $userlist[0].clientWidth; - $userlist.css('width', (68 + w)+'px'); - }); + $(window).on('resize', onResize); var m = function (md) { var d = h('div.cp-app-contacts-content'); @@ -174,7 +176,8 @@ define([ markup.message = function (msg) { if (msg.type !== 'MSG') { return; } var curvePublic = msg.author; - var name = msg.name || contactsData[msg.author].displayName; + var name = typeof msg.name !== "undefined" ? (msg.name || Messages.anonymous) + : contactsData[msg.author].displayName; var d = msg.time ? new Date(msg.time) : undefined; var day = d ? d.toLocaleDateString() : ''; var hour = d ? d.toLocaleTimeString() : ''; @@ -770,6 +773,15 @@ define([ $container.removeClass('cp-app-contacts-initializing'); }; + var onDisconnect = function () { + debug('disconnected'); + $messages.find('.cp-app-contacts-input textarea').prop('disabled', true); + }; + var onReconnect = function () { + debug('reconnected'); + $messages.find('.cp-app-contacts-input textarea').prop('disabled', false); + }; + // Initialize chat when outer is ready (all channels loaded) // TODO: try again in outer if fail to load a channel execCommand('IS_READY', null, function (err, yes) { @@ -784,6 +796,14 @@ define([ onPadChatReady(obj.data); return; } + if (obj.ev === 'DISCONNECT') { + onDisconnect(); + return; + } + if (obj.ev === 'RECONNECT') { + onReconnect(); + return; + } }); };