From 6404e5c43077d1d673c3f437639219a5b8cbe984 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 27 May 2019 14:03:15 +0200 Subject: [PATCH] Fix duplicate notications --- www/common/outer/mailbox-handlers.js | 90 ++++++++++++++++++++++++---- www/common/outer/mailbox.js | 36 +++++------ www/common/sframe-common-mailbox.js | 1 + 3 files changed, 97 insertions(+), 30 deletions(-) diff --git a/www/common/outer/mailbox-handlers.js b/www/common/outer/mailbox-handlers.js index 15eca8321..9decd2739 100644 --- a/www/common/outer/mailbox-handlers.js +++ b/www/common/outer/mailbox-handlers.js @@ -8,21 +8,40 @@ define([ }; var handlers = {}; + var removeHandlers = {}; + // Store the friend request displayed to avoid duplicates + var friendRequest = {}; handlers['FRIEND_REQUEST'] = function (ctx, data, cb) { // Check if the request is valid (send by the correct user) if (data.msg.author !== data.msg.content.curvePublic) { return void cb(true); } + // Don't show duplicate friend request: if we already have a friend request + // in memory from the same user, dismiss the new one + if (friendRequest[data.msg.author]) { return void cb(true); } + + friendRequest[data.msg.author] = true; + // If the user is already in our friend list, automatically accept the request if (Messaging.getFriend(ctx.store.proxy, data.msg.author)) { Messaging.acceptFriendRequest(ctx.store, data.msg.content, function (obj) { - if (obj && obj.error) { return void cb(); } + if (obj && obj.error) { + return void cb(); + } cb(true); }); return; } + cb(); }; + removeHandlers['FRIEND_REQUEST'] = function (ctx, box, data) { + if (friendRequest[data.curvePublic]) { + delete friendRequest[data.curvePublic]; + } + }; + + var friendRequestDeclined = {}; handlers['DECLINE_FRIEND_REQUEST'] = function (ctx, box, data, cb) { setTimeout(function () { // Our friend request was declined. @@ -31,16 +50,34 @@ define([ // Remove the pending message and display the "declined" state in the UI delete ctx.store.proxy.friends_pending[data.msg.author]; ctx.updateMetadata(); + if (friendRequestDeclined[data.msg.author]) { return; } box.sendMessage({ type: 'FRIEND_REQUEST_DECLINED', content: { user: data.msg.author, name: data.msg.content.displayName } + }, function () { + if (friendRequestDeclined[data.msg.author]) { + // TODO remove our message because another one was sent first? + } + friendRequestDeclined[data.msg.author] = true; }); }, getRandomTimeout(ctx)); cb(true); }; + handlers['FRIEND_REQUEST_DECLINED'] = function (ctx, box, data, cb) { + if (friendRequestDeclined[data.msg.content.user]) { return void cb(true); } + friendRequestDeclined[data.msg.content.user] = true; + cb(); + }; + removeHandlers['FRIEND_REQUEST_DECLINED'] = function (ctx, box, data) { + if (friendRequestDeclined[data.content.user]) { + delete friendRequestDeclined[data.content.user]; + } + }; + + var friendRequestAccepted = {}; handlers['ACCEPT_FRIEND_REQUEST'] = function (ctx, box, data, cb) { // Our friend request was accepted. setTimeout(function () { @@ -65,24 +102,57 @@ define([ curvePublic: data.msg.author, displayName: data.msg.content.displayName } + }, function () { + if (friendRequestAccepted[data.msg.author]) { + // TODO remove our message because another one was sent first? + } + friendRequestAccepted[data.msg.author] = true; }); }); }, getRandomTimeout(ctx)); cb(true); }; + handlers['FRIEND_REQUEST_ACCEPTED'] = function (ctx, box, data, cb) { + if (friendRequestAccepted[data.msg.content.user]) { return void cb(true); } + friendRequestAccepted[data.msg.content.user] = true; + cb(); + }; + removeHandlers['FRIEND_REQUEST_ACCEPTED'] = function (ctx, box, data) { + if (friendRequestAccepted[data.content.user]) { + delete friendRequestAccepted[data.content.user]; + } + }; - return function (ctx, box, data, cb) { - var type = data.msg.type; - if (handlers[type]) { - try { - handlers[type](ctx, box, data, cb); - } catch (e) { - console.error(e); + return { + add: function (ctx, box, data, cb) { + var type = data.msg.type; + + if (handlers[type]) { + try { + handlers[type](ctx, box, data, cb); + } catch (e) { + console.error(e); + cb(); + } + } else { cb(); } - } else { - cb(); + }, + remove: function (ctx, box, data, h) { + // We sometimes try to delete non-existant data (with "delete box.content[h]") + // In this case, we don't have the data in memory so we don't need to call + // any "remove" handler + if (!data) { return; } + var type = data.type; + + if (removeHandlers[type]) { + try { + removeHandlers[type](ctx, box, data, h); + } catch (e) { + console.error(e); + } + } } }; }); diff --git a/www/common/outer/mailbox.js b/www/common/outer/mailbox.js index c16f57a24..c6b20b564 100644 --- a/www/common/outer/mailbox.js +++ b/www/common/outer/mailbox.js @@ -49,6 +49,12 @@ proxy.mailboxes = { content: msg }, cId ? [cId] : ctx.clients); }; + var hideMessage = function (ctx, type, hash, clients) { + ctx.emit('VIEWED', { + type: type, + hash: hash + }, clients || ctx.clients); + }; var getMyKeys = function (ctx) { var proxy = ctx.store && ctx.store.proxy; @@ -86,14 +92,6 @@ proxy.mailboxes = { }); }; - var updateLastKnownHash = function (ctx, type) { - var m = Util.find(ctx, ['store', 'proxy', 'mailboxes', type]); - if (!m) { return; } - var box = ctx.boxes[type]; - if (!box) { return; } - - }; - // Mark a message as read var dismiss = function (ctx, data, cId, cb) { var type = data.type; @@ -116,7 +114,6 @@ proxy.mailboxes = { if (idx === 0) { m.lastKnownHash = hash; box.history.shift(); - delete box.content[hash]; } else if (m.viewed.indexOf(hash) === -1) { m.viewed.push(hash); } @@ -145,16 +142,14 @@ proxy.mailboxes = { // Make sure we remove data about dismissed messages Object.keys(box.content).forEach(function (h) { if (box.history.indexOf(h) === -1 || m.viewed.indexOf(h) !== -1) { + Handlers.remove(ctx, box, box.content[h], h); delete box.content[h]; } }); Realtime.whenRealtimeSyncs(ctx.store.realtime, function () { cb(); - ctx.emit('VIEWED', { - type: type, - hash: hash - }, ctx.clients.filter(function (clientId) { + hideMessage(ctx, type, hash, ctx.clients.filter(function (clientId) { return clientId !== cId; })); }); @@ -201,19 +196,23 @@ proxy.mailboxes = { cfg.onConnect = function (wc, sendMessage) { // Send a message to our box? // NOTE: we use our own curvePublic so that we can decrypt our own message :) - box.sendMessage = function (_msg) { + box.sendMessage = function (_msg, cb) { + cb = cb || function () {}; try { msg = JSON.stringify(_msg); } catch (e) { console.error(e); } sendMessage(msg, function (err, hash) { + if (err) { return void console.error(err); } + box.history.push(hash); box.content[hash] = _msg; var message = { msg: _msg, hash: hash }; showMessage(ctx, type, message); + cb(); }, keys.curvePublic); }; box.queue.forEach(function (msg) { @@ -236,7 +235,7 @@ proxy.mailboxes = { msg: msg, hash: hash }; - Handlers(ctx, box, message, function (toDismiss) { + Handlers.add(ctx, box, message, function (toDismiss) { if (toDismiss) { dismiss(ctx, { type: type, @@ -275,11 +274,9 @@ proxy.mailboxes = { } // Listen for changes in the "viewed" and lastKnownHash values var view = function (h) { + Handlers.remove(ctx, box, box.content[h], h); delete box.content[h]; - ctx.emit('VIEWED', { - type: type, - hash: h - }, ctx.clients); + hideMessage(ctx, type, h); }; ctx.store.proxy.on('change', ['mailboxes', type], function (o, n, p) { if (p[2] === 'lastKnownHash') { @@ -350,7 +347,6 @@ proxy.mailboxes = { if (BLOCKING_TYPES.indexOf(key) === -1) { openChannel(ctx, key, m, function () { - updateLastKnownHash(ctx, key); //console.log(key + ' mailbox is ready'); }); } else { diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index cfa6e7a0b..65d9965c8 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -25,6 +25,7 @@ define([ var history = {}; var removeFromHistory = function (type, hash) { + if (!history[type]) { return; } history[type] = history[type].filter(function (obj) { return obj.hash !== hash; });