Mute friends: dismiss notifications and fix UI issues
This commit is contained in:
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,6 +806,45 @@ define([
|
|||||||
// var onJoinRoom
|
// var onJoinRoom
|
||||||
// var onLeaveRoom
|
// 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 ready = false;
|
||||||
var onMessengerReady = function () {
|
var onMessengerReady = function () {
|
||||||
@ -820,39 +859,7 @@ define([
|
|||||||
rooms.forEach(initializeRoom);
|
rooms.forEach(initializeRoom);
|
||||||
});
|
});
|
||||||
|
|
||||||
execCommand('GET_MUTED_USERS', null, function (err, muted) {
|
updateMutedList();
|
||||||
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();
|
|
||||||
});
|
|
||||||
|
|
||||||
$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…
x
Reference in New Issue
Block a user