Mute friends: dismiss notifications and fix UI issues

pull/1/head
yflory 5 years ago
parent bbf2e3a9ae
commit 11ddb96422

@ -580,6 +580,7 @@ define([
}]; }];
var modal = dialog.customModal(content, {buttons: buttons}); var modal = dialog.customModal(content, {buttons: buttons});
UI.openCustomModal(modal); UI.openCustomModal(modal);
return modal;
}; };
UI.log = function (msg) { UI.log = function (msg) {

@ -84,6 +84,7 @@ define([
var myData = createData(store.proxy, false); var myData = createData(store.proxy, false);
if (store.proxy.friends) { if (store.proxy.friends) {
store.proxy.friends.me = myData; store.proxy.friends.me = myData;
delete store.proxy.friends.me.channel;
} }
if (store.modules['team']) { if (store.modules['team']) {
store.modules['team'].updateMyData(myData); store.modules['team'].updateMyData(myData);

@ -3803,10 +3803,20 @@ define([
}); });
}; };
var modal;
var mute = UIElements.createMuteButton(common, msg.content, function () {
// Mute = auto-reject friend request
var $modal = modal && $(modal) && $(modal).closest('div.alertify');
if ($modal && $modal.length && $modal[0].closeModal) {
$modal[0].closeModal(function () {});
}
return void todo(false); // XXX false is reject. We can also "dismiss"...
});
var content = h('div.cp-share-modal', [ var content = h('div.cp-share-modal', [
setHTML(h('p'), text) setHTML(h('p'), text),
h('p', mute)
]); ]);
UI.proposal(content, todo); modal = UI.proposal(content, todo);
}; };
UIElements.displayAddOwnerModal = function (common, data) { UIElements.displayAddOwnerModal = function (common, data) {
@ -4148,5 +4158,28 @@ define([
UI.proposal(div, todo); UI.proposal(div, todo);
}; };
UIElements.createMuteButton = function (common, data, cb) {
cb = cb || function () {};
var button = h('i.fa.fa-bell-slash-o', {
title: Messages.notifications_muteUserTitle
});
var module = common.makeUniversal('messenger');
$(button).click(function () {
UI.confirm(Messages.notifications_muteUserConfirm, function (yes) {
if (!yes) { return; }
module.execCommand('MUTE_USER', {
curvePublic: data.curvePublic,
name: data.displayName || data.name,
avatar: data.avatar
}, function (e) {
cb(e);
if (e) { return void UI.warn(Messages.error); }
UI.log(Messages.success);
});
});
});
return button;
};
return UIElements; return UIElements;
}); });

@ -186,7 +186,7 @@ define([
markup.message = function (msg) { markup.message = function (msg) {
if (msg.type !== 'MSG') { return; } if (msg.type !== 'MSG') { return; }
var curvePublic = msg.author; var curvePublic = msg.author;
var name = typeof msg.name !== "undefined" ? var name = (typeof msg.name !== "undefined" || !contactsData[msg.author]) ?
(msg.name || Messages.anonymous) : (msg.name || Messages.anonymous) :
contactsData[msg.author].displayName; contactsData[msg.author].displayName;
var d = msg.time ? new Date(msg.time) : undefined; var d = msg.time ? new Date(msg.time) : undefined;
@ -548,7 +548,7 @@ define([
UI.confirm(content, function (yes) { UI.confirm(content, function (yes) {
if (!yes) { return; } if (!yes) { return; }
var mute = Util.isChecked($(content).find('#cp-contacts-mute')); var mute = Util.isChecked($(content).find('#cp-contacts-mute'));
muteUser(friend); if (mute) { muteUser(friend); }
removeFriend(curvePublic); removeFriend(curvePublic);
// TODO remove friend from userlist ui // TODO remove friend from userlist ui
// FIXME seems to trigger EJOINED from netflux-websocket (from server); // FIXME seems to trigger EJOINED from netflux-websocket (from server);
@ -806,37 +806,27 @@ define([
// var onJoinRoom // var onJoinRoom
// var onLeaveRoom // var onLeaveRoom
var updateMutedList = function () {
var ready = false;
var onMessengerReady = function () {
if (isApp) { return; }
if (ready) { return; }
ready = true;
execCommand('GET_ROOMS', null, function (err, rooms) {
if (err) { return void console.error(err); }
debug('rooms: ' + JSON.stringify(rooms));
rooms.forEach(initializeRoom);
});
execCommand('GET_MUTED_USERS', null, function (err, muted) { execCommand('GET_MUTED_USERS', null, function (err, muted) {
if (err) { return void console.error(err); } if (err) { return void console.error(err); }
if (!muted || Object.keys(muted).length === 0) { return; }
var $button = $userlist.find('.cp-app-contacts-muted-button'); var $button = $userlist.find('.cp-app-contacts-muted-button');
if (!muted || Object.keys(muted).length === 0) {
$button.hide();
return;
}
var rows = Object.keys(muted).map(function (curve) { var rows = Object.keys(muted).map(function (curve) {
var data = muted[curve]; var data = muted[curve];
var avatar = h('div.cp-avatar'); var avatar = h('div.cp-avatar');
var button = h('td', h('i.fa.fa-times', {title: Messages.contacts_unmute})); var button = h('td', h('i.fa.fa-times', {title: Messages.contacts_unmute}));
UIElements.displayAvatar(common, $(avatar), data.avatar, data.name); UIElements.displayAvatar(common, $(avatar), data.avatar, data.name);
$(button).click(function () { $(button).click(function () {
execCommand('UNMUTE_USER', { execCommand('UNMUTE_USER', curve, function (e, data) {
curvePublic: curve,
}, function (e /*, removed */) {
if (e) { return void console.error(e); } if (e) { return void console.error(e); }
$(button).closest('tr').remove(); $(button).closest('tr').remove();
if (!data) { $button.hide(); }
}); });
}); });
return h('tr', [ return h('tr', [
@ -849,10 +839,27 @@ define([
h('p', Messages.contacts_mutedUsers), h('p', Messages.contacts_mutedUsers),
h('table', rows) h('table', rows)
]); ]);
$button.off('click');
$button.click(function () { $button.click(function () {
UI.alert(content); UI.alert(content);
}).show(); }).show();
}); });
};
var ready = false;
var onMessengerReady = function () {
if (isApp) { return; }
if (ready) { return; }
ready = true;
execCommand('GET_ROOMS', null, function (err, rooms) {
if (err) { return void console.error(err); }
debug('rooms: ' + JSON.stringify(rooms));
rooms.forEach(initializeRoom);
});
updateMutedList();
$container.removeClass('cp-app-contacts-initializing'); $container.removeClass('cp-app-contacts-initializing');
}; };
@ -930,6 +937,10 @@ define([
onUpdateData(data); onUpdateData(data);
return; return;
} }
if (cmd === 'UPDATE_MUTED') {
updateMutedList();
return;
}
if (cmd === 'MESSAGE') { if (cmd === 'MESSAGE') {
onMessage(data); onMessage(data);
return; return;

@ -1253,6 +1253,10 @@ define([
if (friend) { return void cb({error: 'ALREADY_FRIEND'}); } if (friend) { return void cb({error: 'ALREADY_FRIEND'}); }
if (!data.notifications || !data.curvePublic) { return void cb({error: 'INVALID_USER'}); } if (!data.notifications || !data.curvePublic) { return void cb({error: 'INVALID_USER'}); }
// Unmute this user when we send them a friend request
var muted = store.proxy.mutedUsers || {};
delete muted[data.curvePublic];
store.proxy.friends_pending = store.proxy.friends_pending || {}; store.proxy.friends_pending = store.proxy.friends_pending || {};
var twoDaysAgo = +new Date() - (2 * 24 * 3600 * 1000); var twoDaysAgo = +new Date() - (2 * 24 * 3600 * 1000);

@ -12,6 +12,13 @@ define([
var handlers = {}; var handlers = {};
var removeHandlers = {}; var removeHandlers = {};
var isMuted = function (ctx, data) {
var muted = ctx.store.proxy.mutedUsers || {};
var curvePublic = Util.find(data, ['msg', 'author']);
if (!curvePublic) { return false; }
return Boolean(muted[curvePublic]);
};
// Store the friend request displayed to avoid duplicates // Store the friend request displayed to avoid duplicates
var friendRequest = {}; var friendRequest = {};
handlers['FRIEND_REQUEST'] = function (ctx, box, data, cb) { handlers['FRIEND_REQUEST'] = function (ctx, box, data, cb) {
@ -21,6 +28,8 @@ define([
return void cb(true); return void cb(true);
} }
if (isMuted(ctx, data)) { return void cb(true); }
// Don't show duplicate friend request: if we already have a friend request // Don't show duplicate friend request: if we already have a friend request
// in memory from the same user, dismiss the new one // in memory from the same user, dismiss the new one
if (friendRequest[data.msg.author]) { return void cb(true); } if (friendRequest[data.msg.author]) { return void cb(true); }
@ -30,10 +39,22 @@ define([
// If the user is already in our friend list, automatically accept the request // If the user is already in our friend list, automatically accept the request
if (Messaging.getFriend(ctx.store.proxy, data.msg.author) || if (Messaging.getFriend(ctx.store.proxy, data.msg.author) ||
ctx.store.proxy.friends_pending[data.msg.author]) { ctx.store.proxy.friends_pending[data.msg.author]) {
delete ctx.store.proxy.friends_pending[data.msg.author];
Messaging.acceptFriendRequest(ctx.store, data.msg.content, function (obj) { Messaging.acceptFriendRequest(ctx.store, data.msg.content, function (obj) {
if (obj && obj.error) { if (obj && obj.error) {
return void cb(); return void cb();
} }
Messaging.addToFriendList({
proxy: ctx.store.proxy,
realtime: ctx.store.realtime,
pinPads: ctx.pinPads
}, data.msg.content, function (err) {
if (err) { console.error(err); }
if (ctx.store.messenger) {
ctx.store.messenger.onFriendAdded(data.msg.content);
}
});
ctx.updateMetadata();
cb(true); cb(true);
}); });
return; return;
@ -170,6 +191,8 @@ define([
var content = msg.content; var content = msg.content;
// content.name, content.title, content.href, content.password // content.name, content.title, content.href, content.password
if (isMuted(ctx, data)) { return void cb(true); }
var channel = Hash.hrefToHexChannelId(content.href, content.password); var channel = Hash.hrefToHexChannelId(content.href, content.password);
var parsed = Hash.parsePadUrl(content.href); var parsed = Hash.parsePadUrl(content.href);
var mode = parsed.hashData && parsed.hashData.mode || 'n/a'; var mode = parsed.hashData && parsed.hashData.mode || 'n/a';
@ -212,6 +235,9 @@ define([
supportMessage = true; supportMessage = true;
cb(); cb();
}; };
removeHandlers['SUPPORT_MESSAGE'] = function () {
supportMessage = false;
};
// Incoming edit rights request: add data before sending it to inner // Incoming edit rights request: add data before sending it to inner
handlers['REQUEST_PAD_ACCESS'] = function (ctx, box, data, cb) { handlers['REQUEST_PAD_ACCESS'] = function (ctx, box, data, cb) {
@ -220,6 +246,8 @@ define([
if (msg.author !== content.user.curvePublic) { return void cb(true); } if (msg.author !== content.user.curvePublic) { return void cb(true); }
if (isMuted(ctx, data)) { return void cb(true); }
var channel = content.channel; var channel = content.channel;
var res = ctx.store.manager.findChannel(channel); var res = ctx.store.manager.findChannel(channel);
@ -270,6 +298,9 @@ define([
var content = msg.content; var content = msg.content;
if (msg.author !== content.user.curvePublic) { return void cb(true); } if (msg.author !== content.user.curvePublic) { return void cb(true); }
if (isMuted(ctx, data)) { return void cb(true); }
if (!content.teamChannel && !(content.href && content.title && content.channel)) { if (!content.teamChannel && !(content.href && content.title && content.channel)) {
console.log('Remove invalid notification'); console.log('Remove invalid notification');
return void cb(true); return void cb(true);
@ -327,6 +358,9 @@ define([
var content = msg.content; var content = msg.content;
if (msg.author !== content.user.curvePublic) { return void cb(true); } if (msg.author !== content.user.curvePublic) { return void cb(true); }
if (isMuted(ctx, data)) { return void cb(true); }
if (!content.team) { if (!content.team) {
console.log('Remove invalid notification'); console.log('Remove invalid notification');
return void cb(true); return void cb(true);

@ -458,12 +458,22 @@ define([
} }
}; };
var getAllClients = function (ctx) {
var all = [];
Array.prototype.push.apply(all, ctx.friendsClients);
Object.keys(ctx.channels).forEach(function (id) {
Array.prototype.push.apply(all, ctx.channels[id].clients);
});
return Util.deduplicateString(all);
};
var muteUser = function (ctx, data, _cb) { var muteUser = function (ctx, data, _cb) {
var cb = Util.once(Util.mkAsync(_cb)); var cb = Util.once(Util.mkAsync(_cb));
var proxy = ctx.store.proxy; var proxy = ctx.store.proxy;
var muted = proxy.mutedUsers = proxy.mutedUsers || {}; var muted = proxy.mutedUsers = proxy.mutedUsers || {};
if (muted[data.curvePublic]) { return void cb(); } if (muted[data.curvePublic]) { return void cb(); }
muted[data.curvePublic] = data; muted[data.curvePublic] = data;
ctx.emit('UPDATE_MUTED', null, getAllClients(ctx));
cb(); cb();
}; };
var unmuteUser = function (ctx, curvePublic, _cb) { var unmuteUser = function (ctx, curvePublic, _cb) {
@ -471,7 +481,8 @@ define([
var proxy = ctx.store.proxy; var proxy = ctx.store.proxy;
var muted = proxy.mutedUsers = proxy.mutedUsers || {}; var muted = proxy.mutedUsers = proxy.mutedUsers || {};
delete muted[curvePublic]; delete muted[curvePublic];
cb(); ctx.emit('UPDATE_MUTED', null, getAllClients(ctx));
cb(Object.keys(muted).length);
}; };
var getMutedUsers = function (ctx, cb) { var getMutedUsers = function (ctx, cb) {
var proxy = ctx.store.proxy; var proxy = ctx.store.proxy;
@ -687,7 +698,14 @@ define([
nThen(function (waitFor) { nThen(function (waitFor) {
// Load or get all friends channels // Load or get all friends channels
Object.keys(friends).forEach(function (key) { Object.keys(friends).forEach(function (key) {
if (key === 'me') { return; } if (key === 'me') {
// At some point a bug inserted a friend's channel into our "me" data.
// This led to displaying our name instead of our friend's name in the
// contacts app. The following line is here to prevent this issue to happen
// again.
delete friends.me.channel;
return;
}
var friend = clone(friends[key]); var friend = clone(friends[key]);
if (typeof(friend) !== 'object') { return; } if (typeof(friend) !== 'object') { return; }
if (!friend.channel) { return; } if (!friend.channel) { return; }
@ -910,15 +928,6 @@ define([
}); });
}; };
var getAllClients = function (ctx) {
var all = [];
Array.prototype.push.apply(all, ctx.friendsClients);
Object.keys(ctx.channels).forEach(function (id) {
Array.prototype.push.apply(all, ctx.channels[id].clients);
});
return Util.deduplicateString(all);
};
Msg.init = function (cfg, waitFor, emit) { Msg.init = function (cfg, waitFor, emit) {
var messenger = {}; var messenger = {};
var store = cfg.store; var store = cfg.store;
@ -934,6 +943,9 @@ define([
range_requests: {} range_requests: {}
}; };
store.proxy.on('change', ['mutedUsers'], function () {
ctx.emit('UPDATE_MUTED', null, getAllClients(ctx));
});
ctx.store.network.on('message', function(msg, sender) { ctx.store.network.on('message', function(msg, sender) {
onDirectMessage(ctx, msg, sender); onDirectMessage(ctx, msg, sender);
@ -965,6 +977,12 @@ define([
var channel = friend.channel; var channel = friend.channel;
if (!channel) { return; } if (!channel) { return; }
// Already friend? don't load the channel a second time
var chanId = friend.channel;
var chan = ctx.channels[chanId];
if (chan) { return; }
// Load the channel and add the friend to the contacts app
loadFriend(ctx, null, friend, function () { loadFriend(ctx, null, friend, function () {
emit('FRIEND', { emit('FRIEND', {
curvePublic: friend.curvePublic, curvePublic: friend.curvePublic,

Loading…
Cancel
Save