', {id: 'cp-sidebarlayout-leftside'}).appendTo(APP.$container);
+ APP.$rightside = $('
', {id: 'cp-sidebarlayout-rightside'}).appendTo(APP.$container);
+ sFrameChan = common.getSframeChannel();
+ sFrameChan.onReady(waitFor());
+ }).nThen(function (/*waitFor*/) {
+ createToolbar();
+ var metadataMgr = common.getMetadataMgr();
+ var privateData = metadataMgr.getPrivateData();
+ common.setTabTitle(Messages.adminPage || 'Administration');
+
+ if (!privateData.edPublic || !ApiConfig.adminKeys || !Array.isArray(ApiConfig.adminKeys)
+ || ApiConfig.adminKeys.indexOf(privateData.edPublic) === -1) {
+ return void UI.errorLoadingScreen(Messages.admin_authError || '403 Forbidden');
+ }
+
+ APP.origin = privateData.origin;
+ APP.readOnly = privateData.readOnly;
+
+ // Content
+ var $rightside = APP.$rightside;
+ var addItem = function (cssClass) {
+ var item = cssClass.slice(9); // remove 'cp-settings-'
+ if (typeof (create[item]) === "function") {
+ $rightside.append(create[item]());
+ }
+ };
+ for (var cat in categories) {
+ if (!Array.isArray(categories[cat])) { continue; }
+ categories[cat].forEach(addItem);
+ }
+
+ createLeftside();
+
+ UI.removeLoadingScreen();
+
+ });
+});
diff --git a/www/admin/main.js b/www/admin/main.js
new file mode 100644
index 000000000..cdfaf115c
--- /dev/null
+++ b/www/admin/main.js
@@ -0,0 +1,64 @@
+// 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 + '/admin/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*/) {
+ // Adding a new avatar from the profile: pin it and store it in the object
+ sframeChan.on('Q_ADMIN_RPC', function (data, cb) {
+ Cryptpad.adminRpc(data, cb);
+ });
+ 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
+ });
+ });
+});