Merge branch 'staging' into oo

This commit is contained in:
yflory
2018-02-19 12:11:06 +01:00
72 changed files with 1549 additions and 511 deletions

View File

@@ -0,0 +1,61 @@
define([
'/bower_components/chainpad/chainpad.dist.js',
], function (ChainPad) {
var Diff = ChainPad.Diff;
var isSpace = function (S, i) {
return /^\s$/.test(S.charAt(i));
};
var leadingBoundary = function (S, offset) {
if (/\s/.test(S.charAt(offset))) { return offset; }
while (offset > 0) {
offset--;
if (isSpace(S, offset)) { offset++; break; }
}
return offset;
};
var trailingBoundary = function (S, offset) {
if (isSpace(S, offset)) { return offset; }
while (offset < S.length && !/\s/.test(S.charAt(offset))) {
offset++;
}
return offset;
};
var opsToWords = function (previous, current) {
var output = [];
Diff.diff(previous, current).forEach(function (op) {
// ignore deleted sections...
var offset = op.offset;
var toInsert = op.toInsert;
// given an operation, check whether it is a word fragment,
// if it is, expand it to its word boundaries
var first = current.slice(leadingBoundary(current, offset), offset);
var last = current.slice(offset + toInsert.length, trailingBoundary(current, offset + toInsert.length));
var result = first + toInsert + last;
// concat-in-place
Array.prototype.push.apply(output, result.split(/\s+/));
});
return output.filter(Boolean);
};
var runningDiff = function (getter, f, time) {
var last = getter();
// first time through, send all the words :D
f(opsToWords("", last));
return setInterval(function () {
var current = getter();
// find inserted words...
var words = opsToWords(last, current);
last = current;
f(words);
}, time);
};
return runningDiff;
});

View File

@@ -6,10 +6,17 @@ define([
'/common/outer/network-config.js',
'/customize/credential.js',
'/bower_components/chainpad/chainpad.dist.js',
'/common/common-realtime.js',
'/common/common-constants.js',
'/common/common-interface.js',
'/common/common-feedback.js',
'/common/outer/local-store.js',
'/customize/messages.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
'/bower_components/scrypt-async/scrypt-async.min.js', // better load speed
], function ($, Listmap, Crypto, Util, NetConfig, Cred, ChainPad) {
], function ($, Listmap, Crypto, Util, NetConfig, Cred, ChainPad, Realtime, Constants, UI,
Feedback, LocalStore, Messages) {
var Exports = {
Cred: Cred,
};
@@ -73,7 +80,7 @@ define([
var rt = opt.rt = Listmap.create(config);
rt.proxy
.on('ready', function () {
cb(void 0, rt);
setTimeout(function () { cb(void 0, rt); });
})
.on('disconnect', function (info) {
cb('E_DISCONNECT', info);
@@ -84,7 +91,7 @@ define([
return Object.keys(proxy).length === 0;
};
Exports.loginOrRegister = function (uname, passwd, isRegister, cb) {
Exports.loginOrRegister = function (uname, passwd, isRegister, shouldImport, cb) {
if (typeof(cb) !== 'function') { return; }
// Usernames are all lowercase. No going back on this one
@@ -137,10 +144,140 @@ define([
return void cb('ALREADY_REGISTERED', res);
}
setTimeout(function () { cb(void 0, res); });
if (isRegister) {
var proxy = rt.proxy;
proxy.edPublic = res.edPublic;
proxy.edPrivate = res.edPrivate;
proxy.curvePublic = res.curvePublic;
proxy.curvePrivate = res.curvePrivate;
proxy.login_name = uname;
proxy[Constants.displayNameKey] = uname;
sessionStorage.createReadme = 1;
Feedback.send('REGISTRATION', true);
} else {
Feedback.send('LOGIN', true);
}
if (shouldImport) {
sessionStorage.migrateAnonDrive = 1;
}
// We have to call whenRealtimeSyncs asynchronously here because in the current
// version of listmap, onLocal calls `chainpad.contentUpdate(newValue)`
// asynchronously.
// The following setTimeout is here to make sure whenRealtimeSyncs is called after
// `contentUpdate` so that we have an update userDoc in chainpad.
setTimeout(function () {
Realtime.whenRealtimeSyncs(rt.realtime, function () {
LocalStore.login(res.userHash, res.userName, function () {
setTimeout(function () { cb(void 0, res); });
});
});
});
});
});
};
Exports.redirect = function () {
if (sessionStorage.redirectTo) {
var h = sessionStorage.redirectTo;
var parser = document.createElement('a');
parser.href = h;
if (parser.origin === window.location.origin) {
delete sessionStorage.redirectTo;
window.location.href = h;
return;
}
}
window.location.href = '/drive/';
};
Exports.loginOrRegisterUI = function (uname, passwd, isRegister, shouldImport, testing, test) {
var hashing = true;
var proceed = function (result) {
hashing = false;
if (test && typeof test === "function" && test()) { return; }
Realtime.whenRealtimeSyncs(result.realtime, function () {
Exports.redirect();
});
};
// setTimeout 100ms to remove the keyboard on mobile devices before the loading screen
// pops up
window.setTimeout(function () {
UI.addLoadingScreen({
loadingText: Messages.login_hashing,
hideTips: true,
});
// We need a setTimeout(cb, 0) otherwise the loading screen is only displayed
// after hashing the password
window.setTimeout(function () {
Exports.loginOrRegister(uname, passwd, isRegister, shouldImport, function (err, result) {
var proxy;
if (result) { proxy = result.proxy; }
if (err) {
switch (err) {
case 'NO_SUCH_USER':
UI.removeLoadingScreen(function () {
UI.alert(Messages.login_noSuchUser, function () {
hashing = false;
});
});
break;
case 'INVAL_USER':
UI.removeLoadingScreen(function () {
UI.alert(Messages.login_invalUser, function () {
hashing = false;
});
});
break;
case 'INVAL_PASS':
UI.removeLoadingScreen(function () {
UI.alert(Messages.login_invalPass, function () {
hashing = false;
});
});
break;
case 'PASS_TOO_SHORT':
UI.removeLoadingScreen(function () {
var warning = Messages._getKey('register_passwordTooShort', [
Cred.MINIMUM_PASSWORD_LENGTH
]);
UI.alert(warning, function () {
hashing = false;
});
});
break;
case 'ALREADY_REGISTERED':
// logMeIn should reset registering = false
UI.removeLoadingScreen(function () {
UI.confirm(Messages.register_alreadyRegistered, function (yes) {
if (!yes) { return; }
proxy.login_name = uname;
if (!proxy[Constants.displayNameKey]) {
proxy[Constants.displayNameKey] = uname;
}
LocalStore.eraseTempSessionValues();
proceed(result);
});
});
break;
default: // UNHANDLED ERROR
hashing = false;
UI.errorLoadingScreen(Messages.login_unhandledError);
}
return;
}
if (testing) { return void proceed(result); }
proceed(result);
});
}, 0);
}, 200);
};
return Exports;
});

View File

@@ -43,7 +43,7 @@ define(req, function(Util, Default, Language) {
messages._checkTranslationState = function (cb) {
if (typeof(cb) !== "function") { return; }
var missing = [];
var allMissing = [];
var reqs = [];
Object.keys(map).forEach(function (code) {
if (code === defaultLanguage) { return; }
@@ -54,37 +54,60 @@ define(req, function(Util, Default, Language) {
Object.keys(map).forEach(function (code, i) {
if (code === defaultLanguage) { return; }
var translation = langs[i];
var updated = {};
Object.keys(Default).forEach(function (k) {
if (/^updated_[0-9]+_/.test(k) && !translation[k]) {
var key = k.split('_').slice(2).join('_');
// Make sure we don't already have an update for that key. It should not happen
// but if it does, keep the latest version
if (updated[key]) {
var ek = updated[key];
if (parseInt(ek.split('_')[1]) > parseInt(k.split('_')[1])) { return; }
var missing = [];
var checkInObject = function (ref, translated, path) {
var updated = {};
Object.keys(ref).forEach(function (k) {
if (/^updated_[0-9]+_/.test(k) && !translated[k]) {
var key = k.split('_').slice(2).join('_');
// Make sure we don't already have an update for that key. It should not happen
// but if it does, keep the latest version
if (updated[key]) {
var ek = updated[key];
if (parseInt(ek.split('_')[1]) > parseInt(k.split('_')[1])) { return; }
}
updated[key] = k;
}
updated[key] = k;
}
});
Object.keys(Default).forEach(function (k) {
if (/^_/.test(k) || k === 'driveReadme') { return; }
if (!translation[k] || updated[k]) {
if (updated[k]) {
missing.push([code, k, 2, 'out.' + updated[k]]);
return;
});
Object.keys(ref).forEach(function (k) {
if (/^_/.test(k) || k === 'driveReadme') { return; }
var nPath = path.slice();
nPath.push(k);
if (!translated[k] || updated[k]) {
if (updated[k]) {
var uPath = path.slice();
uPath.unshift('out');
missing.push([code, nPath, 2, uPath.join('.') + '.' + updated[k]]);
return;
}
return void missing.push([code, nPath, 1]);
}
missing.push([code, k, 1]);
}
});
Object.keys(translation).forEach(function (k) {
if (/^_/.test(k) || k === 'driveReadme') { return; }
if (!Default[k]) {
missing.push([code, k, 0]);
}
if (typeof ref[k] !== typeof translated[k]) {
return void missing.push([code, nPath, 3]);
}
if (typeof ref[k] === "object" && !Array.isArray(ref[k])) {
checkInObject(ref[k], translated[k], nPath);
}
});
Object.keys(translated).forEach(function (k) {
if (/^_/.test(k) || k === 'driveReadme') { return; }
var nPath = path.slice();
nPath.push(k);
if (typeof ref[k] === "undefined") {
missing.push([code, nPath, 0]);
}
});
};
checkInObject(Default, translation, []);
// Push the removals at the end
missing.sort(function (a, b) {
if (a[2] === 0 && b[2] !== 0) { return 1; }
if (a[2] !== 0 && b[2] === 0) { return -1; }
return 0;
});
Array.prototype.push.apply(allMissing, missing); // Destructive concat
});
cb(missing);
cb(allMissing);
});
};

View File

@@ -72,7 +72,7 @@ define([
])
])
]),
h('div.cp-version-footer', "CryptPad v1.25.0 (Zombie)")
h('div.cp-version-footer', "CryptPad v1.26.0 (undefined)")
]);
};
@@ -100,6 +100,7 @@ define([
h('div.collapse.navbar-collapse.justify-content-end#menuCollapse', [
h('a.nav-item.nav-link', { href: '/what-is-cryptpad.html'}, Msg.topbar_whatIsCryptpad),
h('a.nav-item.nav-link', { href: 'https://blog.cryptpad.fr/'}, Msg.blog),
h('a.nav-item.nav-link', { href: '/features.html'}, Msg.features),
h('a.nav-item.nav-link', { href: '/contact.html'}, Msg.contact),
h('a.nav-item.nav-link', { href: '/about.html'}, Msg.about),
].concat(rightLinks))
@@ -332,6 +333,11 @@ define([
h('td')
]),
])
]),
h('div#cp-features-register', [
h('a', {
href: '/register/'
}, h('button.cp-features-register-button', 'Register for free'))
])
]),
infopageFooter()
@@ -367,6 +373,42 @@ define([
]);
};
Pages['/faq.html'] = function () {
var categories = [];
var faq = Msg.faq;
Object.keys(faq).forEach(function (c) {
var questions = [];
Object.keys(faq[c]).forEach(function (q) {
var item = faq[c][q];
if (typeof item !== "object") { return; }
var answer = h('p.cp-faq-questions-a');
var question = h('p.cp-faq-questions-q');
$(question).click(function () {
if ($(answer).is(':visible')) {
return void $(answer).slideUp();
}
$(answer).slideDown();
});
questions.push(h('div.cp-faq-questions-items', [
setHTML(question, item.q),
setHTML(answer, item.a)
]));
});
categories.push(h('div.cp-faq-category', [
h('h3', faq[c].title),
h('div.cp-faq-category-questions', questions)
]));
});
return h('div#cp-main', [
infopageTopbar(),
h('div.container.cp-container', [
h('center', h('h1', Msg.faq_title)),
h('div.cp-faq-container', categories)
]),
infopageFooter()
]);
};
Pages['/terms.html'] = function () {
return h('div#cp-main', [
infopageTopbar(),
@@ -601,6 +643,9 @@ define([
setHTML(h('p.register-explanation'), Msg.register_explanation)
]),
h('div#userForm.form-group.hidden.col-md-6', [
h('a', {
href: '/features.html'
}, Msg.register_whyRegister),
h('input.form-control#username', {
type: 'text',
autocomplete: 'off',

View File

@@ -139,7 +139,7 @@
> * {
width: 100%;
min-width: 300px;
min-width: 260px;
max-width: 500px;
margin: 0 auto;
text-align: left;
@@ -184,7 +184,7 @@
}
}
.alertify-tabs-contents {
flex: 1;
flex: 1 1 auto;
min-height: 0;
& > div {
max-height: 100%;

View File

@@ -12,15 +12,16 @@
background: @colortheme_loading-bg;
color: @colortheme_loading-color;
display: flex;
align-items: center;
flex-flow: column; /* we need column so that the child can shrink vertically */
justify-content: center;
width: 100%;
height: 100%;
overflow: auto;
@media screen and (max-height: 600px), screen and (max-width: 500px) {
align-items: baseline;
}
}
#cp-creation {
flex: 0 1 auto; /* allows shrink */
min-height: 0;
overflow: auto;
text-align: center;
font: @colortheme_app-font;
width: 100%;
@@ -33,24 +34,35 @@
flex-wrap: wrap;
justify-content: center;
align-items: center;
h2, p {
width: 100%;
}
h2 {
width: 100%;
display: flex;
margin-bottom: 20px;
justify-content: space-between;
.cp-creation-help {
display: none;
}
}
.cp-creation-help-container {
width: 100%;
display: flex;
justify-content: space-between;
p {
padding: 0 20px;
flex-grow: 0;
flex-shrink: 0;
flex-basis: 50%;
text-align: justify;
}
}
@media screen and (max-width: 500px) {
width: ~"calc(100% - 30px)";
}
@media screen and (max-height: 600px), screen and (max-width: 500px) {
@media screen and (max-height: 800px), screen and (max-width: 500px) {
h2 .cp-creation-help {
display: inline;
}
p {
.cp-creation-help-container {
display: none;
}
}
@@ -139,5 +151,20 @@
}
}
}
.cp-creation-settings {
justify-content: left;
a {
color: #0275d8;
&:hover {
color: lighten(#0275d8, 10%);
}
}
}
.cp-creation-deleted {
background: #111;
padding: 10px;
text-align: justify;
font-weight: bold;
}
}
}

View File

@@ -8,9 +8,10 @@
width: 100%;
margin-top: 20px;
.cp-limit-bar {
padding: 5px;
display: inline-flex;
justify-content: center;
align-items: center;
display: inline-block;
max-width: 100%;
margin: 3px;
box-sizing: border-box;
@@ -18,7 +19,6 @@
background: white;
position: relative;
text-align: center;
vertical-align: middle;
width: ~"calc(100% - 6px)";
height: 35px;
line-height: 25px;
@@ -29,6 +29,7 @@
background: blue;
position: absolute;
left: 0;
top: 0;
z-index: 1; // .usage
&.cp-limit-usage-normal {
background: @colortheme_green;

View File

@@ -131,6 +131,7 @@
white-space: nowrap;
display: flex;
flex-flow: column;
height: 100%;
.cp-toolbar-userlist-name {
flex: 1;
overflow: hidden;
@@ -759,7 +760,7 @@
display: inline-flex;
align-items: center;
max-width: 100%;
flex: 1;
flex: 1 1 auto;
//margin-bottom: -1px;
.cp-toolbar-users {
pre {

View File

@@ -10,6 +10,7 @@ body.cp-page-what-is-cryptpad { @import "./pages/page-what-is-cryptpad.less"; }
body.cp-page-about { @import "./pages/page-about.less"; }
body.cp-page-privacy { @import "./pages/page-privacy.less"; }
body.cp-page-features { @import "./pages/page-features.less"; }
body.cp-page-faq { @import "./pages/page-faq.less"; }
body.cp-page-terms { @import "./pages/page-terms.less"; }
// Set the HTML style for the apps which shouldn't have a body scrollbar

View File

@@ -50,3 +50,18 @@ table#cp-features-table {
}
}
#cp-features-register {
text-align: center;
padding: 20px;
}
.cp-features-register-button {
font-size: 20px;
color: #fff;
background: @cryptpad_color_blue;
border: 2px solid @cryptpad_color_blue;
border-radius: 0;
&:hover {
transform: scale(1.05);
}
}

0
customize.dist/translations/messages.el.js Executable file → Normal file
View File

View File

@@ -31,12 +31,16 @@ define(function () {
out.wrongApp = "Impossible d'afficher le contenu de ce document temps-réel dans votre navigateur. Vous pouvez essayer de recharger la page.";
out.padNotPinned = 'Ce pad va expirer dans 3 mois, {0}connectez-vous{1} ou {2}enregistrez-vous{3} pour le préserver.';
out.anonymousStoreDisabled = "L'administrateur de cette instance de CryptPad a désactivé le drive pour les utilisateurs non enregistrés. Vous devez vous connecter pour pouvoir utiliser CryptDrive.";
out.expiredError = "Ce pad a atteint sa date d'expiration est n'est donc plus disponible.";
out.expiredErrorCopy = ' Vous pouvez toujours copier son contenu ailleurs en appuyant sur <em>Échap</em>.<br> Dés que vous aurez quitté la page, il sera impossible de le récupérer.';
out.deletedError = 'Ce pad a été supprimé par son propriétaire et n\'est donc plus disponible.';
out.loading = "Chargement...";
out.error = "Erreur";
out.saved = "Enregistré";
out.synced = "Tout est enregistré";
out.deleted = "Pad supprimé de votre CryptDrive";
out.deletedFromServer = "Pad supprimé du serveur";
out.realtime_unrecoverableError = "Le moteur temps-réel a rencontré une erreur critique. Cliquez sur OK pour recharger la page.";
@@ -377,7 +381,8 @@ define(function () {
out.fm_emptyTrashDialog = "Êtes-vous sûr de vouloir vider la corbeille ?";
out.fm_removeSeveralPermanentlyDialog = "Êtes-vous sûr de vouloir supprimer ces {0} éléments de votre CryptDrive de manière permanente ?";
out.fm_removePermanentlyDialog = "Êtes-vous sûr de vouloir supprimer cet élément de votre CryptDrive de manière permanente ?";
out.fm_deleteOwnedPads = "Êtes-vous sûr de vouloir supprimer définitivement ce pad du serveur ?";
out.fm_deleteOwnedPad = "Êtes-vous sûr de vouloir supprimer définitivement ce pad du serveur ?";
out.fm_deleteOwnedPads = "Êtes-vous sûr de vouloir supprimer définitivement ces pads du serveur ?";
out.fm_restoreDialog = "Êtes-vous sûr de vouloir restaurer {0} à son emplacement précédent ?";
out.fm_removeSeveralDialog = "Êtes-vous sûr de vouloir déplacer ces {0} éléments vers la corbeille ?";
out.fm_removeDialog = "Êtes-vous sûr de vouloir déplacer {0} vers la corbeille ?";
@@ -392,7 +397,8 @@ define(function () {
out.updated_0_fm_info_trash = "Vider la corbeille permet de libérer de l'espace dans votre CryptDrive";
out.fm_info_trash = out.updated_0_fm_info_trash;
out.fm_info_allFiles = 'Contient tous les fichiers de "Documents", "Fichiers non triés" et "Corbeille". Vous ne pouvez pas supprimer ou déplacer des fichiers depuis cet endroit.'; // Same here
out.fm_info_anonymous = 'Vous n\'êtes pas connecté, ces pads risquent donc d\'être supprimés (<a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">découvrez pourquoi</a>). ' +
out.fm_info_anonymous = 'Vous n\'êtes pas connecté, ces pads seront donc supprimés après 3 mois d\'inactivité (<a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">découvrez pourquoi</a>). ' +
'Ils sont stockés dans votre navigateur donc nettoyer votre historique peut les faire disparaître.<br>' +
'<a href="/register/">Inscrivez-vous</a> ou <a href="/login/">connectez-vous</a> pour les maintenir en vie.';
out.fm_info_owned = "Vous êtes propriétaire des pads affichés dans cette catégorie. Cela signifie que vous pouvez choisir de les supprimer définitivement du serveur à n'importe quel moment. Ils seront alors inaccessibles pour tous les autres utilisateurs.";
out.fm_alert_backupUrl = "Lien de secours pour ce CryptDrive.<br>" +
@@ -415,6 +421,7 @@ define(function () {
"Cette action supprimera votre CryptDrive et son historique de votre navigateur, mais les pads existeront toujours (de manière chiffrée) sur notre serveur.";
out.fm_padIsOwned = "Vous êtes le propriétaire de ce pad";
out.fm_padIsOwnedOther = "Ce pad est la propriété d'un autre utilisateur";
out.fm_deletedPads = "Ces pads n'existent plus sur le serveur, ils ont été supprimés de votre CryptDrive: {0}";
// File - Context menu
out.fc_newfolder = "Nouveau dossier";
out.fc_rename = "Renommer";
@@ -474,6 +481,7 @@ define(function () {
out.register_warning = "Zero Knowledge signifie que nous ne pouvons pas récupérer vos données si vous perdez vos identifiants.";
out.register_alreadyRegistered = "Cet utilisateur existe déjà, souhaitez-vous vous connecter ?";
out.register_whyRegister = "Pourquoi s'inscrire ?";
out.register_header = "Bienvenue dans CryptPad";
out.register_explanation = [
"<p>Faisons d'abord le point sur certaines choses</p>",
@@ -490,6 +498,7 @@ define(function () {
out.settings_cat_code = "Code";
out.settings_cat_pad = "Documents texte";
out.settings_cat_creation = "Nouveau pad";
out.settings_cat_subscription = "Abonnement";
out.settings_title = "Préférences";
out.settings_save = "Sauver";
@@ -566,7 +575,9 @@ define(function () {
out.upload_uploadPending = "Vous avez déjà un fichier en cours d'importation. Souhaitez-vous l'annuler et importer ce nouveau fichier ?";
out.upload_success = "Votre fichier ({0}) a été importé avec succès et ajouté à votre CryptDrive.";
out.upload_notEnoughSpace = "Il n'y a pas assez d'espace libre dans votre CryptDrive pour ce fichier.";
out.upload_notEnoughSpaceBrief = "Pas assez d'espace";
out.upload_tooLarge = "Ce fichier dépasse la taille maximale autorisée.";
out.upload_tooLargeBrief = 'Fichier trop volumineux';
out.upload_choose = "Choisir un fichier";
out.upload_pending = "En attente";
out.upload_cancelled = "Annulé";
@@ -576,6 +587,7 @@ define(function () {
out.upload_mustLogin = "Vous devez vous connecter pour importer un fichier";
out.download_button = "Déchiffrer et télécharger";
out.download_mt_button = "Télécharger";
out.download_resourceNotAvailable = "Le fichier demandé n'est pas disponible...";
out.todo_title = "CryptTodo";
out.todo_newTodoNamePlaceholder = "Décrivez votre tâche...";
@@ -706,6 +718,7 @@ define(function () {
// features.html
out.features = "Fonctionnalités";
out.features_title = "Tableau des fonctionnalités";
out.features_feature = "Fonctionnalité";
out.features_anon = "Utilisateur anonyme";
@@ -838,6 +851,24 @@ define(function () {
out.feedback_optout = "Si vous le souhaitez, vous pouvez désactiver ces requêtes en vous rendant dans <a href='/settings/'>votre page de préférences</a>, où vous trouverez une case à cocher pour désactiver le retour d'expérience.";
// Creation page
out.creation_404 = "Ce pad n'existe plus. Vous pouvez créer un nouveau pad en utilisant le formulaire suivant.";
out.creation_ownedTitle = "Type de pad";
out.creation_ownedTrue = "Pad possédé";
out.creation_ownedFalse = "Pad ouvert";
out.creation_owned1 = "Un pad <b>possédé</b> peut être supprimé du serveur à tout moment quand son propriétaire le souhaite. Une fois supprimé, il disparaît du CryptDrive des autres utilisateurs.";
out.creation_owned2 = "Un pad <b>ouvert</b> n'a pas de propriétaire et ne peut donc pas être supprimé du serveur à moins d'avoir dépassé sa date d'expiration.";
out.creation_expireTitle = "Durée de vie";
out.creation_expireTrue = "Ajouter durée de vie";
out.creation_expireFalse = "Illimité";
out.creation_expireHours = "Heure(s)";
out.creation_expireDays = "Jour(s)";
out.creation_expireMonths = "Mois";
out.creation_expire1 = "Un pad <b>illimité</b> ne sera pas supprimé du serveur à moins que son propriétaire ne le décide.";
out.creation_expire2 = "Un pad <b>expirant</b> a une durée de vie définie, après laquelle il sera supprimé automatiquement du serveur et du CryptDrive des utilisateurs.";
out.creation_createTitle = "Créer un pad";
out.creation_createFromTemplate = "Depuis un modèle";
out.creation_createFromScratch = "Nouveau pad vide";
out.creation_settings = "Préférences des nouveaux pads";
// Properties about creation data
out.creation_owners = "Propriétaires";
out.creation_ownedByOther = "Possédé par un autre utilisateur";

View File

@@ -22,8 +22,7 @@ define(function () {
out.button_newslide = 'New Presentation';
out.button_newwhiteboard = 'New Whiteboard';
// NOTE: We want to update the 'common_connectionLost' key.
// Please do not add a new 'updated_common_connectionLostAndInfo' but change directly the value of 'common_connectionLost'
// NOTE: Remove updated_0_ if we need an updated_1_
out.updated_0_common_connectionLost = "<b>Server Connection Lost</b><br>You're now in read-only mode until the connection is back.";
out.common_connectionLost = out.updated_0_common_connectionLost;
@@ -33,12 +32,16 @@ define(function () {
out.wrongApp = "Unable to display the content of that realtime session in your browser. Please try to reload that page.";
out.padNotPinned = 'This pad will expire in 3 months, {0}login{1} or {2}register{3} to preserve it.';
out.anonymousStoreDisabled = "The webmaster of this CryptPad instance has disabled the store for anonymous users. You have to log in to be able to use CryptDrive.";
out.expiredError = 'This pad has reached its expiration time and is no longer available.';
out.expiredErrorCopy = ' You can still copy the content to another location by pressing <em>Esc</em>.<br>Once you leave this page, it will disappear forever!';
out.deletedError = 'This pad has been deleted by its owner and is no longer available.';
out.loading = "Loading...";
out.error = "Error";
out.saved = "Saved";
out.synced = "Everything is saved";
out.deleted = "Pad deleted from your CryptDrive";
out.deletedFromServer = "Pad deleted from the server";
out.realtime_unrecoverableError = "The realtime engine has encountered an unrecoverable error. Click OK to reload.";
@@ -381,7 +384,8 @@ define(function () {
out.fm_removePermanentlyDialog = "Are you sure you want to remove that element from your CryptDrive permanently?";
out.fm_removeSeveralDialog = "Are you sure you want to move these {0} elements to the trash?";
out.fm_removeDialog = "Are you sure you want to move {0} to the trash?";
out.fm_deleteOwnedPads = "Are you sure you want to remove permanently this pad from the server?";
out.fm_deleteOwnedPad = "Are you sure you want to remove permanently this pad from the server?";
out.fm_deleteOwnedPads = "Are you sure you want to remove permanently these pads from the server?";
out.fm_restoreDialog = "Are you sure you want to restore {0} to its previous location?";
out.fm_unknownFolderError = "The selected or last visited directory no longer exist. Opening the parent folder...";
out.fm_contextMenuError = "Unable to open the context menu for that element. If the problem persist, try to reload the page.";
@@ -395,7 +399,8 @@ define(function () {
out.fm_info_trash = out.updated_0_fm_info_trash;
out.fm_info_allFiles = 'Contains all the files from "Documents", "Unsorted" and "Trash". You can\'t move or remove files from here.'; // Same here
out.fm_info_anonymous = 'You are not logged in so your pads will expire after 3 months (<a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">find out more</a>). ' +
'<a href="/register/">Sign up</a> or <a href="/login/">Log in</a> to keep them alive.';
'They are stored in your browser so clearing history may make them disappear.<br>' +
'<a href="/register/">Sign up</a> or <a href="/login/">Log in</a> to keep them alive.<br>';
out.fm_info_owned = "You are the owner of the pads displayed here. This means you can remove them permanently from the server whenever you want. If you do so, other users won't be able to access them anymore.";
out.fm_alert_backupUrl = "Backup link for this drive.<br>" +
"It is <strong>highly recommended</strong> that you keep it secret.<br>" +
@@ -417,6 +422,7 @@ define(function () {
"This will remove your CryptDrive and its history from your browser, but your pads will still exist (encrypted) on our server.";
out.fm_padIsOwned = "You are the owner of this pad";
out.fm_padIsOwnedOther = "This pad is owned by another user";
out.fm_deletedPads = "These pads no longer exist on the server, they've been removed from your CryptDrive: {0}";
// File - Context menu
out.fc_newfolder = "New folder";
out.fc_rename = "Rename";
@@ -472,6 +478,7 @@ define(function () {
out.register_mustAcceptTerms = "You must accept the terms of service.";
out.register_mustRememberPass = "We cannot reset your password if you forget it. It's very important that you remember it! Please check the checkbox to confirm.";
out.register_whyRegister = "Why sign up?";
out.register_header = "Welcome to CryptPad";
out.register_explanation = [
"<h3>Lets go over a couple things first:</h3>",
@@ -495,6 +502,7 @@ define(function () {
out.settings_cat_code = "Code";
out.settings_cat_pad = "Rich text";
out.settings_cat_creation = "New pad";
out.settings_cat_subscription = "Subscription";
out.settings_title = "Settings";
out.settings_save = "Save";
@@ -716,6 +724,7 @@ define(function () {
// features.html
out.features = "Features";
out.features_title = "Features table";
out.features_feature = "Feature";
out.features_anon = "Anonymous user";
@@ -737,6 +746,7 @@ define(function () {
out.features_f_multiple = "Use on multiple devices";
out.features_f_multiple_notes = "Easy way to access your pads from any device";
out.features_f_logoutEverywhere = "Log out from other devices";
out.features_f_logoutEverywhere_notes = ""; // Used in the French translation to explain
out.features_f_templates = "Use templates";
out.features_f_templates_notes = "Create templates and create new pads from your templates";
out.features_f_profile = "Create a profile";
@@ -749,6 +759,30 @@ define(function () {
out.features_f_storage_anon = "Pads deleted after 3 months";
out.features_f_storage_registered = "Free: 50MB<br>Premium: 5GB/20GB/50GB";
// faq.html
out.faq_link = "FAQ";
out.faq_title = "Frequently Asked Questions";
out.faq = {};
out.faq.cat1 = {
title: 'Category 1',
q1: {
q: 'What is a pad?',
a: 'A realtime collaborative document...'
},
q2: {
q: 'Question 2?',
a: '42'
}
};
out.faq.cat2 = {
title: 'Category 2',
q1: {
q: 'A new question?',
a: 'The answer'
}
};
// terms.html
out.tos_title = "CryptPad Terms of Service";
@@ -855,23 +889,24 @@ define(function () {
out.feedback_optout = "If you would like to opt out, visit <a href='/settings/'>your user settings page</a>, where you'll find a checkbox to enable or disable user feedback";
// Creation page
out.creation_404 = "This pad not longer exists. Use the following form to create a new pad";
out.creation_404 = "This pad not longer exists. Use the following form to create a new pad.";
out.creation_ownedTitle = "Type of pad";
out.creation_ownedTrue = "Owned pad";
out.creation_ownedFalse = "Open pad";
out.creation_owned1 = "An <b>owned</b> pad is a pad that you can delete from the server whenever you want. Once it is deleted, no one else can access it, even if it is stored in their CryptDrive.";
out.creation_owned1 = "An <b>owned</b> pad can be deleted from the server whenever the owner wants. Deleting an owned pad removes it from other users' CryptDrives.";
out.creation_owned2 = "An <b>open</b> pad doesn't have any owner and thus, it can't be deleted from the server unless it has reached its expiration time.";
out.creation_expireTitle = "Life time";
out.creation_expireTrue = "Add a life time";
out.creation_expireFalse = "Unlimited";
out.creation_expireHours = "Hours";
out.creation_expireDays = "Days";
out.creation_expireMonths = "Months";
out.creation_expire1 = "By default, a pad stored by a registered user will never be removed from the server, unless it is requested by its owner.";
out.creation_expire2 = "If you prefer, you can set a life time to make sure the pad will be permanently deleted from the server and unavailable after the specified date.";
out.creation_expireHours = "Hour(s)";
out.creation_expireDays = "Day(s)";
out.creation_expireMonths = "Month(s)";
out.creation_expire1 = "An <b>unlimited</b> pad will not be removed from the server until its owner deletes it.";
out.creation_expire2 = "An <b>expiring</b> pad has a set lifetime, after which it will be automatically removed from the server and other users' CryptDrives.";
out.creation_createTitle = "Create a pad";
out.creation_createFromTemplate = "From template";
out.creation_createFromScratch = "From scratch";
out.creation_settings = "New Pad settings";
// Properties about creation data
out.creation_owners = "Owners";
out.creation_ownedByOther = "Owned by another user";
@@ -879,7 +914,7 @@ define(function () {
out.creation_expiration = "Expiration time";
out.creation_propertiesTitle = "Availability";
out.creation_appMenuName = "Advanced mode (Ctrl + E)";
out.creation_newPadModalDescription = "Click on a pad type to create it. You can check the box if you want to display the pad creation screen (for owned pad, expiration pad, etc.).";
out.creation_newPadModalDescription = "Click on a pad type to create it. You can check the box if you want to display the pad creation screen (for owned pads, expiring pads, etc.).";
out.creation_newPadModalAdvanced = "Display the pad creation screen";
// New share modal