Merge remote-tracking branch 'origin/contacts-page' into 2026.4-rc

This commit is contained in:
yflory 2026-05-06 13:20:25 +02:00
commit 28c048a119
7 changed files with 451 additions and 131 deletions

View File

@ -157,7 +157,12 @@ define(req, function(AppConfig, Default, Language) {
}
};
return Messages;
Messages.contacts_muted = "Muted"; // XXX new key
Messages.contacts_noFriends = "Your contact list is empty";
Messages.contacts_noFriendsInfo = "Start by adding someone to begin a conversation.";
Messages.contacts_historyCleared = "The chat history has been deleted for both parties"; // XXX
Messages.contacts_confirmRemoveHistory = "Are you sure you want to delete chat history? Messages will be removed for everyone and cannot be restored."
return Messages; // XXX existing key
});
}());

View File

@ -7,6 +7,7 @@
@import (reference) './avatar.less';
@import (reference) './badges.less';
@import (reference) "./colortheme-all.less";
@import (reference) "./browser.less";
.messenger_vars (
@bg-color: @cp_messenger-bg,
@ -89,7 +90,6 @@
background-color: var(--msg-bg-color);
color: @msg-color;
color: var(--msg-color);
overflow-y: auto;
display: flex;
flex-flow: column;
.cp-app-contacts-friend {
@ -100,9 +100,15 @@
margin-bottom: 0;
cursor: pointer;
position: relative;
height: @room-height;
display: flex;
align-items: center;
overflow: hidden;
.cp-avatar {
flex-shrink: 0;
margin-right: 5px;
}
.cp-app-contacts-right-col {
margin-left: 5px;
margin-left: 0;
display: flex;
flex-flow: column;
flex: 1;
@ -112,13 +118,53 @@
overflow: hidden;
text-overflow: ellipsis;
}
.cp-app-contacts-icons {
text-align: right;
& > span:hover {
color: @msg-color-hover;
.cp-app-contacts-bottom-row {
display: flex;
align-items: center;
flex-shrink: 0;
.cp-app-contacts-mute-indicator {
font-size: 0.75em;
display: flex;
align-items: center;
}
svg {
margin-right: 0.1rem;
.cp-app-contacts-icons {
margin-left: auto;
.cp-app-contacts-dropdown-btn {
display: flex;
align-items: center;
background: none;
border: none;
color: inherit;
cursor: pointer;
padding: 2px;
border-radius: @variables_radius;
flex-shrink: 0;
&:hover {
background-color: var(--msg-bg-color-dark);
}
&:focus-visible {
outline: @variables_focus_style;
border-radius: @variables_radius;
}
svg {
margin: 0;
}
}
.cp-dropdown-content {
min-width: auto;
a {
display: flex;
align-items: center;
gap: 5px;
}
svg {
margin: 0;
}
li:focus-visible {
outline: @variables_focus_style;
border-radius: @variables_radius;
}
}
}
}
}
@ -134,6 +180,10 @@
border-color: var(--msg-bg-color-darker);
}
}
&:focus-visible {
outline: @variables_focus_style;
border-radius: @variables_radius;
}
&.cp-app-contacts-notify {
animation: notif 2s ease-in-out infinite;
}
@ -166,7 +216,7 @@
.cp-app-contacts-category-content {
order: 2;
display: flex;
flex-flow: column-reverse;
flex-flow: column;
padding-bottom: 10px;
&:empty {
display: none;
@ -236,6 +286,16 @@
}
}
&.cp-app-contacts-no-chats {
#cp-app-contacts-friendlist {
display: none;
}
#cp-app-contacts-messaging {
display: flex;
flex-direction: column;
}
}
#cp-app-contacts-messaging {
flex: 1;
height: 100%;
@ -245,6 +305,17 @@
.cp-app-contacts-info {
padding: 20px;
a {
color: @msg-color;
color: var(--msg-color);
&:focus-visible {
outline: none;
svg {
outline: @variables_focus_style;
border-radius: @variables_radius;
}
}
}
}
.cp-app-contacts-header {
background-color: @msg-bg-color-lighter;
@ -257,19 +328,17 @@
display: flex;
justify-content: space-between;
align-items: center;
height: 50px;
min-height: 50px;
svg {
margin-right: 0;
}
.hover () {
cursor: pointer;
height: 100%;
line-height: 30px;
padding: 10px;
border-radius: @variables_radius;
&:hover {
background-color: @msg-bg-color-darker;
background-color: var(--msg-color-darker);
background-color: var(--msg-bg-color-dark);
}
}
@ -277,9 +346,23 @@
.cp-app-contacts-right-col {
flex: 1 1 auto;
text-align: center;
min-width: 0;
.cp-app-contacts-name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.cp-app-contacts-right-col {
overflow: hidden;
}
.cp-app-contacts-remove-history {
.hover;
margin-right: 3px;
&:focus-visible {
outline: @variables_focus_style;
border-radius: @variables_radius;
}
}
.cp-avatar-container {
display: flex;
@ -294,6 +377,10 @@
&.cp-app-contacts-faded {
color: @cryptpad_text_col;
}
&:focus-visible {
outline: @variables_focus_style;
border-radius: @variables_radius;
}
}
.cp-app-contacts-header-title {
@ -320,60 +407,79 @@
height: 100%;
display: flex;
flex-flow: column;
.cp-app-contacts-history-cleared {
font-style: italic;
background-color: fade(@cp_help-bg, 50%);
padding: 2px 10px;
> svg {
flex-shrink: 0;
margin: 0;
}
}
.cp-app-contacts-messages {
padding: 0 20px;
margin: 10px 0;
padding: 0 10px;
margin: 10px 2px;
flex: 1;
overflow-x: auto;
&:focus-visible {
outline: @variables_focus_style;
border-radius: @variables_radius;
}
.cp-app-contacts-message {
display: flex;
flex-wrap: wrap;
& > div {
padding: 0 10px;
flex-direction: column;
.cp-app-contacts-sender {
margin-top: 10px;
font-weight: bold;
background-color: var(--msg-bg-color-dark);
display: flex;
justify-content: space-between;
border-radius: @variables_radius;
padding: 0 5px;
}
.cp-app-contacts-message-row {
display: flex;
align-items: flex-start;
}
.cp-app-contacts-content {
overflow: hidden;
word-wrap: break-word;
padding: 0 10px;
&> * {
margin: 0;
}
flex: 1;
min-width: 70%;
position: relative;
min-width: 0;
}
.cp-app-contacts-date {
display: none;
font-style: italic;
}
.cp-app-contacts-sender {
margin-top: 10px;
font-weight: bold;
background-color: rgba(0,0,0,0.1);
display: flex;
justify-content: space-between;
width: 100%;
}
.cp-app-contacts-time {
display: none;
display: flex;
font-size: 0.8em;
align-items: center;
align-items: flex-start;
justify-content: flex-end;
color: @msg-color;
font-weight: bold;
position: absolute;
right: 0;
top: 0;
bottom: 0;
background: rgba(0,0,0,0.3);
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
padding: 0 10px;
padding-right: 5px;
opacity: 0.4;
transition: opacity 0.2s ease;
flex-shrink: 0;
text-align: right;
white-space: nowrap;
}
&:hover {
.cp-app-contacts-time {
display: flex;
opacity: 1;
}
}
}
.cp-app-contacts-system-notification {
align-items: center;
flex-direction: row;
justify-content: center;
color: fade(@cryptpad_text_col, 80%);
}
}
}
.cp-app-contacts-input {
@ -386,7 +492,7 @@
justify-content: center;
padding: 0 5%;
textarea {
margin: 5px 0;
margin: 5px 2px 5px 0;
padding: 5px 10px;
border: none;
height: 54px; // 2 lines (22px height) + 2 margins (5px)
@ -411,6 +517,7 @@
color: @cp_messenger-fg;
background-color: @msg-bg-color-darker;
background-color: var(--msg-bg-color-darker);
border-radius: @variables_radius;
&:hover {
background-color: @msg-bg-color-dark;
background-color: var(--msg-bg-color-dark);
@ -425,4 +532,47 @@
}
}
}
.cp-app-contacts-back {
display: none;
cursor: pointer;
padding: 10px;
&:hover {
background-color: var(--msg-bg-color-dark);
border-radius: @variables_radius;
}
}
@media (max-width: @browser_media-medium-screen) {
#cp-app-contacts-container {
#cp-app-contacts-friendlist {
width: 100%;
flex: 1;
}
#cp-app-contacts-messaging {
display: none;
}
&.cp-app-contacts-chat-open {
#cp-app-contacts-friendlist {
display: none;
}
#cp-app-contacts-messaging {
display: flex;
flex-direction: column;
}
}
&.cp-app-contacts-no-chats {
#cp-app-contacts-friendlist {
display: none;
}
#cp-app-contacts-messaging {
display: flex;
flex-direction: column;
}
}
}
.cp-app-contacts-back {
display: flex;
}
}
}

View File

@ -15,6 +15,7 @@ const factory = (Crypto, Hash, Util, Realtime, Messaging,
var Types = {
message: 'MSG',
cleared: 'CLEARED',
unfriend: 'UNFRIEND',
mapId: 'MAP_ID',
mapIdAck: 'MAP_ID_ACK'
@ -270,6 +271,11 @@ const factory = (Crypto, Hash, Util, Realtime, Messaging,
return true;
}
var proxy = ctx.store.proxy;
if (parsedMsg[0] === Types.cleared) {
channel.messages = [];
ctx.emit('CLEAR_CHANNEL', channel.id, channel.clients);
return;
}
if (parsedMsg[0] === Types.unfriend) {
curvePublic = parsedMsg[1];
@ -916,11 +922,21 @@ const factory = (Crypto, Hash, Util, Realtime, Messaging,
var channel = ctx.channels[id];
if (!channel) { return void cb({error: 'NO_CHANNEL'}); }
if (!ctx.store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
var proxy = ctx.store.proxy || {};
ctx.store.rpc.clearOwnedChannel(id, function (err) {
cb({error:err});
if (!err) {
channel.messages = [];
ctx.emit('CLEAR_CHANNEL', id, channel.clients);
var msg = [Types.cleared, proxy.curvePublic, +new Date()];
var msgStr = JSON.stringify(msg);
var cryptMsg = channel.encrypt(msgStr);
channel.wc.bcast(cryptMsg).then(function () {
// Success (message sent)
}, function (err) {
console.error('Failed to send message:', err);
});
}
});
};

View File

@ -12,7 +12,8 @@ define([
'/common/hyperscript.js',
'/common/diffMarked.js',
'/common/common-icons.js',
], function ($, Messages, Util, UI, UIElements, Badges, h, DiffMd, Icons) {
'/customize/pages.js',
], function ($, Messages, Util, UI, UIElements, Badges, h, DiffMd, Icons, Pages) {
'use strict';
var debug = console.log;
@ -64,7 +65,6 @@ define([
h('h2', Messages.contacts_info1),
h('ul', [
h('li', Messages.contacts_info2),
h('li', Messages.contacts_info3),
h('li', Messages.contacts_info4),
])
])
@ -76,11 +76,11 @@ define([
h('div.cp-app-contacts-category-content')
]),
h('div.cp-app-contacts-friends.cp-app-contacts-category', [
h('div.cp-app-contacts-category-content.cp-contacts-friends'),
h('button.btn.btn-default.cp-app-contacts-muted-button', {tabindex:0},[
Icons.get('mute'),
Messages.contacts_manageMuted
]),
h('div.cp-app-contacts-category-content.cp-contacts-friends')
])
]),
h('div.cp-app-contacts-rooms.cp-app-contacts-category', [
h('div.cp-app-contacts-category-content'),
@ -150,13 +150,14 @@ define([
var channels = Object.keys(state.channels).sort(function (a, b) {
var m1 = state.channels[a].messages.slice(-1)[0];
var m2 = state.channels[b].messages.slice(-1)[0];
if (!m2) { return !m1 ? 0 : 1; }
if (!m1) { return -1; }
return m1.time - m2.time;
if (!m2) { return !m1 ? 0 : -1; }
if (!m1) { return 1; }
return m2.time - m1.time;
});
channels.forEach(function (c, i) {
$userlist.find(dataQuery(c)).css('order', i);
channels.forEach(function (c) {
var $el = $userlist.find(dataQuery(c));
$el.appendTo($el.parent());
});
// Make sure the width is correct even if there is a scrollbar
@ -184,7 +185,8 @@ define([
});
var time = h('div.cp-app-contacts-time', hour);
$d.append(time);
var row = h('div.cp-app-contacts-message-row', [d, time]);
return row;
} catch (e) {
console.error(md);
console.error(e);
@ -239,19 +241,44 @@ define([
};
var clearChannel = function (id) {
$(getChat(id)).find('.cp-app-contacts-messages').html('');
var $chat = $(getChat(id));
if (state.channels && state.channels[id]) {
state.channels[id].messages = [];
}
if ($chat.length) {
$chat.find('.cp-app-contacts-messages').html('');
$chat.find('.cp-app-contacts-message').remove();
}
};
var displaySystemMessage = function (id, message, icon) {
var $messagebox = $(getChat(id)).find('.cp-app-contacts-messages');
if (!$messagebox.length) { return; }
var content = icon ? [Icons.get(icon), h('span', message)] : message;
$messagebox.append(h('div.cp-app-contacts-message.cp-app-contacts-system-notification', content));
normalizeLabels($messagebox);
scrollChatToBottom();
};
markup.chatbox = function (id, data, curvePublic) {
var moreHistory = h('span', {
class: 'cp-app-contacts-more-history',
tabindex: '0',
role: 'button',
'aria-label': Messages.contacts_fetchHistory,
title: Messages.contacts_fetchHistory
});
moreHistory.append(Icons.get('history', {title: Messages.contacts_fetchHistory}));
moreHistory.append(Icons.get('history'));
var chan = state.channels[id];
var displayName = UI.getDisplayName(chan.name || chan.displayName);
var fetching = false;
var $moreHistory = $(moreHistory).click(function () {
var $moreHistory = $(moreHistory).on('keydown', function (e) {
if (e.which === 13 || e.which === 32) {
e.preventDefault();
$(this).click();
}
}).click(function () {
if (fetching) { return; }
// get oldest known message...
@ -308,11 +335,20 @@ define([
});
var removeHistory = h('span', {
'class': 'cp-app-contacts-remove-history'
'class': 'cp-app-contacts-remove-history',
'tabindex': '0',
'role': 'button',
'aria-label': Messages.contacts_removeHistoryTitle,
'title': Messages.contacts_removeHistoryTitle
});
removeHistory.append(Icons.get('remove-history', {title: Messages.contacts_removeHistoryTitle}));
removeHistory.append(Icons.get('remove-history'));
$(removeHistory).click(function () {
$(removeHistory).on('keydown', function (e) {
if (e.which === 13 || e.which === 32) {
e.preventDefault();
$(this).click();
}
}).click(function () {
UI.confirm(Messages.contacts_confirmRemoveHistory, function (yes) {
if (!yes) { return; }
@ -322,6 +358,7 @@ define([
UI.alert(Messages.contacts_removeHistoryServerError);
return;
}
clearChannel(id);
});
});
});
@ -329,13 +366,23 @@ define([
var avatar = h('div.cp-avatar');
var avatarDiv = h('div.cp-avatar-container', avatar);
var backButton = h('span.cp-app-contacts-back', {
'aria-label': Messages.form_backButton,
title: Messages.form_backButton,
}, Icons.get('arrow-left'));
$(backButton).click(function () {
$container.removeClass('cp-app-contacts-chat-open');
});
var headerContent = [
backButton,
avatarDiv,
moreHistory,
data.isFriendChat ? removeHistory : undefined
];
if (isApp) {
headerContent = [
backButton,
h('div.cp-app-contacts-header-title', Messages.contacts_padTitle),
moreHistory
];
@ -363,6 +410,7 @@ define([
});
var sendButton = h('button.btn.btn-primary', {
title: Messages.contacts_send,
'aria-label': Messages.contacts_send
}, Icons.get('send'));
var rightCol = h('span.cp-app-contacts-right-col', [
@ -456,6 +504,32 @@ define([
$messages.find('.cp-app-contacts-info').show();
};
var updateInfoMessage = function () {
var chats = Object.keys(state.channels).length;
var $info = $messages.find('.cp-app-contacts-info');
if (chats === 0) {
$info.html([
h('h2', Messages.contacts_noFriends),
h('ul', [
h('li', [
UI.createHelper(Pages.localizeDocsLink(' https://docs.cryptpad.org/en/user_guide/collaboration.html#contacts'), Messages.contacts_noFriendsInfo),
Messages.contacts_noFriendsInfo
]),
])
]);
$container.addClass('cp-app-contacts-no-chats');
} else {
$info.html([
h('h2', Messages.contacts_info1),
h('ul', [
h('li', Messages.contacts_info2),
h('li', Messages.contacts_info4),
])
]);
$container.removeClass('cp-app-contacts-no-chats');
}
};
var updateStatus = function (id) {
if (!state.channels[id]) { return; }
var $status = find.inList(id).find('.cp-app-contacts-status');
@ -491,6 +565,7 @@ define([
setActive(chanId);
unnotify(chanId);
$container.addClass('cp-app-contacts-chat-open');
var $chat = getChat(chanId);
hideInfo();
$messages.find('div.cp-app-contacts-chat[data-key]').hide();
@ -534,6 +609,7 @@ define([
'tabindex': '0',
'data-key': id,
'data-user': room.isFriendChat ? userlist[0].curvePublic : '',
'aria-label': room.isFriendChat ? UI.getDisplayName(room.name) : room.name
});
@ -543,85 +619,145 @@ define([
curve = __channel.curvePublic;
}
var unmute = h('span', Icons.get('notification'), {
class: 'cp-app-contacts-remove cp-unmute-icon',
title: Messages.contacts_unmute || 'unmute',
style: (curve && mutedUsers[curve]) ? undefined : 'display: none;'
var isMuted = curve && mutedUsers[curve];
var friendData = room.isFriendChat ? userlist[0] : {};
var dropdownOptions = [];
var removeOption = {
tag: 'a',
content: [Icons.get('unfriend'), h('span', Messages.contacts_remove)],
action: function () {
var channel = state.channels[id];
if (!channel.isFriendChat) {
UI.warn(Messages.error);
return;
}
var curvePublic = channel.curvePublic;
var friend = contactsData[curvePublic] || friendData;
var name = Util.fixHTML(UI.getDisplayName(friend.name || friend.displayName));
var content = h('div', [
UI.setHTML(h('p'), Messages._getKey('contacts_confirmRemove', [ name ])),
]);
UI.confirm(content, function (yes) {
if (!yes) { return; }
removeFriend(curvePublic);
// TODO remove friend from userlist ui
// FIXME seems to trigger EJOINED from netflux-websocket (from server);
// (tried to join a channel in which you were already present)
});
return true;
}
};
var viewProfileOption = {
tag: 'a',
content: [Icons.get('user-profile'), h('span', Messages.userlist_visitProfile)],
action: function () {
if (friendData.profile) { window.open(origin + '/profile/#' + friendData.profile); }
return true;
}
};
var rebuildDropdown = function () {
if (!$dropdown || !$dropdown.setOptions) { return; }
var opts = [];
if (room.isFriendChat) {
var isCurrentlyMuted = curve && mutedUsers[curve];
opts.push(isCurrentlyMuted ? unmuteOption : muteOption);
if (friendData.profile) {
opts.push(viewProfileOption);
}
opts.push(removeOption);
}
$dropdown.setOptions(opts);
$dropdown.find('.cp-dropdown-content').hide();
};
var muteOption = {
tag: 'a',
content: [Icons.get('mute'), h('span', Messages.contacts_mute)],
action: function () {
var channel = state.channels[id];
if (!channel.isFriendChat) { return true; }
var curvePublic = channel.curvePublic;
var friend = contactsData[curvePublic] || friendData;
muteUser(friend);
rebuildDropdown();
return true;
}
};
var unmuteOption = {
tag: 'a',
content: [Icons.get('notification'), h('span', Messages.contacts_unmute || 'Unmute')],
action: function () {
var channel = state.channels[id];
if (!channel.isFriendChat) { return true; }
var curvePublic = channel.curvePublic;
unmuteUser(curvePublic);
rebuildDropdown();
return true;
}
};
if (room.isFriendChat) {
dropdownOptions.push(isMuted ? unmuteOption : muteOption);
if (friendData.profile) {
dropdownOptions.push(viewProfileOption);
}
dropdownOptions.push(removeOption);
}
var $dropdown = UIElements.createDropdown({
iconCls: 'settings',
options: dropdownOptions,
buttonCls: 'cp-app-contacts-dropdown-btn',
buttonTitle: Messages.settingsButton
});
var mute = h('span', Icons.get('mute'), {
class: 'cp-app-contacts-remove cp-mute-icon',
title: Messages.contacts_mute || 'mute',
style: (curve && mutedUsers[curve]) ? 'display: none;' : undefined
$dropdown.addClass('cp-app-contacts-icons');
$dropdown.on('click dblclick', function (e) {
e.stopPropagation();
});
var remove = h('span', Icons.get('unfriend', {
class: 'cp-app-contacts-remove',
title: Messages.contacts_remove
}));
var leaveRoom = h('span', Icons.get('logout', {
class: 'cp-app-contacts-remove',
title: Messages.contacts_leaveRoom
}));
var $dropdownMenu = $dropdown.find('.cp-dropdown-content');
$dropdownMenu.css('position', 'fixed');
$dropdown.find('button').on('click', function () {
rebuildDropdown();
var rect = this.getBoundingClientRect();
var menuWidth = $dropdownMenu.outerWidth() || 150;
var viewportWidth = window.innerWidth;
var left = rect.left;
if (left + menuWidth > viewportWidth) {
left = rect.right - menuWidth;
}
if (left < 0) { left = 0; }
$dropdownMenu.css({
top: rect.bottom + 'px',
left: left + 'px',
});
});
var status = h('span.cp-app-contacts-status', {
title: Messages.contacts_online
});
var mute = h('span.cp-app-contacts-mute-indicator', {
title: Messages.contacts_muted,
style: isMuted ? '' : 'display: none;'
}, Icons.get('mute'));
var bottomRow = h('span.cp-app-contacts-bottom-row', [
mute,
$dropdown[0],
]);
var rightCol = h('span.cp-app-contacts-right-col', [
h('span.cp-app-contacts-name', [room.isFriendChat? UI.getDisplayName(room.name): room.name]),
h('span.cp-app-contacts-icons', [
room.isFriendChat ? mute : undefined,
room.isFriendChat ? unmute : undefined,
room.isFriendChat ? remove :
(room.isPadChat || room.isTeamChat) ? undefined : leaveRoom,
])
bottomRow,
]);
var friendData = room.isFriendChat ? userlist[0] : {};
var $room = $(roomEl).on('click keypress', function (event) {
if (event.type === 'click' || (event.type === 'keypress' && event.which === 13)) {
display(id);
}
}).dblclick(function () {
if (friendData.profile) { window.open(origin + '/profile/#' + friendData.profile); }
});
$(unmute).on('click dblclick', function (e) {
e.stopPropagation();
var channel = state.channels[id];
if (!channel.isFriendChat) { return; }
var curvePublic = channel.curvePublic;
$(mute).show();
$(unmute).hide();
unmuteUser(curvePublic);
});
$(mute).on('click dblclick', function (e) {
e.stopPropagation();
var channel = state.channels[id];
if (!channel.isFriendChat) { return; }
var curvePublic = channel.curvePublic;
var friend = contactsData[curvePublic] || friendData;
$(mute).hide();
$(unmute).show();
muteUser(friend);
});
$(remove).click(function (e) {
e.stopPropagation();
var channel = state.channels[id];
if (!channel.isFriendChat) { return; }
var curvePublic = channel.curvePublic;
var friend = contactsData[curvePublic] || friendData;
var name = Util.fixHTML(UI.getDisplayName(friend.name || friend.displayName));
var content = h('div', [
UI.setHTML(h('p'), Messages._getKey('contacts_confirmRemove', [ name ])),
]);
UI.confirm(content, function (yes) {
if (!yes) { return; }
removeFriend(curvePublic);
// TODO remove friend from userlist ui
// FIXME seems to trigger EJOINED from netflux-websocket (from server);
// (tried to join a channel in which you were already present)
});
});
const $avatar = $(h('div.cp-avatar')).appendTo($room);
@ -678,6 +814,8 @@ define([
var $messagebox = $chat.find('.cp-app-contacts-messages');
var shouldScroll = isBottomedOut($messagebox);
$messagebox.find('.cp-app-contacts-system-notification').remove();
$messagebox.append(el_message);
if (shouldScroll) {
@ -801,7 +939,6 @@ define([
$messagebox.append(el_message);
});
normalizeLabels($messagebox);
var roomEl = markup.room(id, room, list);
var $parentEl;
@ -835,6 +972,7 @@ define([
if (err) { return void console.error(err); }
debug('rooms: ' + JSON.stringify(rooms));
rooms.forEach(initializeRoom);
updateInfoMessage();
});
};
@ -848,6 +986,7 @@ define([
if (channel && channel.curvePublic === curvePublic) {
showInfo();
}
updateInfoMessage();
if (!removedByMe) {
// TODO UI.alert if this is triggered by the other guy
}
@ -895,6 +1034,8 @@ define([
.find('.cp-mute-icon').show();
$('.cp-app-contacts-friend[data-user]')
.find('.cp-unmute-icon').hide();
$('.cp-app-contacts-friend[data-user]')
.find('.cp-app-contacts-mute-indicator').hide();
if (!muted || Object.keys(muted).length === 0) {
$button.hide();
return;
@ -905,6 +1046,8 @@ define([
.find('.cp-mute-icon').hide();
$('.cp-app-contacts-friend[data-user="'+curve+'"]')
.find('.cp-unmute-icon').show();
$('.cp-app-contacts-friend[data-user="'+curve+'"]')
.find('.cp-app-contacts-mute-indicator').show();
var data = muted[curve];
var avatar = h('span.cp-avatar');
var button = h('button.btn', {
@ -915,15 +1058,15 @@ define([
]);
common.displayAvatar($(avatar), data.avatar, data.name, Util.noop, data.uid, data.badge);
$(button).click(function () {
unmuteUser(curve, button);
execCommand('UNMUTE_USER', curve, function (e, data) {
if (e) { return void console.error(e); }
unmuteUser(curve, function () {
$(button).closest('div').remove();
if (!data) { $button.hide(); }
$('.cp-app-contacts-friend[data-user="'+curve+'"]')
.find('.cp-unmute-icon').hide();
$('.cp-app-contacts-friend[data-user="'+curve+'"]')
.find('.cp-mute-icon').show();
$('.cp-app-contacts-friend[data-user="'+curve+'"]')
.find('.cp-app-contacts-mute-indicator').hide();
if ($('.cp-contacts-muted-table').find('.cp-contacts-muted-user').length === 0) {
UI.findOKButton().click();
}
@ -957,6 +1100,7 @@ define([
debug('rooms: ' + JSON.stringify(rooms));
rooms.forEach(initializeRoom);
updateInfoMessage();
});
updateMutedList();
@ -1015,6 +1159,7 @@ define([
}
if (cmd === 'CLEAR_CHANNEL') {
clearChannel(data);
displaySystemMessage(data, Messages.contacts_historyCleared, 'clear-canvas');
return;
}
if (cmd === 'PADCHAT_READY') {

File diff suppressed because one or more lines are too long

View File

@ -29,6 +29,9 @@
align-items: center;
span:nth-child(2) {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}

View File

@ -53,6 +53,7 @@ define([
$container: $(toolbarElement),
pageTitle: Messages.contacts_title,
metadataMgr: common.getMetadataMgr(),
skipLink: '#cp-app-contacts-container'
};
APP.toolbar = Toolbar.create(configTb);
APP.toolbar.$rightside.hide();