cloudcmd/client/config.js
2017-02-13 16:11:01 +02:00

300 lines
7.7 KiB
JavaScript

'use strict';
/* global CloudCmd, DOM, io */
const rendy = require('rendy');
const exec = require('execon');
const input = require('./input');
CloudCmd.Config = ConfigProto;
function ConfigProto() {
const config = CloudCmd.config;
const Key = CloudCmd.Key;
const Dialog = DOM.Dialog;
const Images = DOM.Images;
const Events = DOM.Events;
const Files = DOM.Files;
const showLoad = () => {
Images.show.load('top');
};
const TITLE = 'Config';
const Notify = DOM.Notify;
const Config = this;
let Loading = true;
let Element;
let Template;
function init() {
Loading = true;
showLoad();
exec.series([
CloudCmd.View,
function(callback) {
Loading = false;
exec(callback);
DOM.loadSocket(initSocket);
},
Config.show
]);
}
function getHost() {
var l = location,
href = l.origin || l.protocol + '//' + l.host;
return href;
}
function initSocket(error) {
var href = getHost();
var prefix = CloudCmd.PREFIX,
FIVE_SECONDS = 5000,
save = function(data) {
onSave(data);
socket.send(data);
};
if (error)
return;
var socket = io.connect(href + prefix + '/config', {
'max reconnection attempts' : Math.pow(2, 32),
'reconnection limit' : FIVE_SECONDS,
path: prefix + '/socket.io'
});
authCheck(socket);
socket.on('connect', function() {
Config.save = save;
});
socket.on('config', function(config) {
DOM.Storage.setAllowed(config.localStorage);
});
socket.on('message', function(data) {
onSave(data);
});
socket.on('log', function(msg) {
CloudCmd.log(msg);
});
socket.on('disconnect', function() {
Config.save = saveHttp;
});
socket.on('err', function(error) {
Dialog.alert(TITLE, error);
});
}
function authCheck(socket) {
if (!config('auth'))
return;
socket.emit('auth', config('username'), config('password'));
socket.on('reject', function() {
Dialog.alert(TITLE, 'Wrong credentials!');
});
}
Config.save = saveHttp;
this.show = function() {
var prefix = CloudCmd.PREFIX,
funcs = [
exec.with(Files.get, 'config-tmpl'),
exec.with(DOM.load.parallel, [
prefix + '/css/config.css'
])
];
if (!Loading) {
showLoad();
exec.parallel(funcs, fillTemplate);
}
};
function fillTemplate(error, template) {
if (!Template)
Template = template;
Files.get('config', (error, config) => {
if (error)
return Dialog.alert(TITLE, 'Could not load config!');
const obj = input.convert(config);
obj[obj.editor + '-selected'] = 'selected';
delete obj.editor;
obj[obj.packer + '-selected'] = 'selected';
delete obj.packer;
const inner = rendy(Template, obj);
Element = DOM.load({
name : 'div',
className : 'config',
inner,
attribute : {
'data-name': 'js-config'
}
});
const inputs = document.querySelectorAll('input, select', Element);
const inputFirst = inputs[0];
let focus;
if (inputFirst) {
onAuthChange(inputFirst.checked);
focus = () => {
inputFirst.focus();
};
}
[].forEach.call(inputs, (input) => {
Events.addKey(input, onKey)
.add('change', input, ({target}) => {
onChange(target);
});
});
CloudCmd.View.show(Element, {
autoSize: true,
afterShow: focus
});
});
}
this.hide = () => {
CloudCmd.View.hide();
};
function onChange(el) {
var obj = {},
name = input.getName(el),
data = input.getValue(name, Element),
type = el.type;
if (type === 'checkbox')
if (/^(diff|buffer|dirStorage)$/.test(name))
onLSChange(name, data);
else if (name === 'localStorage')
onLocalStorageChange();
else if (name === 'auth')
onAuthChange(data);
if (name === 'notifications') {
if (data && !Notify.check())
Notify.request();
}
obj[name] = data;
Config.save(obj);
}
function onSave(obj) {
Object.keys(obj).forEach((name) => {
const data = obj[name];
CloudCmd._config(name, data);
input.setValue(name, data, Element);
});
DOM.Storage.setAllowed(obj.localStorage);
}
function saveHttp(obj) {
const {RESTful} = DOM;
RESTful.Config.write(obj, (error) => {
if (error)
return;
onSave(obj);
});
}
function onLocalStorageChange() {
var names = ['diff', 'buffer', 'dirStorage', 'localStorage'],
elements = names.map(function(name) {
return input.getElementByName(name, Element);
}),
el = {},
msg = 'Diff, Buffer and Directory Storage do not work without localStorage',
isChecked;
elements.forEach((element) => {
const name = input.getName(element);
el[name] = element;
if (element.checked)
isChecked = true;
});
if (!isChecked || el.localStorage.checked)
return;
Dialog.alert(TITLE, msg);
elements.forEach((element) => {
if (element.checked) {
element.checked = false;
onChange(element);
}
return element;
});
}
function onLSChange(name, data) {
const elLocalStorage = input.getElementByName('localStorage', Element);
const msg = name + ' depends on localStorage';
if (!data || elLocalStorage.checked)
return;
Dialog.alert(TITLE, msg);
elLocalStorage.checked = true;
}
function onAuthChange(checked) {
const elUsername = input.getElementByName('username', Element);
const elPassword = input.getElementByName('password', Element);
elUsername.disabled =
elPassword.disabled = !checked;
}
function onKey({keyCode, target}) {
switch (keyCode) {
case Key.ESC:
Config.hide();
break;
case Key.ENTER:
onChange(target);
break;
}
}
if (!CloudCmd.config('configDialog'))
return;
init();
}