mirror of
https://github.com/cryptpad/cryptpad.git
synced 2026-09-14 11:05:41 +05:00
Merge branch into staging
This commit is contained in:
commit
c3f6510179
@ -71,6 +71,7 @@
|
||||
button {
|
||||
height: @toolbar_line-height !important;
|
||||
outline: 0;
|
||||
border-radius: @variables_radius;
|
||||
color: @toolbar-color;
|
||||
.toolbar_button;
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
|
||||
@ -13,6 +13,8 @@ define(['/common/translations/messages.js'], function (Messages) {
|
||||
// Replace the existing keys in your copied file here:
|
||||
// Messages.button_newpad = "New Rich Text Document";
|
||||
|
||||
Messages.profile_remove_avatar = "Remove this avatar"; // XXX
|
||||
|
||||
return Messages;
|
||||
});
|
||||
|
||||
|
||||
@ -360,7 +360,9 @@ app.use('/block/', function (req, res, next) {
|
||||
// identified by base64-encoded public keys
|
||||
// skip everything else, ie. /block/placeholder.txt
|
||||
if (typeof(name) !== 'string' || name.length !== 44) {
|
||||
return void next();
|
||||
return void res.status(404).json({
|
||||
error: "INVALID_ID",
|
||||
});
|
||||
}
|
||||
|
||||
var authorization = req.headers.authorization;
|
||||
|
||||
@ -60,20 +60,9 @@ define(['/api/config'], function (ApiConfig) {
|
||||
window.location.href = target.href;
|
||||
};
|
||||
|
||||
// Local URLs don't require any warning and can navigate directly without user input.
|
||||
if (target.host === host.host) { return void go(); }
|
||||
|
||||
// It's annoying to be prompted that you are leaving the platform to visit its docs
|
||||
// but marking the docs domain as trusted undermines third-party admins' autonomy.
|
||||
// If we ever abandon the cryptpad.fr domain someone could squat it and abuse this trust.
|
||||
// If the docs domain is a subdomain of the current one then redirect automatically.
|
||||
// We might make the docs domain configurable at some point in the future.
|
||||
if (target.host === 'docs.cryptpad.org' && target.host.endsWith(host.host)) {
|
||||
return void go();
|
||||
}
|
||||
|
||||
// Everything else requires user input, so we load the platform's translations.
|
||||
// Everything else may require user input, so we load the platform's translations.
|
||||
// FIXME: this seems to infer language preferences from the browser instead of the user's account preferences
|
||||
|
||||
require([
|
||||
'/customize/messages.js',
|
||||
], function (Messages) {
|
||||
@ -86,6 +75,18 @@ define(['/api/config'], function (ApiConfig) {
|
||||
return void reject();
|
||||
}
|
||||
|
||||
// Local URLs don't require any warning and can navigate directly without user input.
|
||||
if (target.host === host.host) { return void go(); }
|
||||
|
||||
// It's annoying to be prompted that you are leaving the platform to visit its docs
|
||||
// but marking the docs domain as trusted undermines third-party admins' autonomy.
|
||||
// If we ever abandon the cryptpad.fr domain someone could squat it and abuse this trust.
|
||||
// If the docs domain is a subdomain of the current one then redirect automatically.
|
||||
// We might make the docs domain configurable at some point in the future.
|
||||
if (target.host === 'docs.cryptpad.org' && target.host.endsWith(host.host)) {
|
||||
return void go();
|
||||
}
|
||||
|
||||
// The provided URL will navigate the user away from the outer domain.
|
||||
var question = Messages._getKey('bounce_confirm', [host.hostname, target.href]);
|
||||
// Confirm that they want to leave, then navigate or reject based on their choice.
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
@import (reference) '../../customize/src/less2/include/framework.less';
|
||||
@import (reference) '../../customize/src/less2/include/sidebar-layout.less';
|
||||
@import (reference) '../../customize/src/less2/include/variables.less';
|
||||
|
||||
&.cp-app-profile {
|
||||
|
||||
@ -21,36 +22,38 @@
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
#cp-app-profile-header {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
#cp-app-profile-rightside {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: start;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
#cp-app-profile-avatar {
|
||||
width: 300px;
|
||||
//height: 350px;
|
||||
margin: 10px;
|
||||
margin-right: 20px;
|
||||
text-align: center;
|
||||
max-width: 300px;
|
||||
max-height: 300px;
|
||||
margin-bottom: 3.5rem;
|
||||
&> span {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
height: 300px;
|
||||
width: 300px;
|
||||
border: 1px solid @cp_profile-border;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
.cp-app-profile-avatar-delete {
|
||||
right: 0;
|
||||
position: absolute;
|
||||
opacity: 0.7;
|
||||
opacity: 1;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,6 +61,7 @@
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
vertical-align: top;
|
||||
border-radius: @variables_radius_L;
|
||||
}
|
||||
media-tag {
|
||||
height: 100%;
|
||||
@ -79,11 +83,18 @@
|
||||
margin: 5px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cp-app-profile-resizer {
|
||||
text-align: center;
|
||||
}
|
||||
#cp-app-profile-displayname, #cp-app-profile-link {
|
||||
margin: 10px 0;
|
||||
.cp-app-profile-displayname {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.cp-app-profile-section:empty {
|
||||
display: none;
|
||||
}
|
||||
.cp-app-profile-displayname, .cp-app-profile-link, .cp-app-profile-section {
|
||||
margin-bottom: 1rem;
|
||||
input {
|
||||
width: 100%;
|
||||
font-size: 20px;
|
||||
@ -108,7 +119,8 @@
|
||||
}
|
||||
.cp-app-profile-link {
|
||||
font-size: 25px;
|
||||
vertical-align: middle;
|
||||
display: inline;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.cp-app-profile-displayname, .cp-app-profile-link {
|
||||
line-height: 40px;
|
||||
@ -127,8 +139,19 @@
|
||||
& > button:empty {
|
||||
margin-left: 25px !important;
|
||||
}
|
||||
@media screen and (max-width: @browser_media-medium-screen) {
|
||||
.cp-app-profile-link-code {
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.cp-app-profile-mute-container.cp-app-profile-section {
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
}
|
||||
.cp-app-profile-friend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -146,22 +169,16 @@
|
||||
#cp-app-profile-invite-button {
|
||||
float: right;
|
||||
}
|
||||
.cp-app-profile-viewprofile-button {
|
||||
margin-bottom: 5px !important;
|
||||
}
|
||||
#cp-app-profile-description {
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
margin-bottom: 20px;
|
||||
//margin-bottom: 20px;
|
||||
.cp-app-profile-description-code {
|
||||
display: none;
|
||||
}
|
||||
.cp-app-profile-description-rendered {
|
||||
border: 1px solid @cp_profile-border;
|
||||
padding: 0 15px;
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
#cp-app-profile-description-info {
|
||||
overflow-wrap: anywhere;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.cp-app-profile-description-ok, .cp-app-profile-description-spin {
|
||||
position: absolute;
|
||||
@ -178,6 +195,7 @@
|
||||
font-family: monospace;
|
||||
font-size: 16px;
|
||||
line-height: initial;
|
||||
max-width: 31rem;
|
||||
pre {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
@ -194,7 +212,6 @@
|
||||
justify-content: center;
|
||||
}
|
||||
.cp-app-profile-mute-container {
|
||||
margin-top: 5px;
|
||||
p {
|
||||
margin-top: 5px;
|
||||
font-size: 13px;
|
||||
|
||||
@ -96,6 +96,7 @@ define([
|
||||
var HEADER_ID = "cp-app-profile-header";
|
||||
var HEADER_RIGHT_ID = "cp-app-profile-rightside";
|
||||
var VIEW_PROFILE_BUTTON = 'cp-app-profile-viewprofile-button';
|
||||
var PROFILE_SECTION = "cp-app-profile-section";
|
||||
|
||||
var common;
|
||||
var sFrameChan;
|
||||
@ -108,25 +109,32 @@ define([
|
||||
var hash = common.getMetadataMgr().getPrivateData().hashes.viewHash;
|
||||
var url = APP.origin + '/profile/#' + hash;
|
||||
|
||||
$('<button>', {
|
||||
'class': 'btn '+VIEW_PROFILE_BUTTON,
|
||||
}).text(Messages.profile_viewMyProfile).click(function () {
|
||||
var $blockView = $('<div>', {class: PROFILE_SECTION}).appendTo($container);
|
||||
var button = h('button.btn.' + VIEW_PROFILE_BUTTON, {
|
||||
'aria-labelledby': 'cp-profile-view-button'
|
||||
}, [
|
||||
h('span#cp-profile-view-button', Messages.profile_viewMyProfile)
|
||||
]);
|
||||
$(button).click(function () {
|
||||
window.open(url, '_blank');
|
||||
}).appendTo($container);
|
||||
}).appendTo($blockView);
|
||||
|
||||
$('<button>', {
|
||||
'class': 'btn btn-primary '+VIEW_PROFILE_BUTTON,
|
||||
}).append(h('i.fa.fa-shhare-alt'))
|
||||
.append(h('span', Messages.shareButton))
|
||||
.click(function () {
|
||||
var $blockShare = $('<div>', {class: PROFILE_SECTION}).appendTo($container);
|
||||
var button = h('button.btn.btn-primary.' + VIEW_PROFILE_BUTTON, {
|
||||
'aria-labelledby': 'cp-profile-share-button'
|
||||
}, [
|
||||
h('i.fa.fa-share-alt', { 'aria-hidden': 'true' }),
|
||||
h('span#cp-profile-share-button', Messages.shareButton)
|
||||
]);
|
||||
$(button).click(function () {
|
||||
Clipboard.copy(url, (err) => {
|
||||
if (!err) { UI.log(Messages.shareSuccess); }
|
||||
});
|
||||
}).appendTo($container);
|
||||
}).appendTo($blockShare);
|
||||
};
|
||||
|
||||
var addDisplayName = function ($container) {
|
||||
var $block = $('<div>', {id: DISPLAYNAME_ID}).appendTo($container);
|
||||
var $block = $('<div>', {'class': DISPLAYNAME_ID}).appendTo($container);
|
||||
APP.$name = $('<span>', {'class': DISPLAYNAME_ID}).appendTo($block);
|
||||
};
|
||||
var refreshName = function (data) {
|
||||
@ -134,7 +142,7 @@ define([
|
||||
};
|
||||
|
||||
var addLink = function ($container) {
|
||||
var $block = $('<div>', {id: LINK_ID}).appendTo($container);
|
||||
var $block = $('<div>', {class: PROFILE_SECTION}).appendTo($container);
|
||||
|
||||
APP.$link = $('<a>', {
|
||||
'class': LINK_ID,
|
||||
@ -158,8 +166,8 @@ define([
|
||||
}, Messages.profile_addLink);
|
||||
APP.$linkEdit = $(button);
|
||||
$block.append(button);
|
||||
var save = h('button.btn.btn-primary', Messages.settings_save);
|
||||
var text = h('input');
|
||||
var save = h('button.btn.btn-primary', { 'aria-labelledby': 'cp-save-link' }, Messages.settings_save);
|
||||
var text = h('input#cp-save-link');
|
||||
var code = h('div.cp-app-profile-link-code', [
|
||||
text,
|
||||
save
|
||||
@ -199,8 +207,9 @@ define([
|
||||
|
||||
var addFriendRequest = function ($container) {
|
||||
if (!APP.readOnly || !APP.common.isLoggedIn()) { return; }
|
||||
var $block = $('<div>', {class: PROFILE_SECTION}).appendTo($container);
|
||||
APP.$friend = $(h('div.cp-app-profile-friend-container'));
|
||||
$container.append(APP.$friend);
|
||||
$block.append(APP.$friend);
|
||||
};
|
||||
var refreshFriendRequest = function (data) {
|
||||
if (!APP.$friend) { return; }
|
||||
@ -221,14 +230,16 @@ define([
|
||||
if (friends[data.curvePublic]) {
|
||||
// Add friend message
|
||||
APP.$friend.append(h('p.cp-app-profile-friend', [
|
||||
h('i.fa.fa-address-book'),
|
||||
h('i.fa.fa-address-book', {'aria-hidden': 'true' }),
|
||||
Messages._getKey('isContact', [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
|
||||
var unfriendButton = h('button.btn.btn-primary.cp-app-profile-friend-request', {
|
||||
'aria-labelledby': 'cp-profile-unfriend-button'
|
||||
}, [
|
||||
h('i.fa.fa-user-times', {'aria-hidden': 'true' }),
|
||||
h('span#cp-profile-unfriend-button', Messages.contacts_remove)
|
||||
]);
|
||||
$(unfriendButton).click(function () {
|
||||
// Unfriend confirm
|
||||
@ -246,7 +257,7 @@ define([
|
||||
}
|
||||
|
||||
var button = h('button.btn.btn-success.cp-app-profile-friend-request', [
|
||||
h('i.fa.fa-user-plus'),
|
||||
h('i.fa.fa-user-plus', {'aria-hidden': 'true'}),
|
||||
]);
|
||||
var $button = $(button).appendTo(APP.$friend);
|
||||
|
||||
@ -261,9 +272,11 @@ define([
|
||||
}
|
||||
|
||||
var addCancel = function () {
|
||||
var cancelButton = h('button.btn.btn-danger.cp-app-profile-friend-request', [
|
||||
h('i.fa.fa-user-times'),
|
||||
Messages.cancel
|
||||
var cancelButton = h('button.btn.btn-danger.cp-app-profile-friend-request', {
|
||||
'aria-labelledby': 'cp-profile-cancel-button'
|
||||
},[
|
||||
h('i.fa.fa-user-times', {'aria-hidden': 'true' }),
|
||||
h('span#cp-profile-cancel-button' , Messages.cancel)
|
||||
]);
|
||||
$(cancelButton).click(function () {
|
||||
// Unfriend confirm
|
||||
@ -305,7 +318,7 @@ define([
|
||||
|
||||
var addMuteButton = function ($container) {
|
||||
if (!APP.readOnly || !APP.common.isLoggedIn()) { return; }
|
||||
APP.$mute = $(h('div.cp-app-profile-mute-container'));
|
||||
APP.$mute = $(h('div.cp-app-profile-mute-container.cp-app-profile-section'));
|
||||
$container.append(APP.$mute);
|
||||
};
|
||||
var refreshMute = function (data) {
|
||||
@ -317,7 +330,6 @@ define([
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Add mute/unmute buttons
|
||||
var $mute = APP.$mute;
|
||||
var module = common.makeUniversal('messenger');
|
||||
@ -326,9 +338,11 @@ define([
|
||||
$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'
|
||||
var unmuteButton = h('button.btn.btn-secondary.cp-app-profile-friend-request', {
|
||||
'aria-labelledby': 'cp-profile-unmute-button'
|
||||
}, [
|
||||
h('i.fa.fa-bell', {'aria-hidden': 'true' }),
|
||||
h('span#cp-profile-unmute-button', Messages.contacts_unmute || 'unmute')
|
||||
]);
|
||||
$(unmuteButton).click(function () {
|
||||
module.execCommand('UNMUTE_USER', data.curvePublic, function (e) {
|
||||
@ -338,10 +352,12 @@ define([
|
||||
}).appendTo($mute);
|
||||
return;
|
||||
}
|
||||
var muteButton = h('button.btn.btn-danger-outline.cp-app-profile-friend-request', [
|
||||
h('i.fa.fa-bell-slash'),
|
||||
Messages.contacts_mute || 'mute'
|
||||
]);
|
||||
var muteButton = h('button.btn.btn-danger-outline.cp-app-profile-friend-request', {
|
||||
'aria-labelledby': 'cp-profile-mute-button'
|
||||
}, [
|
||||
h('i.fa.fa-bell-slash', {'aria-hidden': 'true' }),
|
||||
h('span#cp-profile-mute-button', Messages.contacts_mute || 'mute')
|
||||
]);
|
||||
$(muteButton).click(function () {
|
||||
module.execCommand('MUTE_USER', {
|
||||
curvePublic: data.curvePublic,
|
||||
@ -374,7 +390,7 @@ define([
|
||||
|
||||
var $delButton = $('<button>', {
|
||||
'class': 'cp-app-profile-avatar-delete btn btn-danger fa fa-times',
|
||||
title: Messages.fc_delete
|
||||
title: Messages.profile_remove_avatar
|
||||
});
|
||||
$span.append($delButton);
|
||||
$delButton.click(function () {
|
||||
@ -419,10 +435,12 @@ define([
|
||||
}
|
||||
todo();
|
||||
});
|
||||
//upload profile photo button should be secondary
|
||||
var $upButton = common.createButton('upload', false, data);
|
||||
$upButton.removeClass('btn-primary').addClass('btn-secondary');
|
||||
$upButton.removeProp('title');
|
||||
$upButton.text(Messages.profile_upload);
|
||||
$upButton.prepend($('<span>', {'class': 'fa fa-upload'}));
|
||||
$upButton.prepend($('<i>', {'class': 'fa fa-upload', 'aria-hidden': 'true'}));
|
||||
$block.append($upButton);
|
||||
};
|
||||
var refreshAvatar = function (data) {
|
||||
@ -430,16 +448,21 @@ define([
|
||||
};
|
||||
|
||||
var addDescription = function ($container) {
|
||||
var $block = $('<div>', {id: DESCRIPTION_ID, class:'cp-sidebarlayout-element'}).appendTo($container);
|
||||
var $block = $('<div>', {id: DESCRIPTION_ID, class: PROFILE_SECTION}).appendTo($container);
|
||||
|
||||
APP.$description = $('<div>', {
|
||||
'id': 'cp-app-profile-description-info'
|
||||
}).appendTo($block);
|
||||
|
||||
APP.$description = $('<div>', {'class': 'cp-app-profile-description-rendered'}).appendTo($block);
|
||||
APP.$descriptionEdit = $();
|
||||
if (APP.readOnly) { return; }
|
||||
|
||||
var button = h('button.btn.btn-primary', [
|
||||
h('i.fa.fa-pencil'),
|
||||
h('span', Messages.profile_addDescription)
|
||||
]);
|
||||
var button = h('button.btn.btn-secondary', {
|
||||
'aria-labelledby': 'cp-profile-add-description-button'
|
||||
}, [
|
||||
h('i.fa.fa-pencil', {'aria-hidden': 'true' }),
|
||||
h('span#cp-profile-add-description-button', Messages.profile_addDescription)
|
||||
]);
|
||||
APP.$descriptionEdit = $(button);
|
||||
var save = h('button.btn.btn-primary', Messages.settings_save);
|
||||
var text = h('textarea');
|
||||
@ -454,6 +477,7 @@ define([
|
||||
code
|
||||
]);
|
||||
$block.append(div);
|
||||
$(div).insertBefore(APP.$description);
|
||||
|
||||
var cm = SFCodeMirror.create("gfm", CodeMirror, text);
|
||||
var editor = APP.editor = cm.editor;
|
||||
@ -462,6 +486,12 @@ define([
|
||||
editor.setOption('styleActiveLine', true);
|
||||
editor.setOption('readOnly', false);
|
||||
cm.configureTheme(common, function () {});
|
||||
editor.setOption("extraKeys", {
|
||||
"Esc": function () {
|
||||
cm.getInputField().blur();
|
||||
$(save).focus();
|
||||
}
|
||||
});
|
||||
|
||||
var markdownTb = common.createMarkdownToolbar(editor);
|
||||
$(code).prepend(markdownTb.toolbar);
|
||||
@ -486,7 +516,8 @@ define([
|
||||
});
|
||||
};
|
||||
var refreshDescription = function (data) {
|
||||
var val = Marked.parse(data.description || "");
|
||||
var descriptionData = data.description || "";
|
||||
var val = Marked.parse(descriptionData);
|
||||
APP.$description.html(val);
|
||||
APP.$description.off('click');
|
||||
APP.$description.click(function (e) {
|
||||
@ -509,12 +540,14 @@ define([
|
||||
if (!APP.readOnly) { return; }
|
||||
if (!Messages.profile_copyKey) { return; }
|
||||
|
||||
var $div = $(h('div.cp-sidebarlayout-element')).appendTo($container);
|
||||
var $div = $(h('div.cp-app-profile-section')).appendTo($container);
|
||||
APP.$edPublic = $('<button>', {
|
||||
'class': 'btn',
|
||||
}).append(h('i.fa.fa-key'))
|
||||
.append(h('span', Messages.profile_copyKey))
|
||||
.click(function () {
|
||||
'aria-labelledby': 'cp-profile-copy-key-button'
|
||||
}).append([
|
||||
h('i.fa.fa-key', {'aria-hidden': 'true' }),
|
||||
h('span#cp-profile-copy-key-button', Messages.profile_copyKey)
|
||||
]).click(function () {
|
||||
if (!APP.getEdPublic) { return; }
|
||||
APP.getEdPublic();
|
||||
}).appendTo($div).hide();
|
||||
@ -535,15 +568,16 @@ define([
|
||||
|
||||
var addCopyData = function ($container) {
|
||||
if (!APP.isModerator) { return; }
|
||||
|
||||
var $div = $(h('div.cp-sidebarlayout-element')).appendTo($container);
|
||||
APP.$copyData = $(h('button.btn.btn-secondary', [
|
||||
h('i.fa.fa-clipboard'),
|
||||
h('span', Messages.support_copyUserData)
|
||||
var $block = $('<div>', {class:PROFILE_SECTION}).appendTo($container);
|
||||
APP.$copyData = $(h('button.btn.btn-secondary', {
|
||||
'aria-labelledby': 'cp-profile-copy-data-button'
|
||||
}, [
|
||||
h('i.fa.fa-clipboard', {'aria-hidden': 'true' }),
|
||||
h('span#cp-profile-copy-data-button', Messages.support_copyUserData)
|
||||
])).click(function () {
|
||||
if (!APP.getCopyData) { return; }
|
||||
APP.getCopyData();
|
||||
}).appendTo($div).hide();
|
||||
}).appendTo($block).hide();
|
||||
};
|
||||
var setCopyDataButton = function (data) {
|
||||
if (!data.curvePublic) { return; }
|
||||
@ -575,10 +609,10 @@ define([
|
||||
addLink($rightside);
|
||||
addFriendRequest($rightside);
|
||||
addMuteButton($rightside);
|
||||
addDescription(APP.$rightside);
|
||||
addPublicKey($rightside);
|
||||
addCopyData($rightside);
|
||||
addViewButton($rightside);
|
||||
addDescription($rightside);
|
||||
APP.initialized = true;
|
||||
createLeftside();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user