Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
|
||||
@@ -162,7 +162,7 @@ define([
|
||||
])
|
||||
]),
|
||||
h('button.btn.btn-secondary.login.half.first', Msg.login_login),
|
||||
h('button.btn.btn-success.register.half.first', Msg.login_register),
|
||||
h('button.btn.btn-success.register.half', Msg.login_register),
|
||||
h('p.separator', Msg.login_orNoLogin),
|
||||
h('p#buttons.buttons'),
|
||||
h('p.driveLink', [
|
||||
@@ -363,7 +363,7 @@ define([
|
||||
h('button.btn.btn-primary.login.first', Msg.login_login),
|
||||
h('div.extra', [
|
||||
h('p', Msg.login_notRegistered),
|
||||
h('button#register.btn.btn-success.register.first', Msg.login_register)
|
||||
h('button#register.btn.btn-success.register', Msg.login_register)
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
|
||||
@@ -421,6 +421,8 @@ noscript {
|
||||
|
||||
label {
|
||||
margin-bottom: 0;
|
||||
margin-left: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
button {
|
||||
@@ -428,7 +430,7 @@ noscript {
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
&.half {
|
||||
width: ~"calc(50% - 2px)";
|
||||
width: ~"calc(50% - 10px)";
|
||||
&:not(.first) {
|
||||
float: right;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
|
||||
@@ -485,5 +485,32 @@ define(function () {
|
||||
out.canvas_opacityLabel = "Opacidad: {0}";
|
||||
out.canvas_widthLabel = "Talla: {0}";
|
||||
|
||||
// 1.10.0 - Kraken
|
||||
|
||||
out.moreActions = "Más acciones";
|
||||
out.importButton = "Importar";
|
||||
out.exportButton = "Exportar";
|
||||
out.saveTitle = "Guardar título (enter)";
|
||||
out.forgetButton = "Eliminar";
|
||||
out.printText = "Imprimir";
|
||||
out.slideOptionsText = "Opciones";
|
||||
out.historyText = "Historial";
|
||||
out.openLinkInNewTab = "Abrir enlace en pestaña nueva";
|
||||
out.profileButton = "Perfíl";
|
||||
out.profile_urlPlaceholder = "URL";
|
||||
out.profile_namePlaceholder = "Nombre mostrado en su perfíl";
|
||||
out.profile_avatar = "Imágen";
|
||||
out.profile_upload = "Subir una imágen";
|
||||
out.profile_error = "Error al crear tu perfíl: {0}";
|
||||
out.profile_register = "Tienes que registrarte para crear perfíl";
|
||||
out.profile_create = "Crear perfíl";
|
||||
out.profile_description = "Descripción";
|
||||
out.profile_fieldSaved = "Guardado: {0}";
|
||||
out.download_mt_button = "Descargar";
|
||||
out.updated_0_header_logoTitle = "Volver a tu CryptDrive";
|
||||
out.header_logoTitle = out.updated_0_header_logoTitle;
|
||||
|
||||
|
||||
|
||||
return out;
|
||||
});
|
||||
|
||||
@@ -36,6 +36,8 @@ define(function () {
|
||||
out.synced = "Everything is saved";
|
||||
out.deleted = "Pad deleted from your CryptDrive";
|
||||
|
||||
out.realtime_unrecoverableError = "The realtime engine has encountered an unrecoverable error. Click OK to reload.";
|
||||
|
||||
out.disconnected = 'Disconnected';
|
||||
out.synchronizing = 'Synchronizing';
|
||||
out.reconnecting = 'Reconnecting...';
|
||||
|
||||
@@ -30,7 +30,7 @@ const sizeForHashes = (hashes, dsFileStats) => {
|
||||
let sum = 0;
|
||||
hashes.forEach((h) => {
|
||||
const s = dsFileStats[h];
|
||||
if (typeof(s) !== 'number') {
|
||||
if (typeof(s) !== 'object' || typeof(s.size) !== 'number') {
|
||||
//console.log('missing ' + h + ' ' + typeof(s));
|
||||
} else {
|
||||
sum += s.size;
|
||||
@@ -62,11 +62,26 @@ nThen((waitFor) => {
|
||||
});
|
||||
});
|
||||
}).nThen((waitFor) => {
|
||||
|
||||
Fs.readdir('./blob', waitFor((err, list) => {
|
||||
if (err) { throw err; }
|
||||
dirList = list;
|
||||
}));
|
||||
}).nThen((waitFor) => {
|
||||
dirList.forEach((f) => {
|
||||
sema.take((returnAfter) => {
|
||||
Fs.readdir('./blob/' + f, waitFor(returnAfter((err, list2) => {
|
||||
if (err) { throw err; }
|
||||
list2.forEach((ff) => { fileList.push('./blob/' + f + '/' + ff); });
|
||||
})));
|
||||
});
|
||||
});
|
||||
}).nThen((waitFor) => {
|
||||
fileList.forEach((f) => {
|
||||
sema.take((returnAfter) => {
|
||||
Fs.stat(f, waitFor(returnAfter((err, st) => {
|
||||
if (err) { throw err; }
|
||||
dsFileStats[f.replace(/^.*\/([^\/]*)\.ndjson$/, (all, a) => (a))] = st;
|
||||
dsFileStats[f.replace(/^.*\/([^\/\.]*)(\.ndjson)?$/, (all, a) => (a))] = st;
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -129,7 +129,7 @@ Still there are other low-lives in the world so using CryptPad over HTTPS is pro
|
||||
|
||||
## Setup using Docker
|
||||
|
||||
See [Cryptpad-Docker](cryptpad-docker.md)
|
||||
See [Cryptpad-Docker](docs/cryptpad-docker.md)
|
||||
|
||||
## Translations
|
||||
|
||||
|
||||
21
rpc.js
21
rpc.js
@@ -113,15 +113,21 @@ var isTooOld = function (time, now) {
|
||||
return (now - time) > 300000;
|
||||
};
|
||||
|
||||
var expireSessions = function (Sessions) {
|
||||
var now = +new Date();
|
||||
Object.keys(Sessions).forEach(function (key) {
|
||||
var expireSession = function (Sessions, key) {
|
||||
var session = Sessions[key];
|
||||
if (isTooOld(Sessions[key].atime, now)) {
|
||||
if (!session) { return; }
|
||||
if (session.blobstage) {
|
||||
session.blobstage.close();
|
||||
}
|
||||
delete Sessions[key];
|
||||
};
|
||||
|
||||
var expireSessions = function (Sessions) {
|
||||
var now = +new Date();
|
||||
Object.keys(Sessions).forEach(function (key) {
|
||||
var session = Sessions[key];
|
||||
if (session && isTooOld(session.atime, now)) {
|
||||
expireSession(Sessions, key);
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -846,6 +852,7 @@ var isAuthenticatedCall = function (call) {
|
||||
'GET_LIMIT',
|
||||
'UPLOAD_COMPLETE',
|
||||
'UPLOAD_CANCEL',
|
||||
'EXPIRE_SESSION',
|
||||
].indexOf(call) !== -1;
|
||||
};
|
||||
|
||||
@@ -1046,7 +1053,11 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)
|
||||
}
|
||||
Respond(void 0, dict);
|
||||
});
|
||||
|
||||
case 'EXPIRE_SESSION':
|
||||
return void setTimeout(function () {
|
||||
expireSession(Sessions, safeKey);
|
||||
Respond(void 0, "OK");
|
||||
});
|
||||
// restricted to privileged users...
|
||||
case 'UPLOAD':
|
||||
if (!privileged) { return deny(); }
|
||||
|
||||
@@ -159,6 +159,9 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
var randomToken = function () {
|
||||
return Math.random().toString(16).replace(/0./, '');
|
||||
};
|
||||
var feedback = common.feedback = function (action, force) {
|
||||
if (force !== true) {
|
||||
if (!action) { return; }
|
||||
@@ -167,7 +170,7 @@ define([
|
||||
} catch (e) { return void console.error(e); }
|
||||
}
|
||||
|
||||
var href = '/common/feedback.html?' + action + '=' + (+new Date());
|
||||
var href = '/common/feedback.html?' + action + '=' + randomToken();
|
||||
$.ajax({
|
||||
type: "HEAD",
|
||||
url: href,
|
||||
@@ -199,13 +202,29 @@ define([
|
||||
return;
|
||||
};
|
||||
|
||||
common.infiniteSpinnerDetected = false;
|
||||
var whenRealtimeSyncs = common.whenRealtimeSyncs = function (realtime, cb) {
|
||||
realtime.sync();
|
||||
|
||||
window.setTimeout(function () {
|
||||
if (realtime.getAuthDoc() === realtime.getUserDoc()) {
|
||||
return void cb();
|
||||
}
|
||||
|
||||
var to = setTimeout(function () {
|
||||
realtime.abort();
|
||||
// don't launch more than one popup
|
||||
if (common.infiniteSpinnerDetected) { return; }
|
||||
|
||||
// inform the user their session is in a bad state
|
||||
common.confirm(Messages.realtime_unrecoverableError, function (yes) {
|
||||
if (!yes) { return; }
|
||||
window.location.reload();
|
||||
});
|
||||
common.infiniteSpinnerDetected = true;
|
||||
}, 30000);
|
||||
realtime.onSettle(function () {
|
||||
clearTimeout(to);
|
||||
cb();
|
||||
});
|
||||
}, 0);
|
||||
|
||||
@@ -416,6 +416,11 @@ span {
|
||||
}
|
||||
.path {
|
||||
font-style: italic;
|
||||
direction: rtl;
|
||||
.element {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
font-weight: bold;
|
||||
|
||||
@@ -528,6 +528,12 @@ define([
|
||||
module.displayDirectory(currentPath);
|
||||
};
|
||||
|
||||
var getFileNameExtension = function (name) {
|
||||
var matched = /\.\S+$/.exec(name);
|
||||
if (matched && matched.length) { return matched[matched.length -1]; }
|
||||
return '';
|
||||
};
|
||||
|
||||
// Replace a file/folder name by an input to change its value
|
||||
var displayRenameInput = function ($element, path) {
|
||||
// NOTE: setTimeout(f, 0) otherwise the "rename" button in the toolbar is not working
|
||||
@@ -551,6 +557,7 @@ define([
|
||||
value: name
|
||||
}).data('path', path);
|
||||
|
||||
|
||||
// Stop propagation on keydown to avoid issues with arrow keys
|
||||
$input.on('keydown', function (e) { e.stopPropagation(); });
|
||||
|
||||
@@ -567,7 +574,12 @@ define([
|
||||
//$element.parent().append($input);
|
||||
$name.after($input);
|
||||
$input.focus();
|
||||
$input.select();
|
||||
|
||||
var extension = getFileNameExtension(name);
|
||||
var input = $input[0];
|
||||
input.selectionStart = 0;
|
||||
input.selectionEnd = name.length - extension.length;
|
||||
|
||||
// We don't want to open the file/folder when clicking on the input
|
||||
$input.on('click dblclick', function (e) {
|
||||
removeSelected();
|
||||
@@ -1250,12 +1262,11 @@ define([
|
||||
};
|
||||
|
||||
// Create the title block with the "parent folder" button
|
||||
var createTitle = function (path, noStyle) {
|
||||
var createTitle = function ($container, path, noStyle) {
|
||||
if (!path || path.length === 0) { return; }
|
||||
var isTrash = filesOp.isPathIn(path, [TRASH]);
|
||||
var $title = $driveToolbar.find('.path');
|
||||
if (APP.mobile()) {
|
||||
return $title;
|
||||
if (APP.mobile() && !noStyle) { // noStyle means title in search result
|
||||
return $container;
|
||||
}
|
||||
var el = path[0] === SEARCH ? undefined : filesOp.find(path);
|
||||
path = path[0] === SEARCH ? path.slice(0,1) : path;
|
||||
@@ -1281,12 +1292,11 @@ define([
|
||||
if (idx === 0) { name = getPrettyName(p); }
|
||||
else {
|
||||
var $span2 = $('<span>', {'class': 'element separator'}).text(' / ');
|
||||
$title.prepend($span2);
|
||||
$container.prepend($span2);
|
||||
}
|
||||
|
||||
$span.text(name).prependTo($title);
|
||||
$span.text(name).prependTo($container);
|
||||
});
|
||||
return $title;
|
||||
};
|
||||
|
||||
var createInfoBox = function (path) {
|
||||
@@ -1764,7 +1774,8 @@ define([
|
||||
path.pop();
|
||||
path.push(r.data.title);
|
||||
}
|
||||
var $path = $('<td>', {'class': 'col1 path'}).html(createTitle(path, true).html());
|
||||
var $path = $('<td>', {'class': 'col1 path'});
|
||||
createTitle($path, path, true);
|
||||
var parentPath = path.slice();
|
||||
var $a;
|
||||
if (parentPath) {
|
||||
@@ -1859,7 +1870,7 @@ define([
|
||||
// NewButton can be undefined if we're in read only mode
|
||||
createNewButton(isInRoot, $toolbar.find('.leftside'));
|
||||
|
||||
createTitle(path).appendTo($toolbar.find('.path'));
|
||||
createTitle($toolbar.find('.path'), path);
|
||||
|
||||
if (APP.mobile()) {
|
||||
var $context = $('<button>', {'class': 'element right dropdown-bar', id: 'contextButton'});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
|
||||
@@ -54,7 +54,7 @@ define([
|
||||
};
|
||||
loginReady();
|
||||
|
||||
var $uname = $('#name');
|
||||
var $uname = $('#name').focus();
|
||||
|
||||
var $passwd = $('#password')
|
||||
// background loading of login assets
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#container {
|
||||
font-size: 25px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
#header {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
|
||||
@@ -69,6 +69,12 @@ define([
|
||||
$content.find('.slide-container').first().css('margin-left', -(i*100)+'%');
|
||||
updateFontSize();
|
||||
change(Slide.lastIndex, Slide.index);
|
||||
$modal.find('#button_left > span').css({
|
||||
opacity: Slide.index === 0? 0: 1
|
||||
});
|
||||
$modal.find('#button_right > span').css({
|
||||
opacity: Slide.index === (getNumberOfSlides() -1)? 0: 1
|
||||
});
|
||||
};
|
||||
var draw = Slide.draw = function (i) {
|
||||
if (typeof(Slide.content) !== 'string') { return; }
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
|
||||
Reference in New Issue
Block a user