Improve friend request process and UI

pull/1/head
yflory 6 years ago
parent 38f8535dd5
commit 9cb1a059f2

@ -898,6 +898,27 @@
}
.cp-toolbar-notifications {
margin-left: 10px;
.cp-notifications-empty {
color: black;
padding: 5px;
}
button {
position: relative;
&.fa-bell-o {
cursor: default;
}
.cp-dropdown-button-title {
position: absolute;
bottom: 0;
right: 0;
font-size: 14px;
border: 1px solid;
border-radius: 50%;
width: 20px;
height: 20px;
line-height: 16px;
}
}
}
.cp-toolbar-link {
display: inline-flex;

@ -59,7 +59,6 @@ define([
curvePublic: data.curvePublic
}, function (obj) {
cb(obj);
if (obj && obj.error) { return void cb(obj); }
});
};
Msg.addToFriendList = function (cfg, data, cb) {

@ -68,7 +68,7 @@ define([
});
};
Msg.messenger = function (store) {
Msg.messenger = function (store, updateMetadata) {
var messenger = {
handlers: {
event: []
@ -97,6 +97,7 @@ define([
stack.push(f);
};
var allowFriendsChannels = false;
var channels = messenger.channels = {};
var joining = {};
@ -301,7 +302,10 @@ define([
if (!proxy.friends) { return; }
var friends = proxy.friends;
delete friends[curvePublic];
Realtime.whenRealtimeSyncs(realtime, cb);
Realtime.whenRealtimeSyncs(realtime, function () {
updateMetadata();
cb();
});
};
var pushMsg = function (channel, cryptMsg) {
@ -771,45 +775,9 @@ define([
openChannel(data);
};
// Detect friends changes made in another worker
proxy.on('change', ['friends'], function (o, n, p) {
var curvePublic;
if (o === undefined) {
// new friend added
curvePublic = p.slice(-1)[0];
// Load channel
var friend = friends[curvePublic];
if (typeof(friend) !== 'object') { return; }
var channel = friend.channel;
if (!channel) { return; }
loadFriend(friend, function () {
emit('FRIEND', {
curvePublic: curvePublic,
});
});
return;
}
if (typeof(n) === 'undefined') {
// Handled by .on('remove')
return;
}
}).on('remove', ['friends'], function (o, p) {
var curvePublic = p[1];
if (!curvePublic) { return; }
if (p[2] !== 'channel') { return; }
var channel = channels[o];
channel.wc.leave(Types.unfriend);
delete channels[channel.id];
emit('UNFRIEND', {
curvePublic: curvePublic,
fromMe: true
});
});
// Friend added in our contacts in the current worker
messenger.onFriendAdded = function (friendData) {
if (!allowFriendsChannels) { return; }
var friend = friends[friendData.curvePublic];
if (typeof(friend) !== 'object') { return; }
var channel = friend.channel;
@ -820,10 +788,23 @@ define([
});
});
};
messenger.onFriendRemoved = function (curvePublic, chanId) {
var channel = channels[chanId];
if (!channel) { return; }
if (channel.wc) {
channel.wc.leave(Types.unfriend);
}
delete channels[channel.id];
emit('UNFRIEND', {
curvePublic: curvePublic,
fromMe: true
});
};
var ready = false;
var initialized = false;
var init = function () {
allowFriendsChannels = true;
if (initialized) { return; }
initialized = true;
var friends = getFriendList(proxy);

@ -2610,7 +2610,8 @@ define([
UIElements.displayFriendRequestModal = function (common, data) {
var msg = data.content.msg;
var text = Messages._getKey('contacts_request', [msg.content.displayName]);
UI.confirm(text, function (yes) {
var todo = function (yes) {
common.getSframeChannel().query("Q_ANSWER_FRIEND_REQUEST", {
data: data,
value: yes
@ -2621,10 +2622,32 @@ define([
}
UI.log(Messages.contacts_added);
});
};
var content = h('div.cp-share-modal', [
setHTML(h('p'), text)
]);
var buttons = [{
name: Messages.cancel, // XXX "later"?
onClick: function () {},
keys: [27]
}, {
className: 'primary',
name: "Accept (Enter)", // XXX
onClick: function () {
todo(true);
},
keys: [13]
}, {
ok: 'Accept', // XXX
cancel: 'Ignore the request' // XXX
}, true);
className: 'primary',
name: "Ignore the request", // XXX
onClick: function () {
todo(false);
},
keys: [[13, 'ctrl']]
}];
var modal = UI.dialog.customModal(content, {buttons: buttons});
UI.openCustomModal(modal);
};
return UIElements;

@ -0,0 +1,50 @@
define([
'jquery',
'/common/hyperscript.js',
'/common/common-ui-elements.js'
], function ($, h, UIElements) {
var handlers = {};
handlers['FRIEND_REQUEST'] = function (common, data, el) {
var content = data.content;
var msg = content.msg;
// Check authenticity
if (msg.author !== msg.content.curvePublic) { return; }
common.addFriendRequest(data);
// Display the notification
$(el).find('.cp-notification-dismiss').attr('title', 'IGNORE').css('display', 'flex'); // XXX
$(el).find('.cp-notification-content').addClass("cp-clickable");
$(el).find('.cp-notification-content p')
.html('New friend request: <b>'+msg.content.displayName+'</b>') // XXX
.click(function () {
UIElements.displayFriendRequestModal(common, data);
});
};
handlers['ACCEPT_FRIEND_REQUEST'] = function (common, data, el) {
var content = data.content;
var msg = content.msg;
$(el).find('.cp-notification-content p')
.html('Friend request accepted: <b>'+msg.content.displayName+'</b>');
$(el).find('.cp-notification-dismiss').css('display', 'flex');
};
return {
add: function (common, data, el) {
var type = data.content.msg.type;
if (handlers[type]) {
handlers[type](common, data, el);
} else {
$(el).find('.cp-notification-dismiss').css('display', 'flex');
}
},
remove: function (common, data) {
common.removeFriendRequest(data.hash);
},
};
});

@ -639,7 +639,7 @@ define([
/*store.mailbox.post('notifications', 'NAME_CHANGED', {
old: store.proxy[Constants.displayNameKey],
new: value
});*/
});
Object.keys(store.proxy.friends).forEach(function (curve) {
var f = store.proxy.friends[curve];
if (!f.notifications) { return; }
@ -653,7 +653,7 @@ define([
if (obj && obj.error) { return void console.error(obj.error); }
console.log('notif sent to '+f);
});
});
});*/
}
store.proxy[Constants.displayNameKey] = value;
broadcast([clientId], "UPDATE_METADATA");
@ -911,7 +911,6 @@ define([
// Messaging (manage friends from the userlist)
Store.answerFriendRequest = function (clientId, obj, cb) {
console.log(obj);
var value = obj.value;
var data = obj.data;
if (data.type !== 'notifications') { return void cb ({error: 'EINVAL'}); }
@ -926,6 +925,7 @@ define([
}, cb);
};
// If we accept the request, add the friend to the list
if (value) {
Messaging.acceptFriendRequest(store, msg.content, function (obj) {
if (obj && obj.error) { return void cb(obj); }
@ -934,6 +934,9 @@ define([
realtime: store.realtime,
pinPads: function (data, cb) { Store.pinPads(null, data, cb); },
}, msg.content, function (err) {
if (store.messenger) {
store.messenger.onFriendAdded(msg.content);
}
broadcast([], "UPDATE_METADATA");
if (err) { return void cb({error: err}); }
dismiss(cb);
@ -941,6 +944,7 @@ define([
});
return;
}
// Otherwise, just remove the notification
dismiss();
};
Store.sendFriendRequest = function (clientId, data, cb) {
@ -1445,7 +1449,9 @@ define([
};
var loadMessenger = function () {
if (AppConfig.availablePadTypes.indexOf('contacts') === -1) { return; }
var messenger = store.messenger = Messenger.messenger(store);
var messenger = store.messenger = Messenger.messenger(store, function () {
broadcast([], "UPDATE_METADATA");
});
messenger.on('event', function (ev, data) {
sendMessengerEvent('CHAT_EVENT', {
ev: ev,
@ -1496,6 +1502,18 @@ define([
});
};
var cleanFriendRequests = function () {
try {
if (!store.proxy.friends_pending) { return; }
var twoDaysAgo = +new Date() - (2 * 24 * 3600 * 1000); // XXX
Object.keys(store.proxy.friends_pending).forEach(function (curve) {
if (store.proxy.friends_pending[curve] < twoDaysAgo) {
delete store.proxy.friends_pending[curve];
}
});
} catch (e) {}
};
//////////////////////////////////////////////////////////////////
/////////////////////// Init /////////////////////////////////////
//////////////////////////////////////////////////////////////////
@ -1591,6 +1609,7 @@ define([
loadCursor();
loadOnlyOffice();
loadMailbox(waitFor);
cleanFriendRequests();
}).nThen(function () {
var requestLogin = function () {
broadcast([], "REQUEST_LOGIN");
@ -1644,14 +1663,32 @@ define([
// Trigger userlist update when the avatar has changed
broadcast([], "UPDATE_METADATA");
});
proxy.on('change', ['friends'], function () {
proxy.on('change', ['friends'], function (o, n, p) {
// Trigger userlist update when the friendlist has changed
broadcast([], "UPDATE_METADATA");
if (!store.messenger) { return; }
if (o !== undefined) { return; }
var curvePublic = p.slice(-1)[0];
var friend = proxy.friends && proxy.friends[curvePublic];
store.messenger.onFriendAdded(friend);
});
proxy.on('remove', ['friends'], function (o, p) {
broadcast([], "UPDATE_METADATA");
if (!store.messenger) { return; }
var curvePublic = p[1];
if (!curvePublic) { return; }
if (p[2] !== 'channel') { return; }
store.messenger.onFriendRemoved(curvePublic, o);
});
proxy.on('change', ['friends_pending'], function () {
// Trigger userlist update when the friendlist has changed
broadcast([], "UPDATE_METADATA");
});
proxy.on('remove', ['friends_pending'], function () {
broadcast([], "UPDATE_METADATA");
});
proxy.on('change', ['settings'], function () {
broadcast([], "UPDATE_METADATA");
});

@ -0,0 +1,52 @@
define([
'/common/common-messaging.js',
], function (Messaging) {
var handlers = {};
handlers['FRIEND_REQUEST'] = function (ctx, data, cb) {
if (data.msg.author === data.msg.content.curvePublic &&
Messaging.getFriend(ctx.store.proxy, data.msg.author)) {
Messaging.acceptFriendRequest(ctx.store, data.msg.content, function (obj) {
if (obj && obj.error) { return void cb(); }
cb(true);
});
return;
}
cb();
};
handlers['ACCEPT_FRIEND_REQUEST'] = function (ctx, box, data, cb) {
// Our friend request was accepted.
// Make sure we really sent it
if (!ctx.store.proxy.friends_pending[data.msg.author]) { return void cb(); }
// And add the friend
Messaging.addToFriendList({
proxy: ctx.store.proxy,
realtime: ctx.store.realtime,
pinPads: ctx.pinPads
}, data.msg.content, function (err) {
if (err) { console.error(err); }
delete ctx.store.proxy.friends_pending[data.msg.author];
if (ctx.store.messenger) {
ctx.store.messenger.onFriendAdded(data.msg.content);
}
ctx.updateMetadata();
});
cb();
};
return function (ctx, box, data, cb) {
var type = data.msg.type;
if (handlers[type]) {
try {
handlers[type](ctx, box, data, cb);
} catch (e) {
cb();
}
} else {
cb();
}
};
});

@ -347,11 +347,11 @@ proxy.mailboxes = {
if (BLOCKING_TYPES.indexOf(key) === -1) {
openChannel(ctx, key, m, function () {
updateLastKnownHash(ctx, key);
console.log(key + ' mailbox is ready');
//console.log(key + ' mailbox is ready');
});
} else {
openChannel(ctx, key, m, waitFor(function () {
console.log(key + ' mailbox is ready');
//console.log(key + ' mailbox is ready');
}));
}
});

@ -3,9 +3,10 @@ define([
'/common/common-util.js',
'/common/common-interface.js',
'/common/common-ui-elements.js',
'/common/notifications.js',
'/common/hyperscript.js',
'/customize/messages.js'
], function ($, Util, UI, UIElements, h, Messages) {
], function ($, Util, UI, UIElements, Notifications, h, Messages) {
var Mailbox = {};
Messages = Messages; // XXX
@ -87,6 +88,7 @@ define([
var todo = function (f) {
try {
var el = createElement(data);
Notifications.add(Common, data, el);
f(data, el);
} catch (e) {
console.error(e);
@ -103,6 +105,7 @@ define([
onViewedHandlers.forEach(function (f) {
try {
f(data);
Notifications.remove(Common, data);
} catch (e) {
console.error(e);
}
@ -165,7 +168,7 @@ define([
});
execCommand('SUBSCRIBE', null, function () {
console.log('subscribed');
//console.log('subscribed');
});
return mailbox;

@ -392,10 +392,17 @@ define([
var friendRequests = {};
funcs.addFriendRequest = function (data) {
var curve = Util.find(data, ['content', 'msg', 'author']);
console.log(data);
console.log(curve);
friendRequests[curve] = data;
};
funcs.removeFriendRequest = function (hash) {
Object.keys(friendRequests).some(function (curve) {
var h = Util.find(friendRequests[curve], ['content', 'hash']);
if (h === hash) {
delete friendRequests[curve];
return true;
}
});
};
funcs.getFriendRequests = function () {
return JSON.parse(JSON.stringify(friendRequests));
};

@ -8,11 +8,10 @@ define([
'/common/common-util.js',
'/common/common-feedback.js',
'/common/hyperscript.js',
'/common/notifications.js',
'/common/messenger-ui.js',
'/customize/messages.js',
], function ($, Config, ApiConfig, UIElements, UI, Hash, Util, Feedback, h,
Notifications, MessengerUI, Messages) {
MessengerUI, Messages) {
var Common;
var Bar = {
@ -235,9 +234,8 @@ Notifications, MessengerUI, Messages) {
// Editors
var pendingFriends = Common.getPendingFriends(); // Friend requests sent
var friendRequests = Common.getFriendRequests(); // Friend requests received
console.log(friendRequests);
var friendTo = +new Date() - (2 * 24 * 3600 * 1000);
friendTo = +new Date(); // XXX
//friendTo = +new Date(); // XXX
editUsersNames.forEach(function (data) {
var name = data.name || Messages.anonymous;
var $span = $('<span>', {'class': 'cp-avatar'});
@ -305,7 +303,6 @@ Notifications, MessengerUI, Messages) {
}
} else if (Common.isLoggedIn() && data.curvePublic && !friends[data.curvePublic]
&& !priv.readOnly) {
console.log(pendingFriends);
if (pendingFriends[data.curvePublic] && pendingFriends[data.curvePublic] > friendTo) {
$('<span>', {'class': 'cp-toolbar-userlist-friend'}).text(Messages.userlist_pending)
.appendTo($rightCol);
@ -950,10 +947,11 @@ Notifications, MessengerUI, Messages) {
return $userAdmin;
};
var createNotifications = function (toolbar) {
console.log(Common.mailbox);
var createNotifications = function (toolbar, config) {
var $notif = toolbar.$top.find('.'+NOTIFICATIONS_CLS).show();
var div = h('div.cp-notifications-container');
var div = h('div.cp-notifications-container', [
h('div.cp-notifications-empty', "Nothing new here") // XXX
]);
var pads_options = [div];
var dropdownConfig = {
text: '', // Button initial text
@ -963,15 +961,35 @@ Notifications, MessengerUI, Messages) {
common: Common
};
var $newPadBlock = UIElements.createDropdown(dropdownConfig);
$newPadBlock.find('button').attr('title', Messages.mailbox_title); // XXX
$newPadBlock.find('button').addClass('fa fa-bell-o');
var $button = $newPadBlock.find('button');
$button.attr('title', Messages.mailbox_title); // XXX
$button.addClass('fa fa-bell-o');
var $n = $button.find('.cp-dropdown-button-title').hide();
var $empty = $(div).find('.cp-notifications-empty');
var refresh = function () {
updateUserList(toolbar, config);
var n = $(div).find('.cp-notification').length;
$button.removeClass('fa-bell-o').removeClass('fa-bell');
if (n === 0) {
$empty.show();
$n.hide();
return void $button.addClass('fa-bell-o');
}
$empty.hide();
$n.text(n).show();
$button.addClass('fa-bell');
};
Common.mailbox.subscribe({
onMessage: function (data, el) {
if (el) {
Notifications(Common, data, el);
div.appendChild(el);
}
refresh();
},
onViewed: function (data) {
refresh();
}
});

Loading…
Cancel
Save