mirror of
https://github.com/cryptpad/cryptpad.git
synced 2026-09-12 19:49:59 +05:00
Merge remote-tracking branch 'origin/contacts-page' into 2026.4-rc
This commit is contained in:
commit
28c048a119
@ -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
|
||||
|
||||
});
|
||||
}());
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@ -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') {
|
||||
|
||||
2
www/common/worker.bundle.min.js
vendored
2
www/common/worker.bundle.min.js
vendored
File diff suppressed because one or more lines are too long
@ -29,6 +29,9 @@
|
||||
align-items: center;
|
||||
span:nth-child(2) {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user