mirror of https://github.com/xwiki-labs/cryptpad
Merge branch 'inviteUI' of github.com:xwiki-labs/cryptpad into inviteUI
This commit is contained in:
commit
f4072ae817
|
@ -103,7 +103,7 @@ define([
|
|||
])*/
|
||||
])
|
||||
]),
|
||||
h('div.cp-version-footer', "CryptPad v3.7.0 (HimalayanQuail)")
|
||||
h('div.cp-version-footer', "CryptPad v3.8.0 (IsolobodonPortoricensis)")
|
||||
]);
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
@import (reference) "./variables.less";
|
||||
@import (reference) "./avatar.less";
|
||||
@import (reference) "./tools.less";
|
||||
@import (reference) "./buttons.less";
|
||||
|
||||
.alertify_main() {
|
||||
--LessLoader_require: LessLoader_currentFile();
|
||||
|
@ -225,28 +226,6 @@
|
|||
::-ms-input-placeholder { /* Microsoft Edge */
|
||||
color: @cryptpad_color_grey;
|
||||
}
|
||||
input:not(.form-control), textarea {
|
||||
background-color: @alertify-input-fg;
|
||||
color: @cryptpad_text_col;
|
||||
border: 1px solid @alertify-input-bg;
|
||||
margin-bottom: @alertify_padding-base;
|
||||
width: 100%;
|
||||
font-size: 100%;
|
||||
padding: @alertify_padding-base;
|
||||
&[readonly] {
|
||||
background-color: @alertify-light-bg;
|
||||
color: @cryptpad_text_col;
|
||||
border-color: @alertify-light-bg;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: hidden;
|
||||
padding: 8px;
|
||||
&[readonly] {
|
||||
resize: none;
|
||||
}
|
||||
}
|
||||
|
||||
span.cp-password-container {
|
||||
display: flex;
|
||||
|
@ -281,99 +260,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
button:not(.btn):not(.pure-button):not(.md-button):not(.mdl-button) {
|
||||
.buttons_main();
|
||||
input:not(.form-control), textarea {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
background-color: @colortheme_alertify-cancel;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
outline: 0;
|
||||
button {
|
||||
display: inline-block;
|
||||
align-items: center;
|
||||
padding: 0 6px;
|
||||
position: relative;
|
||||
margin: 6px 8px;
|
||||
line-height: 36px;
|
||||
min-height: 36px;
|
||||
white-space: nowrap;
|
||||
min-width: 88px;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
border-radius: 0;
|
||||
|
||||
color: @alertify-btn-fg;
|
||||
border: 1px solid @alertify-btn-fg;
|
||||
|
||||
&.no-margin {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&:hover, &:active {
|
||||
background-color: @alertify-light-bg;
|
||||
}
|
||||
|
||||
&.safe, &.danger {
|
||||
color: @colortheme_old-base;
|
||||
white-space: normal;
|
||||
font-weight: bold;
|
||||
}
|
||||
&.danger {
|
||||
background-color: @colortheme_alertify-red;
|
||||
border-color: @colortheme_alertify-red-border;
|
||||
color: @colortheme_alertify-red-color;
|
||||
&:hover, &:active {
|
||||
background-color: contrast(@colortheme_modal-bg, darken(@colortheme_alertify-red, 10%), lighten(@colortheme_alertify-red, 10%));
|
||||
}
|
||||
}
|
||||
|
||||
&.safe {
|
||||
background-color: @colortheme_alertify-green;
|
||||
border-color: @colortheme_alertify-green-border;
|
||||
color: @colortheme_alertify-green-color;
|
||||
&:hover, &:active {
|
||||
background-color: contrast(@colortheme_modal-bg, darken(@colortheme_alertify-green, 10%), lighten(@colortheme_alertify-green, 10%));
|
||||
}
|
||||
}
|
||||
|
||||
&.primary {
|
||||
background-color: @colortheme_alertify-primary;
|
||||
color: @colortheme_alertify-primary-text;
|
||||
border-color: @colortheme_alertify-primary-border;
|
||||
font-weight: bold;
|
||||
&:hover, &:active {
|
||||
background-color: contrast(@colortheme_modal-bg, darken(@colortheme_alertify-primary, 10%), lighten(@colortheme_alertify-primary, 10%));
|
||||
}
|
||||
}
|
||||
|
||||
&.cancel {
|
||||
border-color: @colortheme_alertify-cancel-border;
|
||||
color: @colortheme_alertify-cancel-border;
|
||||
&:hover, &:hover {
|
||||
background-color: fade(@colortheme_alertify-cancel-border, 25%);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
&:focus {
|
||||
//border: 1px dotted @alertify-base;
|
||||
box-shadow: 0px 0px 5px @colortheme_alertify-primary;
|
||||
outline: none;
|
||||
}
|
||||
&::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed !important;
|
||||
background-color: @colortheme_alertify-disabled;
|
||||
color: @colortheme_alertify-disabled-text;
|
||||
border-color: @colortheme_alertify-disabled-border;
|
||||
&:hover, &:active {
|
||||
background-color: @colortheme_alertify-disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
@import (reference) "./colortheme-all.less";
|
||||
@import (reference) "./variables.less";
|
||||
|
||||
.buttons_main() {
|
||||
@alertify-fore: @colortheme_modal-fg;
|
||||
@alertify-btn-fg: @alertify-fore;
|
||||
@alertify-light-bg: fade(@alertify-fore, 25%);
|
||||
@alertify_padding-base: @variables_padding;
|
||||
@alertify-input-bg: @colortheme_modal-input;
|
||||
@alertify-input-fg: @colortheme_modal-input-fg;
|
||||
|
||||
input:not(.form-control), textarea {
|
||||
background-color: @alertify-input-fg;
|
||||
color: @cryptpad_text_col;
|
||||
border: 1px solid @alertify-input-bg;
|
||||
width: 100%;
|
||||
font-size: 100%;
|
||||
padding: @alertify_padding-base;
|
||||
&[readonly] {
|
||||
background-color: @alertify-light-bg;
|
||||
color: @cryptpad_text_col;
|
||||
border-color: @alertify-input-fg;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: hidden;
|
||||
padding: 8px;
|
||||
&[readonly] {
|
||||
resize: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
button:not(.pure-button):not(.md-button):not(.mdl-button) {
|
||||
|
||||
background-color: @colortheme_alertify-cancel;
|
||||
box-sizing: border-box;
|
||||
outline: 0;
|
||||
align-items: center;
|
||||
padding: 0 6px;
|
||||
line-height: 36px;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
border-radius: 0;
|
||||
|
||||
.fa {
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
color: @alertify-btn-fg;
|
||||
border: 1px solid @alertify-btn-fg;
|
||||
|
||||
&.no-margin {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&:hover, &:active {
|
||||
background-color: lighten(@alertify-fore, 35%);
|
||||
}
|
||||
|
||||
&.safe, &.danger, &.btn-safe, &.btn-danger {
|
||||
color: @colortheme_old-base;
|
||||
white-space: normal;
|
||||
font-weight: bold;
|
||||
}
|
||||
&.danger, &.btn-danger {
|
||||
background-color: @colortheme_alertify-red;
|
||||
border-color: @colortheme_alertify-red-border;
|
||||
color: @colortheme_alertify-red-color;
|
||||
&:hover, &:active {
|
||||
background-color: contrast(@colortheme_modal-bg, darken(@colortheme_alertify-red, 10%), lighten(@colortheme_alertify-red, 10%));
|
||||
}
|
||||
}
|
||||
|
||||
&.safe, &.btn-safe {
|
||||
background-color: @colortheme_alertify-green;
|
||||
border-color: @colortheme_alertify-green-border;
|
||||
color: @colortheme_alertify-green-color;
|
||||
&:hover, &:active {
|
||||
background-color: contrast(@colortheme_modal-bg, darken(@colortheme_alertify-green, 10%), lighten(@colortheme_alertify-green, 10%));
|
||||
}
|
||||
}
|
||||
|
||||
&.primary, &.btn-primary {
|
||||
background-color: @colortheme_alertify-primary;
|
||||
color: @colortheme_alertify-primary-text;
|
||||
border-color: @colortheme_alertify-primary-border;
|
||||
font-weight: bold;
|
||||
&:hover, &:active {
|
||||
background-color: contrast(@colortheme_modal-bg, darken(@colortheme_alertify-primary, 10%), lighten(@colortheme_alertify-primary, 10%));
|
||||
}
|
||||
}
|
||||
|
||||
&.cancel, &.btn-cancel {
|
||||
border-color: @colortheme_alertify-cancel-border;
|
||||
color: @colortheme_alertify-cancel-border;
|
||||
&:hover, &:hover {
|
||||
background-color: fade(@colortheme_alertify-cancel-border, 25%);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
&:focus {
|
||||
//border: 1px dotted @alertify-base;
|
||||
box-shadow: 0px 0px 5px @colortheme_alertify-primary;
|
||||
outline: none;
|
||||
}
|
||||
&::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed !important;
|
||||
background-color: @colortheme_alertify-disabled;
|
||||
color: @colortheme_alertify-disabled-text;
|
||||
border-color: @colortheme_alertify-disabled-border;
|
||||
&:hover, &:active {
|
||||
background-color: @colortheme_alertify-disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,13 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
media-tag:empty {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: inline-block;
|
||||
border: 1px solid #BBB;
|
||||
}
|
||||
|
||||
media-tag img {
|
||||
flex: 1;
|
||||
max-height: 100% !important;
|
||||
|
|
|
@ -78,6 +78,9 @@
|
|||
.cp-app-contacts-name {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.cp-app-contacts-icons {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
|
@ -89,6 +92,7 @@
|
|||
.cp-app-contacts-remove {
|
||||
cursor: pointer;
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
&:hover {
|
||||
color: darken(@color, 20%);
|
||||
}
|
||||
|
@ -121,8 +125,30 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.cp-app-contacts-muted-button {
|
||||
margin: 10px;
|
||||
border: 0;
|
||||
display: none;
|
||||
order: 3;
|
||||
.fa-bell-slash {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cp-contacts-muted-table {
|
||||
.cp-contacts-muted-user {
|
||||
margin-bottom: 5px;
|
||||
.cp-avatar {
|
||||
margin-right: 10px;
|
||||
}
|
||||
button {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#cp-app-contacts-container.cp-app-contacts-inapp {
|
||||
#cp-app-contacts-friendlist {
|
||||
display: none;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
@import (reference) "/customize/src/less2/include/colortheme-all.less";
|
||||
@import (reference) "/customize/src/less2/include/leftside-menu.less";
|
||||
@import (reference) "/customize/src/less2/include/buttons.less";
|
||||
|
||||
@sidebar_button-width: 400px;
|
||||
|
||||
|
@ -95,9 +96,11 @@
|
|||
}
|
||||
}
|
||||
margin-bottom: 20px;
|
||||
.buttons_main();
|
||||
}
|
||||
[type="text"], [type="password"], button {
|
||||
vertical-align: middle;
|
||||
min-width: 40px;
|
||||
height: 40px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
@ -106,12 +109,12 @@
|
|||
width: @sidebar_button-width;
|
||||
input {
|
||||
flex: 1;
|
||||
border-radius: 0.25em 0 0 0.25em;
|
||||
//border-radius: 0.25em 0 0 0.25em;
|
||||
border: 1px solid #adadad;
|
||||
border-right: 0px;
|
||||
}
|
||||
button {
|
||||
border-radius: 0 0.25em 0.25em 0;
|
||||
//border-radius: 0 0.25em 0.25em 0;
|
||||
//border: 1px solid #adadad;
|
||||
border-left: 0px;
|
||||
}
|
||||
|
@ -119,6 +122,13 @@
|
|||
&>div {
|
||||
margin: 10px 0;
|
||||
}
|
||||
button.btn {
|
||||
margin: 0 5px 0 0;
|
||||
}
|
||||
span.cp-password-container {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
/*
|
||||
button.btn {
|
||||
@button-bg: @colortheme_sidebar-button-bg;
|
||||
@button-red-bg: @colortheme_sidebar-button-red-bg;
|
||||
|
@ -126,6 +136,9 @@
|
|||
background-color: @button-bg;
|
||||
border-color: darken(@button-bg, 10%);
|
||||
color: white;
|
||||
.fa {
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
&:hover {
|
||||
background-color: darken(@button-bg, 10%);
|
||||
}
|
||||
|
@ -146,6 +159,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "cryptpad",
|
||||
"version": "3.7.0",
|
||||
"version": "3.8.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "cryptpad",
|
||||
"description": "realtime collaborative visual editor with zero knowlege server",
|
||||
"version": "3.7.0",
|
||||
"version": "3.8.0",
|
||||
"license": "AGPL-3.0+",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -98,6 +98,13 @@
|
|||
max-height: 90vh;
|
||||
}
|
||||
}
|
||||
media-tag:empty {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: inline-block;
|
||||
border: 1px solid #BBB;
|
||||
}
|
||||
|
||||
.markdown_main();
|
||||
.cp-app-code-preview-empty {
|
||||
display: none;
|
||||
|
|
|
@ -592,6 +592,7 @@ define([
|
|||
}];
|
||||
var modal = dialog.customModal(content, {buttons: buttons});
|
||||
UI.openCustomModal(modal);
|
||||
return modal;
|
||||
};
|
||||
|
||||
UI.log = function (msg) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1684,6 +1684,11 @@ define([
|
|||
dismissButton
|
||||
]) // XXX
|
||||
]);
|
||||
$(linkMessage).keydown(function (e) {
|
||||
if (e.which === 13) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
var localStore = window.cryptpadStore;
|
||||
localStore.get('hide-alert-teamInvite', function (val) {
|
||||
if (val === '1') { return; }
|
||||
|
@ -1762,7 +1767,7 @@ define([
|
|||
onClick: function () {
|
||||
return process();
|
||||
},
|
||||
keys: [13]
|
||||
keys: []
|
||||
}, {
|
||||
className: 'primary cp-teams-invite-copy',
|
||||
name: Messages.team_inviteLinkCopy, // XXX
|
||||
|
@ -4156,7 +4161,7 @@ define([
|
|||
};
|
||||
|
||||
var content = h('div.cp-share-modal', [
|
||||
setHTML(h('p'), text)
|
||||
setHTML(h('p'), text),
|
||||
]);
|
||||
UI.proposal(content, todo);
|
||||
};
|
||||
|
|
|
@ -435,8 +435,6 @@
|
|||
return mediaObject;
|
||||
}
|
||||
|
||||
mediaObject.tag.innerHTML = '<img style="width: 100px; height: 100px;">';
|
||||
|
||||
// Download the encrypted blob
|
||||
download(src, function (err, u8Encrypted) {
|
||||
if (err) {
|
||||
|
|
|
@ -3,9 +3,10 @@ define([
|
|||
'/customize/messages.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/common-ui-elements.js',
|
||||
'/common/hyperscript.js',
|
||||
'/common/diffMarked.js',
|
||||
], function ($, Messages, Util, UI, h, DiffMd) {
|
||||
], function ($, Messages, Util, UI, UIElements, h, DiffMd) {
|
||||
'use strict';
|
||||
|
||||
var debug = console.log;
|
||||
|
@ -13,6 +14,8 @@ define([
|
|||
|
||||
var MessengerUI = {};
|
||||
|
||||
var mutedUsers = {};
|
||||
|
||||
var dataQuery = function (id) {
|
||||
return '[data-key="' + id + '"]';
|
||||
};
|
||||
|
@ -67,8 +70,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'),
|
||||
h('h2.cp-app-contacts-category-title', Messages.contacts_friends),
|
||||
h('button.cp-app-contacts-muted-button',[
|
||||
h('i.fa.fa-bell-slash'),
|
||||
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'),
|
||||
|
@ -184,7 +190,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;
|
||||
|
@ -486,6 +492,20 @@ define([
|
|||
}
|
||||
};
|
||||
|
||||
var unmuteUser = function (curve) {
|
||||
execCommand('UNMUTE_USER', curve, function (e) {
|
||||
if (e) { return void console.error(e); }
|
||||
});
|
||||
};
|
||||
var muteUser = function (data) {
|
||||
execCommand('MUTE_USER', {
|
||||
curvePublic: data.curvePublic,
|
||||
name: data.displayName || data.name,
|
||||
avatar: data.avatar
|
||||
}, function (e /*, removed */) {
|
||||
if (e) { return void console.error(e); }
|
||||
});
|
||||
};
|
||||
var removeFriend = function (curvePublic) {
|
||||
execCommand('REMOVE_FRIEND', curvePublic, function (e /*, removed */) {
|
||||
if (e) { return void console.error(e); }
|
||||
|
@ -499,6 +519,21 @@ define([
|
|||
title: room.name
|
||||
});
|
||||
|
||||
|
||||
var curve;
|
||||
if (room.isFriendChat) {
|
||||
var __channel = state.channels[id];
|
||||
curve = __channel.curvePublic;
|
||||
}
|
||||
|
||||
var unmute = h('span.cp-app-contacts-remove.fa.fa-bell.cp-unmute-icon', {
|
||||
title: Messages.contacts_unmute || 'unmute',
|
||||
style: (curve && mutedUsers[curve]) ? undefined : 'display: none;'
|
||||
});
|
||||
var mute = h('span.cp-app-contacts-remove.fa.fa-bell-slash.cp-mute-icon', {
|
||||
title: Messages.contacts_mute || 'mute',
|
||||
style: (curve && mutedUsers[curve]) ? 'display: none;' : undefined
|
||||
});
|
||||
var remove = h('span.cp-app-contacts-remove.fa.fa-user-times', {
|
||||
title: Messages.contacts_remove
|
||||
});
|
||||
|
@ -511,8 +546,12 @@ define([
|
|||
});
|
||||
var rightCol = h('span.cp-app-contacts-right-col', [
|
||||
h('span.cp-app-contacts-name', [room.name]),
|
||||
room.isFriendChat ? remove :
|
||||
(room.isPadChat || room.isTeamChat) ? undefined : leaveRoom,
|
||||
h('span.cp-app-contacts-icons', [
|
||||
room.isFriendChat ? mute : undefined,
|
||||
room.isFriendChat ? unmute : undefined,
|
||||
room.isFriendChat ? remove :
|
||||
(room.isPadChat || room.isTeamChat) ? undefined : leaveRoom,
|
||||
])
|
||||
]);
|
||||
|
||||
var friendData = room.isFriendChat ? userlist[0] : {};
|
||||
|
@ -523,23 +562,43 @@ define([
|
|||
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;
|
||||
UI.confirm(Messages._getKey('contacts_confirmRemove', [
|
||||
Util.fixHTML(friend.name)
|
||||
]), function (yes) {
|
||||
var content = h('div', [
|
||||
UI.setHTML(h('p'), Messages._getKey('contacts_confirmRemove', [Util.fixHTML(friend.name)])),
|
||||
]);
|
||||
UI.confirm(content, function (yes) {
|
||||
if (!yes) { return; }
|
||||
removeFriend(curvePublic, function (e) {
|
||||
if (e) { return void console.error(e); }
|
||||
});
|
||||
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)
|
||||
}, undefined, true);
|
||||
});
|
||||
});
|
||||
|
||||
if (friendData.avatar && avatars[friendData.avatar]) {
|
||||
|
@ -792,6 +851,62 @@ define([
|
|||
// var onJoinRoom
|
||||
// var onLeaveRoom
|
||||
|
||||
var updateMutedList = function () {
|
||||
execCommand('GET_MUTED_USERS', null, function (err, muted) {
|
||||
if (err) { return void console.error(err); }
|
||||
mutedUsers = muted;
|
||||
|
||||
var $button = $userlist.find('.cp-app-contacts-muted-button');
|
||||
|
||||
$('.cp-app-contacts-friend[data-user]')
|
||||
.find('.cp-mute-icon').show();
|
||||
$('.cp-app-contacts-friend[data-user]')
|
||||
.find('.cp-unmute-icon').hide();
|
||||
if (!muted || Object.keys(muted).length === 0) {
|
||||
$button.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
var rows = Object.keys(muted).map(function (curve) {
|
||||
$('.cp-app-contacts-friend[data-user="'+curve+'"]')
|
||||
.find('.cp-mute-icon').hide();
|
||||
$('.cp-app-contacts-friend[data-user="'+curve+'"]')
|
||||
.find('.cp-unmute-icon').show();
|
||||
var data = muted[curve];
|
||||
var avatar = h('span.cp-avatar');
|
||||
var button = h('button', {
|
||||
'data-user': curve
|
||||
}, [
|
||||
h('i.fa.fa-bell'),
|
||||
Messages.contacts_unmute || 'unmute'
|
||||
]);
|
||||
UIElements.displayAvatar(common, $(avatar), data.avatar, data.name);
|
||||
$(button).click(function () {
|
||||
unmuteUser(curve, button);
|
||||
execCommand('UNMUTE_USER', curve, function (e, data) {
|
||||
if (e) { return void console.error(e); }
|
||||
$(button).closest('div').remove();
|
||||
if (!data) { $button.hide(); }
|
||||
$('.cp-app-contacts-friend[data-user="'+curve+'"]')
|
||||
.find('.cp-mute-icon').show();
|
||||
});
|
||||
});
|
||||
return h('div.cp-contacts-muted-user', [
|
||||
h('span', avatar),
|
||||
h('span', data.name),
|
||||
button
|
||||
]);
|
||||
});
|
||||
var content = h('div', [
|
||||
h('h4', Messages.contacts_mutedUsers || 'Muted users...'),
|
||||
h('div.cp-contacts-muted-table', rows)
|
||||
]);
|
||||
$button.off('click');
|
||||
$button.click(function () {
|
||||
UI.alert(content);
|
||||
}).show();
|
||||
});
|
||||
};
|
||||
|
||||
var ready = false;
|
||||
var onMessengerReady = function () {
|
||||
|
@ -806,6 +921,8 @@ define([
|
|||
rooms.forEach(initializeRoom);
|
||||
});
|
||||
|
||||
updateMutedList();
|
||||
|
||||
$container.removeClass('cp-app-contacts-initializing');
|
||||
};
|
||||
|
||||
|
@ -882,6 +999,10 @@ define([
|
|||
onUpdateData(data);
|
||||
return;
|
||||
}
|
||||
if (cmd === 'UPDATE_MUTED') {
|
||||
updateMutedList();
|
||||
return;
|
||||
}
|
||||
if (cmd === 'MESSAGE') {
|
||||
onMessage(data);
|
||||
return;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -428,20 +428,21 @@ define([
|
|||
}
|
||||
|
||||
var channel = ctx.channels[data.channel];
|
||||
if (!channel) {
|
||||
return void cb({error: "NO_SUCH_CHANNEL"});
|
||||
}
|
||||
|
||||
// Unfriend with mailbox
|
||||
if (ctx.store.mailbox && data.curvePublic && data.notifications) {
|
||||
Messaging.removeFriend(ctx.store, curvePublic, function (obj) {
|
||||
if (obj && obj.error) { return void cb({error:obj.error}); }
|
||||
ctx.updateMetadata();
|
||||
cb(obj);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Unfriend with channel
|
||||
if (!channel) {
|
||||
return void cb({error: "NO_SUCH_CHANNEL"});
|
||||
}
|
||||
try {
|
||||
var msg = [Types.unfriend, proxy.curvePublic, +new Date()];
|
||||
var msgStr = JSON.stringify(msg);
|
||||
|
@ -458,6 +459,40 @@ 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) {
|
||||
var cb = Util.once(Util.mkAsync(_cb));
|
||||
var proxy = ctx.store.proxy;
|
||||
var muted = proxy.mutedUsers = proxy.mutedUsers || {};
|
||||
delete muted[curvePublic];
|
||||
ctx.emit('UPDATE_MUTED', null, getAllClients(ctx));
|
||||
cb(Object.keys(muted).length);
|
||||
};
|
||||
var getMutedUsers = function (ctx, cb) {
|
||||
var proxy = ctx.store.proxy;
|
||||
if (cb) {
|
||||
return void cb(proxy.mutedUsers || {});
|
||||
}
|
||||
return proxy.mutedUsers || {};
|
||||
};
|
||||
|
||||
var openChannel = function (ctx, data) {
|
||||
var proxy = ctx.store.proxy;
|
||||
var network = ctx.store.network;
|
||||
|
@ -664,7 +699,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; }
|
||||
|
@ -887,15 +929,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;
|
||||
|
@ -911,6 +944,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);
|
||||
|
@ -942,6 +978,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,
|
||||
|
@ -990,6 +1032,9 @@ define([
|
|||
if (cmd === 'GET_ROOMS') {
|
||||
return void getRooms(ctx, data, cb);
|
||||
}
|
||||
if (cmd === 'GET_MUTED_USERS') {
|
||||
return void getMutedUsers(ctx, cb);
|
||||
}
|
||||
if (cmd === 'GET_USERLIST') {
|
||||
return void getUserList(ctx, data, cb);
|
||||
}
|
||||
|
@ -1002,6 +1047,12 @@ define([
|
|||
if (cmd === 'REMOVE_FRIEND') {
|
||||
return void removeFriend(ctx, data, cb);
|
||||
}
|
||||
if (cmd === 'MUTE_USER') {
|
||||
return void muteUser(ctx, data, cb);
|
||||
}
|
||||
if (cmd === 'UNMUTE_USER') {
|
||||
return void unmuteUser(ctx, data, cb);
|
||||
}
|
||||
if (cmd === 'GET_STATUS') {
|
||||
return void getStatus(ctx, data, cb);
|
||||
}
|
||||
|
|
|
@ -451,7 +451,6 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) {
|
|||
|
||||
// copy the new profile from the old one
|
||||
members[curve] = Util.clone(members[author]);
|
||||
members[curve].curvePublic = curve;
|
||||
// and erase the old one
|
||||
delete members[author];
|
||||
return true;
|
||||
|
@ -776,7 +775,6 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) {
|
|||
Object.keys(data).forEach(function (curve) {
|
||||
if (!isValidId(curve) || isMap(ref.state.members[curve])) { return delete data[curve]; }
|
||||
});
|
||||
console.error('SENDING INVITE');
|
||||
|
||||
send(['INVITE', data], cb);
|
||||
};
|
||||
|
|
|
@ -446,7 +446,6 @@ define([
|
|||
// If we've been kicked, don't try to update our data, we'll close everything
|
||||
// in the next nThen part
|
||||
var state = roster.getState();
|
||||
console.error(state);
|
||||
var me = Util.find(ctx, ['store', 'proxy', 'curvePublic']);
|
||||
if (!state.members[me]) { return; }
|
||||
|
||||
|
@ -1280,6 +1279,8 @@ define([
|
|||
var seeds = data.seeds; // {scrypt, preview}
|
||||
var bytes64 = data.bytes64;
|
||||
|
||||
if (!teamId || !team) { return void cb({error: 'EINVAL'}); }
|
||||
|
||||
var roster = team.roster;
|
||||
|
||||
var teamName;
|
||||
|
@ -1312,12 +1313,16 @@ define([
|
|||
var putOpts = {
|
||||
initialState: '{}',
|
||||
network: ctx.store.network,
|
||||
metadata: {
|
||||
owners: [ctx.store.proxy.edPublic, ephemeralKeys.edPublic]
|
||||
}
|
||||
};
|
||||
|
||||
(function () {
|
||||
// a random signing keypair to prevent further writes to the channel
|
||||
// we don't need to remember it cause we're only writing once
|
||||
var sign = Invite.generateSignPair(); // { validateKey, signKey}
|
||||
putOpts.metadata.validateKey = sign.validateKey;
|
||||
|
||||
// visible with only the invite link
|
||||
var previewContent = {
|
||||
|
@ -1325,7 +1330,6 @@ define([
|
|||
message: message,
|
||||
author: Messaging.createData(ctx.store.proxy, false),
|
||||
displayName: name,
|
||||
curvePublic: ephemeralKeys.curvePublic,
|
||||
};
|
||||
|
||||
var cryptput_config = {
|
||||
|
@ -1352,6 +1356,7 @@ define([
|
|||
// a different random signing key so that the server can't correlate these documents
|
||||
// as components of an invite
|
||||
var sign = Invite.generateSignPair(); // { validateKey, signKey}
|
||||
putOpts.metadata.validateKey = sign.validateKey;
|
||||
|
||||
// available only with the link and the content
|
||||
var inviteContent = {
|
||||
|
@ -1486,13 +1491,16 @@ define([
|
|||
// Accept the roster invitation: relplace our ephemeral keys with our user keys
|
||||
var rosterData = Util.find(inviteContent, ['teamData', 'keys', 'roster']);
|
||||
var myKeys = inviteContent.ephemeral;
|
||||
if (!rosterData || !myKeys) {
|
||||
waitFor.abort();
|
||||
return void cb({error: 'INVALID_INVITE_CONTENT'});
|
||||
}
|
||||
var rosterKeys = Crypto.Team.deriveMemberKeys(rosterData.edit, myKeys);
|
||||
Roster.create({
|
||||
network: ctx.store.network,
|
||||
channel: rosterData.channel,
|
||||
keys: rosterKeys,
|
||||
anon_rpc: ctx.store.anon_rpc,
|
||||
lastKnownHash: rosterData.lastKnownHash, // XXX Can we trust this user?
|
||||
}, waitFor(function (err, roster) {
|
||||
if (err) {
|
||||
waitFor.abort();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
@import (reference) '../../customize/src/less2/include/framework.less';
|
||||
@import (reference) '../../customize/src/less2/include/messenger.less';
|
||||
@import (reference) '../../customize/src/less2/include/avatar.less';
|
||||
@import (reference) '../../customize/src/less2/include/buttons.less';
|
||||
|
||||
// body
|
||||
&.cp-app-contacts {
|
||||
|
@ -17,6 +19,22 @@
|
|||
display: flex; // We need this to remove a 3px border at the bottom of the toolbar
|
||||
}
|
||||
|
||||
.cp-app-contacts-friends {
|
||||
.buttons_main();
|
||||
}
|
||||
.cp-contacts-muted-table {
|
||||
.avatar_main(50px);
|
||||
.cp-contacts-muted-user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
span:nth-child(2) {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.messenger_main();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,15 @@
|
|||
);
|
||||
.sidebar-layout_main();
|
||||
|
||||
@cp-profile-is-your-friend: #777;
|
||||
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
#cp-sidebarlayout-leftside {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#cp-app-profile-header {
|
||||
display: flex;
|
||||
#cp-app-profile-rightside {
|
||||
|
@ -64,8 +71,9 @@
|
|||
}
|
||||
}
|
||||
button {
|
||||
min-width: 40px;
|
||||
height: 40px;
|
||||
margin: 5px;
|
||||
margin: 5px !important;
|
||||
}
|
||||
}
|
||||
.cp-app-profile-resizer {
|
||||
|
@ -108,10 +116,18 @@
|
|||
display: none;
|
||||
}
|
||||
& > button:empty {
|
||||
margin-left: 25px;
|
||||
margin-left: 25px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cp-app-profile-friend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: @cp-profile-is-your-friend;
|
||||
.fa {
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
}
|
||||
.cp-app-profile-friend-request {
|
||||
flex: 0;
|
||||
width: 400px;
|
||||
|
@ -124,11 +140,7 @@
|
|||
}
|
||||
.cp-app-profile-viewprofile-button {
|
||||
margin-bottom: 20px;
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
&> span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
width: 300px;
|
||||
}
|
||||
#cp-app-profile-description {
|
||||
position: relative;
|
||||
|
@ -166,13 +178,6 @@
|
|||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
.cp-app-profile-description-edit {
|
||||
& > button {
|
||||
span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#cp-app-profile-create {
|
||||
height: 100%;
|
||||
|
@ -181,5 +186,12 @@
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.cp-app-profile-mute-container {
|
||||
margin-top: 5px;
|
||||
p {
|
||||
margin-top: 5px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -178,9 +178,6 @@ define([
|
|||
|
||||
var addFriendRequest = function ($container) {
|
||||
if (!APP.readOnly || !APP.common.isLoggedIn()) { return; }
|
||||
APP.$friend = $('<button>', {
|
||||
'class': 'btn btn-success cp-app-profile-friend-request',
|
||||
});
|
||||
APP.$friend = $(h('div.cp-app-profile-friend-container'));
|
||||
$container.append(APP.$friend);
|
||||
};
|
||||
|
@ -195,42 +192,124 @@ define([
|
|||
|
||||
APP.$friend.html('');
|
||||
|
||||
var module = common.makeUniversal('messenger');
|
||||
var name = Util.fixHTML(data.name) || Messages.anonymous;
|
||||
|
||||
var friends = common.getMetadataMgr().getPrivateData().friends;
|
||||
// This is a friend: display the "friend" message and an "unfriend" button
|
||||
if (friends[data.curvePublic]) {
|
||||
APP.$friend.append(h('p.cp-app-profile-friend', Messages._getKey('profile_friend', [data.name || Messages.anonymous])));
|
||||
// Add friend message
|
||||
APP.$friend.append(h('p.cp-app-profile-friend', [
|
||||
h('i.fa.fa-address-book'),
|
||||
Messages._getKey('profile_friend', [name])
|
||||
]));
|
||||
if (!friends[data.curvePublic].notifications) { return; }
|
||||
// Add unfriend button
|
||||
var unfriendButton = h('button.btn.btn-primary.cp-app-profile-friend-request', [
|
||||
h('i.fa.fa-user-times'),
|
||||
Messages.contacts_remove
|
||||
]);
|
||||
$(unfriendButton).click(function () {
|
||||
// Unfriend confirm
|
||||
var content = h('div', [
|
||||
UI.setHTML(h('p'), Messages._getKey('contacts_confirmRemove', [name]))
|
||||
]);
|
||||
UI.confirm(content, function (yes) {
|
||||
if (!yes) { return; }
|
||||
module.execCommand('REMOVE_FRIEND', data.curvePublic, function (e) {
|
||||
if (e) { return void console.error(e); }
|
||||
});
|
||||
});
|
||||
}).appendTo(APP.$friend);
|
||||
return;
|
||||
}
|
||||
|
||||
var $button = $('<button>', {
|
||||
'class': 'btn btn-success cp-app-profile-friend-request',
|
||||
}).appendTo(APP.$friend);
|
||||
var button = h('button.btn.btn-success.cp-app-profile-friend-request', [
|
||||
h('i.fa.fa-user-plus'),
|
||||
]);
|
||||
var $button = $(button).appendTo(APP.$friend);
|
||||
|
||||
// If this curve has sent us a friend request, we should not be able to sent it to them
|
||||
var friendRequests = common.getFriendRequests();
|
||||
if (friendRequests[data.curvePublic]) {
|
||||
$button.html(Messages._getKey('friendRequest_received', [data.name || Messages.anonymous]))
|
||||
$button.append(Messages._getKey('friendRequest_received', [name || Messages.anonymous]))
|
||||
.click(function () {
|
||||
UIElements.displayFriendRequestModal(common, friendRequests[data.curvePublic]);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Pending friend (we've sent a friend request)
|
||||
var pendingFriends = APP.common.getPendingFriends(); // Friend requests sent
|
||||
if (pendingFriends[data.curvePublic]) {
|
||||
$button.attr('disabled', 'disabled').text(Messages.profile_friendRequestSent);
|
||||
$button.attr('disabled', 'disabled').append(Messages.profile_friendRequestSent);
|
||||
return;
|
||||
}
|
||||
// This is not a friend yet: we can send a friend request
|
||||
$button.text(Messages._getKey('userlist_addAsFriendTitle', [data.name || Messages.anonymous]))
|
||||
.click(function () {
|
||||
APP.common.sendFriendRequest({
|
||||
curvePublic: data.curvePublic,
|
||||
notifications: data.notifications
|
||||
}, function () {
|
||||
$button.attr('disabled', 'disabled').text(Messages.profile_friendRequestSent);
|
||||
$button.attr('disabled', 'disabled').append(Messages.profile_friendRequestSent);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var addMuteButton = function ($container) {
|
||||
if (!APP.readOnly || !APP.common.isLoggedIn()) { return; }
|
||||
APP.$mute = $(h('div.cp-app-profile-mute-container'));
|
||||
$container.append(APP.$mute);
|
||||
};
|
||||
var refreshMute = function (data) {
|
||||
if (!APP.$mute) { return; }
|
||||
|
||||
var me = common.getMetadataMgr().getUserData().curvePublic;
|
||||
if (data.curvePublic === me) {
|
||||
APP.$mute.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Add mute/unmute buttons
|
||||
var $mute = APP.$mute;
|
||||
var module = common.makeUniversal('messenger');
|
||||
module.execCommand('GET_MUTED_USERS', null, function (muted) {
|
||||
if (!muted || typeof(muted) !== "object") { return; }
|
||||
$mute.html('');
|
||||
var isMuted = muted[data.curvePublic];
|
||||
if (isMuted) {
|
||||
var unmuteButton = h('button.btn.btn-secondary.cp-app-profile-friend-request', [
|
||||
h('i.fa.fa-bell'),
|
||||
Messages.contacts_unmute || 'unmute'
|
||||
]);
|
||||
$(unmuteButton).click(function () {
|
||||
module.execCommand('UNMUTE_USER', data.curvePublic, function (e) {
|
||||
if (e) { console.error(e); return void UI.warn(Messages.error); }
|
||||
refreshMute(data);
|
||||
});
|
||||
}).appendTo($mute);
|
||||
return;
|
||||
}
|
||||
var muteButton = h('button.btn.btn-danger.cp-app-profile-friend-request', [
|
||||
h('i.fa.fa-bell-slash'),
|
||||
Messages.contacts_mute || 'mute'
|
||||
]);
|
||||
$(muteButton).click(function () {
|
||||
module.execCommand('MUTE_USER', {
|
||||
curvePublic: data.curvePublic,
|
||||
name: Util.fixHTML(data.displayName || data.name),
|
||||
avatar: data.avatar
|
||||
}, function (e) {
|
||||
if (e) { console.error(e); return void UI.warn(Messages.error); }
|
||||
refreshMute(data);
|
||||
});
|
||||
}).appendTo($mute);
|
||||
$(UI.setHTML(h('p'), Messages.contacts_muteInfo)).appendTo($mute);
|
||||
});
|
||||
};
|
||||
|
||||
var displayAvatar = function (val) {
|
||||
var sframeChan = common.getSframeChannel();
|
||||
var $span = APP.$avatar;
|
||||
|
@ -304,7 +383,7 @@ define([
|
|||
};
|
||||
|
||||
var addDescription = function ($container) {
|
||||
var $block = $('<div>', {id: DESCRIPTION_ID}).appendTo($container);
|
||||
var $block = $('<div>', {id: DESCRIPTION_ID, class:'cp-sidebarlayout-element'}).appendTo($container);
|
||||
|
||||
APP.$description = $('<div>', {'class': 'cp-app-profile-description-rendered'}).appendTo($block);
|
||||
APP.$descriptionEdit = $();
|
||||
|
@ -390,14 +469,15 @@ define([
|
|||
APP.$container.find('#'+CREATE_ID).remove();
|
||||
|
||||
if (!APP.initialized) {
|
||||
var $header = $('<div>', {id: HEADER_ID}).appendTo(APP.$rightside);
|
||||
var $header = $('<div>', {id: HEADER_ID, class:'cp-sidebarlayout-element'}).appendTo(APP.$rightside);
|
||||
addAvatar($header);
|
||||
var $rightside = $('<div>', {id: HEADER_RIGHT_ID}).appendTo($header);
|
||||
addDisplayName($rightside);
|
||||
addLink($rightside);
|
||||
addFriendRequest($rightside);
|
||||
addMuteButton($rightside);
|
||||
addDescription(APP.$rightside);
|
||||
addViewButton(APP.$rightside);
|
||||
addViewButton($rightside);
|
||||
APP.initialized = true;
|
||||
createLeftside();
|
||||
}
|
||||
|
@ -409,6 +489,7 @@ define([
|
|||
refreshLink(data);
|
||||
refreshDescription(data);
|
||||
refreshFriendRequest(data);
|
||||
refreshMute(data);
|
||||
};
|
||||
|
||||
var createToolbar = function () {
|
||||
|
|
|
@ -184,12 +184,12 @@
|
|||
&:checked {
|
||||
& + label {
|
||||
font-weight: bold;
|
||||
background-color: lighten(@colortheme_loading-bg, 20%);
|
||||
background-color: @colortheme_logo-2;
|
||||
cursor: default;
|
||||
border: 1px solid #c1158e;
|
||||
border: 1px solid @colortheme_logo-2;
|
||||
color: @colortheme_loading-color;
|
||||
&:hover {
|
||||
background-color: lighten(@colortheme_loading-bg, 20%);
|
||||
background-color: @colortheme_logo-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -203,10 +203,11 @@
|
|||
height: 50px;
|
||||
padding: 5px;
|
||||
margin: 0 20px;
|
||||
border: 1px solid black;
|
||||
color: @colortheme_logo-2;
|
||||
border: 1px solid @colortheme_logo-2;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: lighten(@colortheme_loading-bg, 10%);
|
||||
background-color: lighten(@colortheme_logo-2, 35%);
|
||||
}
|
||||
}
|
||||
.fa {
|
||||
|
@ -235,6 +236,7 @@
|
|||
}
|
||||
input {
|
||||
width: 70px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
select {
|
||||
width: 100px;
|
||||
|
|
|
@ -217,6 +217,7 @@ define([
|
|||
if (key === 'chat') { $category.append($('<span>', {'class': 'fa fa-comments'})); }
|
||||
if (key === 'drive') { $category.append($('<span>', {'class': 'fa fa-hdd-o'})); }
|
||||
if (key === 'admin') { $category.append($('<span>', {'class': 'fa fa-cogs'})); }
|
||||
if (key === 'link') { $category.append($('<span>', {'class': 'fa fa-envelope'})); }
|
||||
|
||||
if (key === active) {
|
||||
$category.addClass('cp-leftside-active');
|
||||
|
@ -493,8 +494,9 @@ define([
|
|||
refreshCreate(common, cb);
|
||||
});
|
||||
|
||||
makeBlock('drive', function (common, cb) {
|
||||
makeBlock('drive', function (common, cb, $div) {
|
||||
$('div.cp-team-drive').empty();
|
||||
$div.removeClass('cp-sidebarlayout-element'); // Don't apply buttons and input styles from sidebarlayout
|
||||
var content = [
|
||||
h('div.cp-app-drive-container', {tabindex:0}, [
|
||||
h('div#cp-app-drive-tree'),
|
||||
|
@ -778,7 +780,6 @@ define([
|
|||
var links = Object.keys(roster).filter(function (k) {
|
||||
if (!roster[k].pending) { return; }
|
||||
if (!roster[k].inviteChannel) { return; }
|
||||
roster[k].curvePublic = k; // XXX "if (!data.curvePublic) { return; }" in makeMember
|
||||
return roster[k].role === "VIEWER" || !roster[k].role;
|
||||
}).map(function (k) {
|
||||
return makeMember(common, roster[k], me);
|
||||
|
@ -1076,9 +1077,13 @@ define([
|
|||
errorBlock = h('div.alert.alert-danger', {style: 'display: none;'}),
|
||||
div
|
||||
];
|
||||
// "cb" will put the content into the UI.
|
||||
// We're displaying a spinner while we're cryptgetting the preview content
|
||||
cb(c);
|
||||
|
||||
var declineButton = h('button.btn.btn-danger', Messages.friendRequest_decline);
|
||||
var declineButton = h('button.btn.btn-danger', {
|
||||
style: 'display: none;'
|
||||
}, Messages.friendRequest_decline);
|
||||
var acceptButton = h('button.btn.btn-primary', Messages.team_inviteJoin || 'JOIN TEAM'); // XXX
|
||||
var inviteDiv = h('div', [
|
||||
h('nav', [
|
||||
|
@ -1150,20 +1155,9 @@ define([
|
|||
|
||||
nThen(function (waitFor) {
|
||||
// Get preview content.
|
||||
// Use the team module if we're logged in, or sframeChan if we're not
|
||||
var f = function (data, cb) {
|
||||
if (driveAPP.loggedIn) {
|
||||
return void APP.module.execCommand('GET_PREVIEW_CONTENT', data, cb);
|
||||
}
|
||||
var sframeChan = common.getSframeChannel();
|
||||
sframeChan.query('Q_ANON_GET_PREVIEW_CONTENT', data, function (err, json) {
|
||||
cb(json);
|
||||
});
|
||||
};
|
||||
f({
|
||||
seeds: seeds,
|
||||
}, waitFor(function (json) {
|
||||
if (json && json.error) { // XXX this is failing with "team is disabled"
|
||||
var sframeChan = common.getSframeChannel();
|
||||
sframeChan.query('Q_ANON_GET_PREVIEW_CONTENT', { seeds: seeds }, waitFor(function (json) {
|
||||
if (json && json.error) {
|
||||
// XXX APP.module is not ready yet?
|
||||
// err === DELETED: different message?
|
||||
$(errorBlock).text(Messages.error + json.error).show(); // XXX
|
||||
|
@ -1176,7 +1170,7 @@ define([
|
|||
$div.append(h('div.cp-teams-invite-from', [
|
||||
Messages.team_inviteFrom || 'From:', // XXX
|
||||
displayUser(common, json.author)
|
||||
]));
|
||||
]));
|
||||
$div.append(UI.setHTML(h('p.cp-teams-invite-to'),
|
||||
Messages._getKey('team_inviteFromMsg',
|
||||
[Util.fixHTML(json.author.displayName),
|
||||
|
|
Loading…
Reference in New Issue