mirror of
https://github.com/cryptpad/cryptpad.git
synced 2026-09-14 11:05:41 +05:00
Server app prototype to display listed servers from accounts.cryptpad.fr
This commit is contained in:
parent
825820f6bf
commit
ba0a39f00c
@ -50,7 +50,8 @@
|
||||
"jszip": "Stuk/jszip#^3.1.5",
|
||||
"requirejs-plugins": "^1.0.3",
|
||||
"dragula.js": "3.7.2",
|
||||
"MathJax": "3.0.5"
|
||||
"MathJax": "3.0.5",
|
||||
"datatables": "^1.10.21"
|
||||
},
|
||||
"resolutions": {
|
||||
"bootstrap": "^v4.0.0",
|
||||
|
||||
306
www/servers/app/app-servers.less
Normal file
306
www/servers/app/app-servers.less
Normal file
@ -0,0 +1,306 @@
|
||||
@import (reference) '../../customize/src/less2/include/framework.less';
|
||||
@import (reference) '../../customize/src/less2/include/sidebar-layout.less';
|
||||
@import (reference) '../../customize/src/less2/include/avatar.less';
|
||||
@import (reference) "../../customize/src/less2/include/limit-bar.less";
|
||||
|
||||
&.cp-app-accounts {
|
||||
.limit-bar_main();
|
||||
|
||||
.framework_min_main(
|
||||
@bg-color: @colortheme_admin-bg,
|
||||
@warn-color: @colortheme_admin-warn,
|
||||
@color: @colortheme_admin-color
|
||||
);
|
||||
.sidebar-layout_main();
|
||||
|
||||
.cp-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
@plan_basic: #DDEFFF;
|
||||
@plan_pro: #E4FFDD;
|
||||
@plan_power: #F6DDFF;
|
||||
@alert-neutral: #EFEFEF;
|
||||
@active-color: #AFFDC2;
|
||||
@inactive-color: #FFD4D4;
|
||||
|
||||
|
||||
#cp-sidebarlayout-rightside {
|
||||
color: @cryptpad_text_col !important;
|
||||
.alert {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
.cp-accounts-subscribe-anon, .cp-accounts-subscribe-form, .cp-accounts-subscribe-admin {
|
||||
max-width: 940px;
|
||||
margin: 10px auto 20px !important;
|
||||
}
|
||||
|
||||
.cp-accounts-donate {
|
||||
max-width: 650px;
|
||||
}
|
||||
|
||||
.cp-limit-container {
|
||||
.cp-limit-buttons {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.cp-accounts-mysubs-addplan {
|
||||
max-width: 830px;
|
||||
#gift label {
|
||||
margin-bottom: 0;
|
||||
margin-top: 10px;
|
||||
font-weight: unset;
|
||||
}
|
||||
}
|
||||
.cp-accounts-subscribe-form {
|
||||
ul {
|
||||
list-style-position: outside;
|
||||
padding-left: 10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.subscription-info {
|
||||
font-size: 14px;
|
||||
}
|
||||
.subscription-terms {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.active-plan {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.choose-plan {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@media (max-width: @browser_media-medium-screen) {
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.plan {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
width: 300px;
|
||||
min-height: 350px;
|
||||
&:not(:last-child) {
|
||||
margin-right: 20px;
|
||||
@media (max-width: @browser_media-medium-screen) {
|
||||
margin-right: 0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
.plan-header-text {
|
||||
text-transform: capitalize;
|
||||
font-size: 30px;
|
||||
}
|
||||
.plan-price-area {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
.plan-price-text {
|
||||
font-size: 60px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
ul.plan-details {
|
||||
flex: 1;
|
||||
padding-right: 10px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
.buttons {
|
||||
margin: 10px;
|
||||
button {
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.alert {
|
||||
margin: 0 10px;
|
||||
background: white;
|
||||
border: none;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
.plan-basic {
|
||||
background-color: @plan_basic;
|
||||
}
|
||||
.plan-pro {
|
||||
background-color: @plan_pro;
|
||||
}
|
||||
.plan-power {
|
||||
background-color: @plan_power;
|
||||
}
|
||||
.link-to-stripe {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 10px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
.info-bottom {
|
||||
font-size: 14px;
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cp-accounts-mysubs-data {
|
||||
.active-subs {
|
||||
.subscription {
|
||||
min-height: 300px;
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
background: white;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
color: inherit;
|
||||
border: none;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
button {
|
||||
flex-shrink: 0;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.users {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
& > span {
|
||||
width: 180px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.subscription-container {
|
||||
.subscription {
|
||||
min-height: 175px;
|
||||
width: 300px;
|
||||
&:not(.details) {
|
||||
.creation, .notes, .expired, .cancel, .close-d, .storage {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
&.details {
|
||||
.open-d {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.subscription-container, .active-subs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
|
||||
.subscription {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
margin-right: 20px;
|
||||
padding: 10px;
|
||||
background-color: #eee;
|
||||
position: relative;
|
||||
|
||||
& > span {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
button.open-details {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.open-d, .close-d {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.billing, .shared, .expired {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
button {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
.billing {
|
||||
.text {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
}
|
||||
|
||||
.plan {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.active, .inactive {
|
||||
position: absolute;
|
||||
padding: 0 5px;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
}
|
||||
.inactive {
|
||||
background-color: @inactive-color;
|
||||
}
|
||||
.active {
|
||||
background-color: @active-color;
|
||||
}
|
||||
|
||||
.benificiary-data {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: white;
|
||||
padding: 5px;
|
||||
.cp-avatar {
|
||||
margin-right: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.notes {
|
||||
flex: 1;
|
||||
max-height: 60px;
|
||||
}
|
||||
|
||||
.avatar_main(30px);
|
||||
}
|
||||
}
|
||||
}
|
||||
.cp-accounts-mysubs-addplan {
|
||||
.avatar_main(30px);
|
||||
}
|
||||
|
||||
.cp-accounts-subscribe-admin {
|
||||
div.admin {
|
||||
margin-bottom: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
.cp-accounts-admin {
|
||||
input[type="text"] {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
34
www/servers/app/inner.html
Normal file
34
www/servers/app/inner.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="cp-app-noscroll">
|
||||
<head>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<script async data-bootload="/servers/app/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
|
||||
<style>
|
||||
.loading-hidden { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="cp-toolbar" class="cp-toolbar-container"></div>
|
||||
<div id="cp-sidebarlayout-container" style="display: none;">
|
||||
<div id="cp-sidebarlayout-rightside">
|
||||
<h1 id="cp-servers-title">CryptPad Server List</h1>
|
||||
<p id="cp-servers-desc">
|
||||
Lorem ipso sum. Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.Lorem ipso sum.
|
||||
</p>
|
||||
<table id="servers" class="display" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>URL</th>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Version</th>
|
||||
<th>Registered Users</th>
|
||||
<th>Max connections</th>
|
||||
<th>First Connection</th>
|
||||
<th>Last Connection</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
56
www/servers/app/inner.js
Normal file
56
www/servers/app/inner.js
Normal file
@ -0,0 +1,56 @@
|
||||
// Load #1, load as little as possible because we are in a race to get the loading screen up.
|
||||
define([
|
||||
'jquery',
|
||||
'/bower_components/nthen/index.js',
|
||||
'/customize/application_config.js',
|
||||
'/common/dom-ready.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/sframe-common.js',
|
||||
'/common/toolbar.js',
|
||||
'/bower_components/datatables/media/js/jquery.dataTables.min.js',
|
||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||
'css!/bower_components/datatables/media/css/dataTables.bootstrap4.min.css',
|
||||
'css!/bower_components/datatables/media/css/jquery.dataTables.min.css',
|
||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||
'css!/servers/app/servers.css',
|
||||
'less!/servers/app/app-servers.less',
|
||||
], function ($, nThen, ApiConfig, DomReady, UI, SFCommon, Toolbar, DataTable) {
|
||||
var APP = {}
|
||||
|
||||
// Loaded in load #2
|
||||
nThen(function (waitFor) {
|
||||
DomReady.onReady(waitFor());
|
||||
}).nThen(function (waitFor) {
|
||||
$(waitFor(UI.addLoadingScreen));
|
||||
SFCommon.create(waitFor(function (c) { APP.common = common = c; }));
|
||||
}).nThen(function (/*waitFor*/) {
|
||||
APP.$container = $('#cp-sidebarlayout-container');
|
||||
APP.$toolbar = $('#cp-toolbar');
|
||||
var displayed = ['pageTitle'];
|
||||
var configTb = {
|
||||
displayed: displayed,
|
||||
$container: APP.$toolbar,
|
||||
sfCommon: common,
|
||||
pageTitle: "CryptPad Servers",
|
||||
metadataMgr: common.getMetadataMgr(),
|
||||
};
|
||||
APP.toolbar = Toolbar.create(configTb);
|
||||
APP.toolbar.$rightside.hide();
|
||||
APP.$container.show();
|
||||
UI.removeLoadingScreen();
|
||||
|
||||
$('#servers').DataTable( {
|
||||
"ajax": ApiConfig.accounts_api + "/api/servers",
|
||||
"columns" : [
|
||||
{ "data" : "url" },
|
||||
{ "data" : "name" },
|
||||
{ "data" : "desc" },
|
||||
{ "data" : "version" },
|
||||
{ "data" : "registeredUsers" },
|
||||
{ "data" : "maxOpenUniqueWebSockets" },
|
||||
{ "data" : "firstConnection" },
|
||||
{ "data" : "lastConnection" }
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
65
www/servers/app/main.js
Normal file
65
www/servers/app/main.js
Normal file
@ -0,0 +1,65 @@
|
||||
// Load #1, load as little as possible because we are in a race to get the loading screen up.
|
||||
define([
|
||||
'/bower_components/nthen/index.js',
|
||||
'/api/config',
|
||||
'/common/dom-ready.js',
|
||||
'/common/requireconfig.js',
|
||||
'/common/sframe-common-outer.js',
|
||||
], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) {
|
||||
var requireConfig = RequireConfig();
|
||||
|
||||
// Loaded in load #2
|
||||
nThen(function (waitFor) {
|
||||
DomReady.onReady(waitFor());
|
||||
}).nThen(function (waitFor) {
|
||||
var req = {
|
||||
cfg: requireConfig,
|
||||
req: [ '/common/loading.js' ],
|
||||
pfx: window.location.origin
|
||||
};
|
||||
window.rc = requireConfig;
|
||||
window.apiconf = ApiConfig;
|
||||
document.getElementById('sbox-iframe').setAttribute('src',
|
||||
ApiConfig.httpSafeOrigin + '/servers/app/inner.html?' + requireConfig.urlArgs +
|
||||
'#' + encodeURIComponent(JSON.stringify(req)));
|
||||
|
||||
// This is a cheap trick to avoid loading sframe-channel in parallel with the
|
||||
// loading screen setup.
|
||||
var done = waitFor();
|
||||
var onMsg = function (msg) {
|
||||
var data = JSON.parse(msg.data);
|
||||
if (data.q !== 'READY') { return; }
|
||||
window.removeEventListener('message', onMsg);
|
||||
var _done = done;
|
||||
done = function () { };
|
||||
_done();
|
||||
};
|
||||
window.addEventListener('message', onMsg);
|
||||
}).nThen(function (/*waitFor*/) {
|
||||
var addRpc = function (sframeChan, Cryptpad/*, Utils*/) {
|
||||
sframeChan.on('ACCOUNTS_GET_KEYS', function (data, cb) {
|
||||
Cryptpad.getUserObject(null, function (obj) {
|
||||
cb(obj);
|
||||
});
|
||||
});
|
||||
sframeChan.on('Q_UPDATE_LIMIT', function (data, cb) {
|
||||
Cryptpad.updatePinLimit(function (e) {
|
||||
cb({error: e});
|
||||
});
|
||||
});
|
||||
};
|
||||
var category;
|
||||
if (window.location.hash) {
|
||||
category = window.location.hash.slice(1);
|
||||
window.location.hash = '';
|
||||
}
|
||||
var addData = function (obj) {
|
||||
if (category) { obj.category = category; }
|
||||
};
|
||||
SFCommonO.start({
|
||||
noRealtime: true,
|
||||
addRpc: addRpc,
|
||||
addData: addData
|
||||
});
|
||||
});
|
||||
});
|
||||
192
www/servers/app/messages.js
Normal file
192
www/servers/app/messages.js
Normal file
@ -0,0 +1,192 @@
|
||||
(function () {
|
||||
var LS_LANG = "CRYPTPAD_LANG";
|
||||
|
||||
// add your module to this map so it gets used
|
||||
var map = {
|
||||
'de': 'Deutsch',
|
||||
'es': 'Español',
|
||||
'fr': 'Français',
|
||||
//'it': 'Italiano',
|
||||
};
|
||||
|
||||
var getStoredLanguage = function () { return localStorage.getItem(LS_LANG); };
|
||||
var getBrowserLanguage = function () { return navigator.language || navigator.userLanguage; };
|
||||
var getLanguage = function () {
|
||||
if (window.cryptpadLanguage) { return window.cryptpadLanguage; }
|
||||
if (getStoredLanguage()) { return getStoredLanguage(); }
|
||||
var l = getBrowserLanguage() || '';
|
||||
if (Object.keys(map).indexOf(l) !== -1) {
|
||||
return l;
|
||||
}
|
||||
// Edge returns 'fr-FR' --> transform it to 'fr' and check again
|
||||
return Object.keys(map).indexOf(l.split('-')[0]) !== -1 ? l.split('-')[0] : 'en';
|
||||
};
|
||||
var language = getLanguage();
|
||||
|
||||
var req = ['jquery', 'json!/accounts/resources/translations/messages.json'];
|
||||
if (language && map[language]) { req.push('json!/accounts/resources/translations/messages.' + language + '.json'); }
|
||||
|
||||
define(req, function($, Default, Language) {
|
||||
|
||||
var externalMap = JSON.parse(JSON.stringify(map));
|
||||
|
||||
map.en = 'English';
|
||||
var defaultLanguage = 'en';
|
||||
|
||||
var messages;
|
||||
|
||||
if (!Language || !language || language === defaultLanguage || language === 'default' || !map[language]) {
|
||||
messages = Default;
|
||||
}
|
||||
else {
|
||||
// Add the translated keys to the returned object
|
||||
messages = $.extend(true, {}, Default, Language);
|
||||
}
|
||||
|
||||
messages._languages = map;
|
||||
|
||||
// TODO
|
||||
messages._checkTranslationState = function (cb) {
|
||||
if (typeof(cb) !== "function") { return; }
|
||||
var allMissing = [];
|
||||
var reqs = [];
|
||||
Object.keys(externalMap).forEach(function (code) {
|
||||
reqs.push('/resources/translations/messages.' + code + '.js');
|
||||
});
|
||||
require(reqs, function () {
|
||||
var langs = arguments;
|
||||
Object.keys(externalMap).forEach(function (code, i) {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
// Add handler to the language selector
|
||||
var storeLanguage = function (l) {
|
||||
localStorage.setItem(LS_LANG, l);
|
||||
};
|
||||
messages._initSelector = function ($select) {
|
||||
var selector = $select || $('#language-selector');
|
||||
|
||||
if (!selector.length) { return; }
|
||||
|
||||
var $button = $(selector).find('button .buttonTitle');
|
||||
// Select the current language in the list
|
||||
var option = $(selector).find('[data-value="' + language + '"]');
|
||||
selector.setValue(language || 'English');
|
||||
|
||||
// Listen for language change
|
||||
$(selector).find('a.languageValue').on('click', function () {
|
||||
var newLanguage = $(this).attr('data-value');
|
||||
storeLanguage(newLanguage);
|
||||
if (newLanguage !== language) {
|
||||
setTimeout(function () { window.location.reload(); });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var translateText = function (i, e) {
|
||||
var $el = $(e);
|
||||
var key = $el.data('localization');
|
||||
$el.html(messages[key]);
|
||||
};
|
||||
var translateAppend = function (i, e) {
|
||||
var $el = $(e);
|
||||
var key = $el.data('localization-append');
|
||||
$el.append(messages[key]);
|
||||
};
|
||||
var translateTitle = function (i, e) {
|
||||
var $el = $(this);
|
||||
var key = $el.data('localization-title');
|
||||
$el.attr('title', messages[key]);
|
||||
};
|
||||
var translatePlaceholder = function (i, e) {
|
||||
var $el = $(this);
|
||||
var key = $el.data('localization-placeholder');
|
||||
$el.attr('placeholder', messages[key]);
|
||||
};
|
||||
messages._applyTranslation = function () {
|
||||
$('[data-localization]').each(translateText);
|
||||
$('[data-localization-append]').each(translateAppend);
|
||||
$('#pad-iframe').contents().find('[data-localization]').each(translateText);
|
||||
$('[data-localization-title]').each(translateTitle);
|
||||
$('[data-localization-placeholder]').each(translatePlaceholder);
|
||||
$('#pad-iframe').contents().find('[data-localization-title]').each(translateTitle);
|
||||
};
|
||||
|
||||
messages._getLanguage = function () { return language; };
|
||||
|
||||
return messages;
|
||||
|
||||
});
|
||||
}());
|
||||
360
www/servers/app/servers.css
Normal file
360
www/servers/app/servers.css
Normal file
@ -0,0 +1,360 @@
|
||||
.hide {
|
||||
display:none;
|
||||
}
|
||||
|
||||
div.disabled {
|
||||
opacity: 0.4;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
div.plan, div.renewal {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
div.plan-selected, div.renewal-selected {
|
||||
border: 1px solid #dde;
|
||||
background: #eef;
|
||||
}
|
||||
#info {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.choose-plan .plan img {
|
||||
width: 100%;
|
||||
}
|
||||
.spinner-div {
|
||||
margin: 20px auto;
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
.loading-message {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
/* login form */
|
||||
|
||||
.login-form {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.login-form-entry {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
.support-disabled {
|
||||
opacity: 0.4;
|
||||
background: #eee;
|
||||
}
|
||||
.support-pro-noauth {
|
||||
width: 90%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
|
||||
.plan-details, .support-details, .donate-details {
|
||||
margin-top: 20px;
|
||||
text-align:left;
|
||||
font-family: lato, Helvetica, sans-serif;
|
||||
font-size: 1.02em;
|
||||
}
|
||||
|
||||
/*End of Plan Style*/
|
||||
|
||||
.choose-renewal {
|
||||
margin: 10px 10%;
|
||||
padding: 20px;
|
||||
flex-flow: column;
|
||||
display: flex;
|
||||
background: #efe;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.renewal-options {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
.cp h3.renewal-description {
|
||||
padding-top: 0;
|
||||
}
|
||||
.renewal-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
.renewal-label input {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
.cp button.btn-plan-basic, button.btn-donate5, button.btn-gift {
|
||||
background-color: #00ADEE;
|
||||
border-color: #00ADEE;
|
||||
}
|
||||
.cp button.btn-plan-pro {
|
||||
background-color: #78b336;
|
||||
border-color: #78b336;
|
||||
}
|
||||
.cp button.btn-plan-power, .cp button.btn-donate10 {
|
||||
background-color: #F87217;
|
||||
border-color: #F87217;
|
||||
}
|
||||
.cp button.paybutton:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table.subscription-table {
|
||||
width: 100%;
|
||||
}
|
||||
table.subscription-table .cell-benificiary {
|
||||
max-width: 200px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
table.subscription-table tr.personnal-subscription {
|
||||
background-color: #eef;
|
||||
}
|
||||
table.subscription-table .cell-cancel {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.active-subs div.buttons {
|
||||
text-align: center;
|
||||
}
|
||||
.active-subs div.buttons button {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.active-subs div.buttons .show-active-only-box {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.cp-contacts-container {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
.cp-contacts-container .cp-contact {
|
||||
padding: 5px;
|
||||
margin-right: 5px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cp-contacts-container .cp-contact:hover {
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
.cp-contacts-container .cp-avatar {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.cp-contacts-container .cp-name {
|
||||
width: 100px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.subscription-form div.buttons {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#info .button-container {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
|
||||
#info div.row > div {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
#info div.row {
|
||||
margin-right: 0px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
#info #error {
|
||||
padding: 0 10px 0 10px;
|
||||
}
|
||||
/* TODO(cjd) this is crap */
|
||||
#info > span {
|
||||
padding-left: 15px;
|
||||
}
|
||||
#info a.btn {
|
||||
color: white;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
#heading {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pay-spinner {
|
||||
position: fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
background-color:rgba(0, 0, 0, 0.6);
|
||||
z-index: 999999;
|
||||
color:white;
|
||||
|
||||
min-height: 100%;
|
||||
min-height: 100vh;
|
||||
height: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.pay-spinner div {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
#hallOfFameCheck {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
.faq-container .faq-questions-q {
|
||||
color: #3a84b6;
|
||||
padding: 0;
|
||||
margin-bottom: 0;
|
||||
margin-top: 5px;
|
||||
cursor: pointer;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.faq-container .faq-questions-q:hover {
|
||||
color: #2e688f;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.faq-container .faq-questions-a {
|
||||
display: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.crypto input {
|
||||
width: 100%;
|
||||
background-color: rgba(0,0,0,0.03);
|
||||
border: 0px;
|
||||
}
|
||||
.crypto table {
|
||||
width: 100%;
|
||||
}
|
||||
.crypto .coin-address {
|
||||
width: 100%;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.cp-admin-tabs-container {
|
||||
height: 50px;
|
||||
margin: 20px 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.cp-admin-tab {
|
||||
height: 100%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #EEF;
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
border-top: 1px solid #AAA;
|
||||
border-left: 1px solid #AAA;
|
||||
border-right: 1px solid #AAA;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cp-admin-tab:hover {
|
||||
background: #DDE;
|
||||
}
|
||||
.cp-admin-tab.active {
|
||||
background: #DDE;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.cp-admin-stats {
|
||||
background-color: #EEE;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.cp-admin-stats p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.cp div.cp-stats {
|
||||
flex: 1;
|
||||
}
|
||||
.cp div.cp-stats * {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cp-admin-stats .cp-stats-note {
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cp-admin-edit-getform input {
|
||||
margin: 0 10px;
|
||||
}
|
||||
.cp-admin-edit-found th {
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
.cp-admin-edit-found tbody tr:hover {
|
||||
background: #EEE;
|
||||
}
|
||||
.cp-admin-edit-found td {
|
||||
padding: 5px;
|
||||
border: 1px solid #CCC;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cp-admin-edit-getform input {
|
||||
margin: 0 10px;
|
||||
}
|
||||
.cp-admin-edit-form p {
|
||||
background: #AA0000;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
}
|
||||
.cp-admin-edit-form-content .cp-edit-field {
|
||||
font-weight: bold;
|
||||
}
|
||||
.cp-admin-edit-form-content .cp-edit-note {
|
||||
font-size: 0.9em;
|
||||
font-style: italic;
|
||||
}
|
||||
.cp-admin-edit-form-content input {
|
||||
margin: 0 10px;
|
||||
padding: 0 5px;
|
||||
border: 1px solid #888;
|
||||
}
|
||||
.cp-admin-edit-form-content {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
12
www/servers/index.html
Normal file
12
www/servers/index.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CryptPad</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="referrer" content="no-referrer" />
|
||||
<script async data-bootload="app/main.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
|
||||
<link href="/customize/src/outer.css?ver=1.1" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="sbox-iframe">
|
||||
Loading…
Reference in New Issue
Block a user