Mute friends: dismiss notifications and fix UI issues

This commit is contained in:
yflory 2019-12-10 13:07:57 +01:00
parent bbf2e3a9ae
commit 11ddb96422
7 changed files with 150 additions and 48 deletions

View file

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

View file

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

View file

@ -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', [
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) {
@ -4148,5 +4158,28 @@ define([
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;
});

View file

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

View file

@ -1253,6 +1253,10 @@ define([
if (friend) { return void cb({error: 'ALREADY_FRIEND'}); }
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 || {};
var twoDaysAgo = +new Date() - (2 * 24 * 3600 * 1000);

View file

@ -12,6 +12,13 @@ define([
var handlers = {};
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
var friendRequest = {};
handlers['FRIEND_REQUEST'] = function (ctx, box, data, cb) {
@ -21,6 +28,8 @@ define([
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
// in memory from the same user, dismiss the new one
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 (Messaging.getFriend(ctx.store.proxy, 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) {
if (obj && obj.error) {
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);
});
return;
@ -170,6 +191,8 @@ define([
var content = msg.content;
// 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 parsed = Hash.parsePadUrl(content.href);
var mode = parsed.hashData && parsed.hashData.mode || 'n/a';
@ -212,6 +235,9 @@ define([
supportMessage = true;
cb();
};
removeHandlers['SUPPORT_MESSAGE'] = function () {
supportMessage = false;
};
// Incoming edit rights request: add data before sending it to inner
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 (isMuted(ctx, data)) { return void cb(true); }
var channel = content.channel;
var res = ctx.store.manager.findChannel(channel);
@ -270,6 +298,9 @@ define([
var content = msg.content;
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)) {
console.log('Remove invalid notification');
return void cb(true);
@ -327,6 +358,9 @@ define([
var content = msg.content;
if (msg.author !== content.user.curvePublic) { return void cb(true); }
if (isMuted(ctx, data)) { return void cb(true); }
if (!content.team) {
console.log('Remove invalid notification');
return void cb(true);

View file

@ -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 cb = Util.once(Util.mkAsync(_cb));
var proxy = ctx.store.proxy;
var muted = proxy.mutedUsers = proxy.mutedUsers || {};
if (muted[data.curvePublic]) { return void cb(); }
muted[data.curvePublic] = data;
ctx.emit('UPDATE_MUTED', null, getAllClients(ctx));
cb();
};
var unmuteUser = function (ctx, curvePublic, _cb) {
@ -471,7 +481,8 @@ define([
var proxy = ctx.store.proxy;
var muted = proxy.mutedUsers = proxy.mutedUsers || {};
delete muted[curvePublic];
cb();
ctx.emit('UPDATE_MUTED', null, getAllClients(ctx));
cb(Object.keys(muted).length);
};
var getMutedUsers = function (ctx, cb) {
var proxy = ctx.store.proxy;
@ -687,7 +698,14 @@ define([
nThen(function (waitFor) {
// Load or get all friends channels
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]);
if (typeof(friend) !== 'object') { 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) {
var messenger = {};
var store = cfg.store;
@ -934,6 +943,9 @@ define([
range_requests: {}
};
store.proxy.on('change', ['mutedUsers'], function () {
ctx.emit('UPDATE_MUTED', null, getAllClients(ctx));
});
ctx.store.network.on('message', function(msg, sender) {
onDirectMessage(ctx, msg, sender);
@ -965,6 +977,12 @@ define([
var channel = friend.channel;
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 () {
emit('FRIEND', {
curvePublic: friend.curvePublic,