Customize directory for alpha meet instance

This commit is contained in:
Ludovic Dubost 2020-04-12 15:51:59 +02:00
parent 17ece71579
commit 925af115bb
6 changed files with 706 additions and 0 deletions

View File

@ -0,0 +1,37 @@
/*
* You can override the configurable values from this file.
* The recommended method is to make a copy of this file (/customize.dist/application_config.js)
in a 'customize' directory (/customize/application_config.js).
* If you want to check all the configurable values, you can open the internal configuration file
but you should not change it directly (/common/application_config_internal.js)
*/
define(['/common/application_config_internal.js'], function (AppConfig) {
// Example: If you want to remove the survey link in the menu:
// AppConfig.surveyURL = "";
/* Select the buttons displayed on the main page to create new collaborative sessions.
* Removing apps from the list will prevent users from accessing them. They will instead be
* redirected to the drive.
* You should never remove the drive from this list.
*/
AppConfig.availablePadTypes = ['drive', 'teams', 'pad', 'sheet', 'code', 'slide', 'poll', 'kanban', 'whiteboard',
'meet', 'oodoc', 'ooslide', 'file', 'todo', 'contacts'];
/* The registered only types are apps restricted to registered users.
* You should never remove apps from this list unless you know what you're doing. The apps
* listed here by default can't work without a user account.
* You can however add apps to this list. The new apps won't be visible for unregistered
* users and these users will be redirected to the login page if they still try to access
* the app
*/
AppConfig.registeredOnlyTypes = ['file', 'contacts', 'oodoc', 'ooslide', 'notifications'];
/* CryptPad is available is multiple languages, but only English and French are maintained
* by the developers. The other languages may be outdated, and any missing string for a langauge
* will use the english version instead. You can customize the langauges you want to be available
* on your instance by removing them from the following list.
* An empty list will load all available languages for CryptPad. The list of available languages
* can be found at the top of the file `/customize.dist/messages.js`. The list should only
* contain languages code ('en', 'fr', 'de', 'pt-br', etc.), not their full name.
*/
AppConfig.availableLanguages = ['en'];
return AppConfig;
});

16
customize/index.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html class="cp">
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
<head>
<title data-localization="main_title">CryptPad Meet Alpha: Experimental Zero Knowledge Conferencing</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"/>
<script async data-bootload="/customize/template.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
</head>
<body class="html">
<noscript>
<p><strong>OOPS</strong> In order to do encryption in your browser, Javascript is really <strong>really</strong> required.</p>
<p><strong>OUPS</strong> Afin de pouvoir réaliser le chiffrement dans votre navigateur, Javascript est <strong>vraiment</strong> nécessaire.</p>
</noscript>
</html>

197
customize/messages.js Executable file
View File

@ -0,0 +1,197 @@
(function () {
// add your module to this map so it gets used
var map = {
'ca': 'Català',
'de': 'Deutsch',
'el': 'Ελληνικά',
'es': 'Español',
'fi': 'Suomalainen',
'fr': 'Français',
//'hi': 'हिन्दी',
'it': 'Italiano',
'nb': 'Norwegian Bokmål',
//'pl': 'Polski',
'pt-br': 'Português do Brasil',
'ro': 'Română',
'ru': 'Русский',
//'sv': 'Svenska',
//'te': 'తెలుగు',
'zh': '繁體中文',
//'nl': 'Nederlands'
};
var messages = {};
var LS_LANG = "CRYPTPAD_LANG";
var getStoredLanguage = function () { return localStorage && localStorage.getItem(LS_LANG); };
var getBrowserLanguage = function () { return navigator.language || navigator.userLanguage || ''; };
var getLanguage = messages._getLanguage = function () {
if (window.cryptpadLanguage) { return window.cryptpadLanguage; }
if (getStoredLanguage()) { return getStoredLanguage(); }
var l = getBrowserLanguage();
// Edge returns 'fr-FR' --> transform it to 'fr' and check again
return map[l] ? l :
(map[l.split('-')[0]] ? l.split('-')[0] :
(map[l.split('_')[0]] ? l.split('_')[0] : 'en'));
};
var language = getLanguage();
// Translations files were migrated from requirejs modules to json.
// To avoid asking every administrator to update their customized translation files,
// we use a requirejs map to redirect the old path to the new one and to use the
// requirejs json plugin
var reqPaths = {
"/common/translations/messages.js":"json!/common/translations/messages.json"
};
Object.keys(map).forEach(function (k) {
reqPaths["/common/translations/messages."+k+".js"] = "json!/common/translations/messages."+k+".json";
});
require.config({
map: {
"*": reqPaths
}
});
var req = [
'/common/common-util.js',
'/customize/application_config.js',
'/customize/translations/messages.js'
];
if (language && map[language]) { req.push('/customize/translations/messages.' + language + '.js'); }
define(req, function(Util, AppConfig, Default, Language) {
map.en = 'English';
var defaultLanguage = 'en';
if (AppConfig.availableLanguages) {
if (AppConfig.availableLanguages.indexOf(language) === -1) {
language = defaultLanguage;
Language = Default;
localStorage.setItem(LS_LANG, language);
}
Object.keys(map).forEach(function (l) {
if (l === defaultLanguage) { return; }
if (AppConfig.availableLanguages.indexOf(l) === -1) {
delete map[l];
}
});
}
var extend = function (a, b) {
for (var k in b) {
if (Util.isObject(b[k])) {
a[k] = Util.isObject(a[k]) ? a[k] : {};
extend(a[k], b[k]);
continue;
}
if (Array.isArray(b[k])) {
a[k] = b[k].slice();
continue;
}
a[k] = b[k] || a[k];
}
};
extend(messages, Default);
if (Language && language !== defaultLanguage) {
// Add the translated keys to the returned object
extend(messages, Language);
}
messages._languages = map;
messages._languageUsed = language;
messages._checkTranslationState = function (cb) {
if (typeof(cb) !== "function") { return; }
var allMissing = [];
var reqs = [];
Object.keys(map).forEach(function (code) {
if (code === defaultLanguage) { return; }
reqs.push('/customize/translations/messages.' + code + '.js');
});
require(reqs, function () {
var langs = arguments;
Object.keys(map).forEach(function (code, i) {
if (code === defaultLanguage) { return; }
var translation = langs[i];
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;
}
});
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]);
}
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(allMissing);
});
};
// Get keys with parameters
messages._getKey = function (key, argArray) {
if (!messages[key]) { return '?'; }
var text = messages[key];
if (typeof(text) === 'string') {
return text.replace(/\{(\d+)\}/g, function (str, p1) {
if (typeof(argArray[p1]) === 'string' || typeof(argArray[p1]) === "number") {
return argArray[p1];
}
console.error("Only strings and numbers can be used in _getKey params!");
return '';
});
} else {
return text;
}
};
messages.driveReadme = '["BODY",{"class":"cke_editable cke_editable_themed cke_contents_ltr cke_show_borders","contenteditable":"true","spellcheck":"false","style":"color: rgb(51, 51, 51);"},' +
'[["H1",{},["'+messages.readme_welcome+'"]],["P",{},["'+messages.readme_p1+'"]],["P",{},["'+messages.readme_p2+'"]],["HR",{},[]],["H2",{},["'+messages.readme_cat1+'",["BR",{},[]]]],["UL",{},[["LI",{},["'+messages._getKey("readme_cat1_l1", ['",["STRONG",{},["'+messages.newButton+'"]],"', '",["STRONG",{},["'+messages.type.pad+'"]],"'])+'"]],["LI",{},["'+messages.readme_cat1_l2+'"]],["LI",{},["'+messages._getKey("readme_cat1_l3", ['",["STRONG",{},["'+messages.fm_unsortedName+'"]],"'])+'",["UL",{},[["LI",{},["'+messages._getKey("readme_cat1_l3_l1", ['",["STRONG",{},["'+messages.fm_rootName+'"]],"'])+'"]],["LI",{},["'+messages.readme_cat1_l3_l2+'"]]]]]],["LI",{},["'+messages._getKey("readme_cat1_l4", ['",["STRONG",{},["'+messages.fm_trashName+'"]],"'])+'",["BR",{},[]]]]]],["P",{},[["BR",{},[]]]],["H2",{},["'+messages.readme_cat2+'",["BR",{},[]]]],["UL",{},[["LI",{},["'+messages._getKey("readme_cat2_l1", ['",["STRONG",{},["'+messages.shareButton+'"]],"', '",["STRONG",{},["'+messages.edit+'"]],"', '",["STRONG",{},["'+messages.view+'"]],"'])+'"]],["LI",{},["'+messages.readme_cat2_l2+'"]]]],["P",{},[["BR",{},[]]]],["H2",{},["'+messages.readme_cat3+'"]],["UL",{},[["LI",{},["'+messages.readme_cat3_l1+'"]],["LI",{},["'+messages.readme_cat3_l2+'"]],["LI",{},["'+messages.readme_cat3_l3+'",["BR",{},[]]]]]]],' +
'{"metadata":{"defaultTitle":"' + messages.driveReadmeTitle + '","title":"' + messages.driveReadmeTitle + '"}}]';
return messages;
});
}());

172
customize/pages/index.js Normal file
View File

@ -0,0 +1,172 @@
define([
'jquery',
'/api/config',
'/common/hyperscript.js',
'/common/common-feedback.js',
'/common/common-interface.js',
'/common/textFit.min.js',
'/customize/messages.js',
'/customize/application_config.js',
'/common/outer/local-store.js',
'/customize/pages.js'
], function ($, Config, h, Feedback, UI, TextFit, Msg, AppConfig, LocalStore, Pages) {
var urlArgs = Config.requireConf.urlArgs;
var isAvailableType = function (x) {
if (!Array.isArray(AppConfig.availablePadTypes)) { return true; }
return AppConfig.availablePadTypes.indexOf(x) !== -1;
};
var checkRegisteredType = function (x) {
// Return true if we're registered or if the app is not registeredOnly
if (LocalStore.isLoggedIn()) { return true; }
if (!Array.isArray(AppConfig.registeredOnlyTypes)) { return true; }
return AppConfig.registeredOnlyTypes.indexOf(x) === -1;
};
return function () {
var icons = [
[ 'meet', Msg.type.meet],
].filter(function (x) {
return isAvailableType(x[0]);
})
.map(function (x) {
var s = 'div.bs-callout.cp-callout-' + x[0];
var isEnabled = checkRegisteredType(x[0]);
//if (i > 2) { s += '.cp-more.cp-hidden'; }
var icon = AppConfig.applicationsIcon[x[0]];
var font = icon.indexOf('cptools') === 0 ? 'cptools' : 'fa';
var href = '/'+ x[0] +'/';
var attr = isEnabled ? { href: href } : {
onclick: function () {
sessionStorage.redirectTo = href;
window.location.href = '/login/';
}
};
if (!isEnabled) {
s += '.cp-app-disabled';
attr.title = Msg.mustLogin;
}
return h('a', [
attr,
h(s, [
h('i.' + font + '.' + icon),
h('div.pad-button-text', {
style: 'width:120px;height:30px;'
}, [ x[1] ])
])
]);
});
icons.forEach(function (a) {
setTimeout(function () {
TextFit($(a).find('.pad-button-text')[0], {minFontSize: 13, maxFontSize: 18});
});
});
UI.addTooltips();
/*
var more = icons.length < 4? undefined: h('div.bs-callout.cp-callout-more', [
h('div.cp-callout-more-lessmsg.cp-hidden', [
"see less ",
h('i.fa.fa-caret-up')
]),
h('div.cp-callout-more-moremsg', [
"see more ",
h('i.fa.fa-caret-down')
]),
{
onclick: function () {
if (showingMore) {
$('.cp-more, .cp-callout-more-lessmsg').addClass('cp-hidden');
$('.cp-callout-more-moremsg').removeClass('cp-hidden');
} else {
$('.cp-more, .cp-callout-more-lessmsg').removeClass('cp-hidden');
$('.cp-callout-more-moremsg').addClass('cp-hidden');
}
showingMore = !showingMore;
}
}
]);*/
var _link = h('a', {
href: "https://opencollective.com/cryptpad/",
target: '_blank',
rel: 'noopener',
});
var crowdFunding = h('button', [
Msg.crowdfunding_button
]);
$(crowdFunding).click(function () {
_link.click();
Feedback.send('HOME_SUPPORT_CRYPTPAD');
});
var blocks = h('div.container',[
h('div.row.justify-content-sm-center',[
h('div.col-12.col-sm-4.cp-index-block.cp-index-block-host', h('div', [
Pages.setHTML(h('span'), Msg.home_host),
h('div.cp-img-container', [
h('img.agpl', {
src: "/customize/images/AGPL.png",
title: Msg.home_host_agpl
}),
h('a.img', {
href: 'https://blog.cryptpad.fr/2018/11/13/CryptPad-receives-NGI-Startup-Award/',
target: '_blank'
}, h('img.ngi', {
src: "/customize/images/ngi.png",
title: Msg.home_ngi
}))
])
])),
h('div.col-12.col-sm-4.cp-index-block.cp-index-block-product', h('div', [
Msg.home_product
])),
AppConfig.disableCrowdfundingMessages ? undefined : h('div.col-12.col-sm-4.cp-index-block.cp-index-block-help', h('div', [
Msg.crowdfunding_home1,
h('br'),
Msg.crowdfunding_home2,
h('br'),
crowdFunding,
_link
])),
])
]);
return [
h('div#cp-main', [
Pages.infopageTopbar(),
h('div.container.cp-container', [
h('div.row', [
h('div.col-12.col-sm-12',[
h('h2', Msg.meet_home),
h('h4', Msg.meet_warning),
h('br'),
h('br'),
]),
h('div.cp-title.col-12.col-sm-6', [
h('img', { src: '/customize/cryptpad-new-logo-colors-logoonly.png?' + urlArgs }),
h('h1', 'CryptPad'),
h('p', Msg.main_catch_phrase)
]),
h('div.col-12.col-sm-6.cp-app-grid', [
icons,
//more
]),
]),
blocks,
/*h('div.row', [
h('div.cp-crowdfunding', [
crowdFunding
])
])*/
]),
]),
Pages.infopageFooter(),
];
};
});

View File

@ -0,0 +1,265 @@
@import (reference) "../include/infopages.less";
@import (reference) "../include/colortheme-all.less";
&.cp-page-index {
.infopages_main();
@background_lighter: rgba(0,0,0,0.1);
@background_darker: rgba(0,0,0,0.4);
#cp-main {
color: #FFF;
background: linear-gradient( @background_darker, @background_lighter ), url('/customize/bg14.jpg');
background-size: cover;
background-position: center;
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
.container {
@media only screen and (max-device-width : 576px) {
margin-top: 6em;
}
}
& > .cp-container {
flex: 1;
display: flex;
flex-flow: column;
justify-content: space-around;
justify-content: space-evenly;
}
}
body {
font-family: "Open Sans", Helvetica;
}
.cp-right {
.cp-register-btn {
padding: 0.5em 1em 0.7em 1em;
border: 2px solid #fff;
&:hover {
transform: scale(1.05);
}
}
.cp-login-btn {
color: #fff;
padding: 0.5em 1em 0.7em 1em;
&:hover {
transform: scale(1.05);
}
}
}
.cp-title {
display: flex;
align-items: center;
flex-direction: column;
margin-top: 1.5em;
img {
height: 20vh;
margin-bottom: 1.5em;
}
margin-left: 0;
margin-bottom: 20px;
h1 {
font-family: "Neuropolitical";
//font-family: Garamond, Baskerville, "Baskerville Old Face", "Hoefler Text", "Times New Roman", Times, serif;
//font-family: "Raleway";
font-size: 45px;
}
p {
//font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-size: 20px;
//font-style: italic;
}
}
.navbar {
background: transparent;
width: 100%;
@media only screen and (max-device-width: 991px) {
margin-top: 0;
}
.navbar-brand {
background-image: url(/customize/CryptPad-white-logo.svg);
}
a {
color: #fff;
&:visited {
color: rgba(255,255,255,.9);
};
}
.nav-link {
&:hover {
color: inherit;
transform: scale(1.05);
};
}
.cp-register-btn {
border: 2px solid #fff;
}
.navbar-toggler {
margin-top: 10px;
color: #fff;
}
}
@callout-padding: 15px;
a:hover {
text-decoration: none;
}
.cp-app-grid {
display: flex;
flex-wrap: wrap;
& > a {
margin: 20px;
}
align-items: center;
}
@icons-size: 120px;
@icons-text-size: 30px;
.bs-callout {
display: flex;
align-items: stretch;
margin: 0;
background: rgba(255,255,255,0.6);
color: black;
transition: all .1s ease-in-out;
box-sizing: border-box;
position: relative;
flex-flow: column;
height: @icons-size;
width: @icons-size;
a {
color: black;
&:hover { text-decoration-line: none; }
}
div h4 {
@media only screen and (min-device-width: 576px) and (max-device-width: 767px) {
font-size: 1.3em;
}
}
div {
flex: 1;
min-height: 0;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 16px;
}
.fa, .cptools {
display: flex;
align-items: center;
font-size: @icons-size - 60px;
justify-content: center;
width: @icons-size;
height: @icons-size - @icons-text-size;
transition: width 0.1s;
color: #fff;
}
&.cp-app-disabled {
cursor: not-allowed !important;
opacity: 0.5;
}
}
h4 {
margin: 0;
}
.cp-callout-more-moremsg,.cp-callout-more-lessmsg {
transform: none !important;
}
.bs-callout+.bs-callout {
margin-top: -5px;
}
.bs-callout:hover {
//color: white;
transform: scale(1.05);
cursor: pointer;
}
.bs-callout:hover.cp-callout-more {
transform: none !important;
}
.cp-callout-pad .cptools { background-color: @colortheme_pad-bg; }
.cp-callout-code .cptools { background-color: @colortheme_code-bg; }
.cp-callout-slide .cptools { background-color: @colortheme_slide-bg; }
.cp-callout-poll .cptools { background-color: @colortheme_poll-bg; }
.cp-callout-kanban .cptools { background-color: @colortheme_kanban-bg; }
.cp-callout-whiteboard .cptools { background-color: @colortheme_whiteboard-bg; }
.cp-callout-drive .fa { background-color: @colortheme_drive-bg; }
.cp-callout-sheet .fa { background-color: @colortheme_oocell-bg; }
.cp-hidden { display: none !important; }
.cp-callout-more {
display: inline-block;
align-content: center;
height: 2em;
border-radius: 1em;
margin-left: auto;
margin-right: auto;
margin-top: 0;
background: none;
width: 100%;
div {
.infopages_link();
color: #fff;
.fa, .cptools {
font-size: inherit;
padding: 0;
width: 1em;
padding-left: 5px;
}
}
}
.cp-index-block-help {
button {
outline: none;
background-color: @colortheme_logo-2;
color: @colortheme_base;
border: none;
padding: 10px 20px;
border-radius: 44px;
cursor: pointer;
&:hover {
background-color: lighten(@colortheme_logo-2, 3%);
}
}
}
.cp-index-block {
min-height: 100%;
& > div {
background: rgba(0,0,0,0.5);
margin: 0 5px;
padding: 15px 10px;
height: 100%;
display: flex;
flex-flow: column;
justify-content: space-evenly;
}
.cp-img-container {
display: flex;
}
img, a.img {
margin: auto;
background: white;
&.agpl {
max-height: 50px;
}
&.ngi {
max-height: 100px;
}
}
}
@media (min-width: 576px) and (max-width: 767px) {
.container {
padding-left: 0;
padding-right: 0;
}
div#cp-main.cp-page-index .cp-topbar .navbar-toggler-left {
left: 5px;
}
}
}

View File

@ -0,0 +1,19 @@
/*
* You can override the translation text using this file.
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
* If you want to check all the existing translation keys, you can open the internal language file
but you should not change it directly (/common/translations/messages.{LANG}.js)
*/
define(['/common/translations/messages.js'], function (Messages) {
// Replace the existing keys in your copied file here:
// Messages.button_newpad = "New Rich Text Document";
Messages.home_host = "This instance is an alpha instance of CryptPad Meet, a version of CryptPad featuring a Zero Knowledge audio and video conferencing pad.";
Messages.meet_home = "This service features an experimental end-to-end encrypted video and audio conferencing service";
Messages.meet_warning = "WARNING ! While the plan is to have the same security features as for pads, the experimental conferencing service is not yet secure. The current transport is end-to-end encrypted but uses the same key for all conferences. All accounts and data on this server can be deleted at any time";
Messages.main_catch_phrase = "CryptPad Meet - Alpha";
Messages.meet = "Meet";
Messages.button_newmeet = "New Meeting";
return Messages;
});