Files

117 lines
4.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
'require baseclass';
'require fs';
'require rpc';
'require ui';
var callGet = rpc.declare({ object: 'luci.argon_branding', method: 'get', expect: { '': {} }, raise: true });
var callSet = rpc.declare({ object: 'luci.argon_branding', method: 'set', params: ['target', 'token'], expect: { '': {} }, raise: true });
var callReset = rpc.declare({ object: 'luci.argon_branding', method: 'reset', params: ['target'], expect: { '': {} }, raise: true });
return baseclass.extend({
load: function() {
return callGet().catch(function() { return null; });
},
render: function(map, state) {
var busy = false;
var buttons = [];
var previews = {};
var defaults = {
favicon: L.resource('../argon/icon/favicon-32x32.png'),
logo: L.resource('../argon/img/argon.svg')
};
var labels = { favicon: _('Browser icon'), logo: _('Login logo') };
var available = state && state.result === 0;
function assetUrl(kind) {
return state && /^image-[0-9a-f]{64}\.png$/.test(state[kind] || '') ?
L.resource('../argon/branding/' + state[kind]) : defaults[kind];
}
function refresh() {
Object.keys(previews).forEach(function(kind) {
previews[kind].src = assetUrl(kind);
});
buttons.forEach(function(button) {
button.node.disabled = !!(map.readonly || busy || !available ||
(button.reset && !state[button.target]));
});
}
function update(target, upload) {
if (map.readonly || busy || !available)
return Promise.resolve();
busy = true;
refresh();
var file;
return Promise.resolve().then(function() {
if (!upload)
return callReset(target);
var token = Array.from(crypto.getRandomValues(new Uint32Array(4)), function(n) {
return ('00000000' + n.toString(16)).slice(-8);
}).join('');
file = '/tmp/argon_branding_' + token + '.png';
return ui.uploadFile(file).then(function() {
return callSet(target, token);
});
}).then(function(result) {
if (result.result === 2)
throw new Error(_('Invalid PNG image or dimensions.'));
if (result.result === 3)
throw new Error(_('Another update is running. Please try again.'));
if (result.result !== 0)
throw new Error(_('Unable to save custom branding.'));
state = result;
}).catch(function(error) {
ui.addNotification(null, E('p', {}, error.message), 'error');
}).finally(function() {
return (file ? L.resolveDefault(fs.remove(file)) : Promise.resolve()).finally(function() {
busy = false;
refresh();
});
});
}
function action(target, upload, label) {
var node = E('button', {
'type': 'button',
'class': 'btn cbi-button ' + (upload ? 'cbi-button-action' : 'cbi-button-reset'),
'click': function() { return update(target, upload); }
}, label);
buttons.push({ node: node, target: target, reset: !upload });
return node;
}
var cards = Object.keys(labels).map(function(kind) {
var preview = E('img', {
'src': assetUrl(kind), 'alt': labels[kind], 'width': 64, 'height': 64,
'error': function() { if (this.getAttribute('src') !== defaults[kind]) this.src = defaults[kind]; }
});
previews[kind] = preview;
return E('div', { 'class': 'argon-branding-card' }, [
E('h4', {}, labels[kind]),
E('div', { 'class': 'argon-branding-row' }, [
preview,
E('div', { 'class': 'argon-branding-actions' }, [
action(kind, true, _('Upload PNG...')),
action(kind, false, _('Restore default'))
])
])
]);
});
var content = E('div', { 'class': 'argon-branding-content' }, [
E('p', {}, _('PNG images, 16–1024 pixels per side, up to 1 MiB. Browser icons must be square.')),
E('div', { 'class': 'argon-branding-cards' }, cards),
action('both', true, _('Upload for both...')),
E('p', {}, _('Changes apply immediately. Reload open pages to update their icons.'))
]);
if (!available)
content.appendChild(E('p', { 'class': 'error' }, _('Unable to load custom branding. Reload this page or reinstall the theme.')));
refresh();
return E('div', { 'class': 'cbi-section', 'id': 'argon-branding' }, [
E('h3', {}, _('Custom branding')), content
]);
}
});