const config=require('config'); const assets=require('assets'); const Popup=require('popup'); let lastCEId=0; class ConfigEditor extends Popup { constructor() { super("Config editor", [], {ok: "OK"}); const metaConfig=assets.get('metaConfig'); this.watchers=[]; for(let key in metaConfig) { const level=Array.from(key).reduce((a, c) => a+c=='.', 0)+2; const data=metaConfig[key]; if(!data.type) { this.addHeading(data.name); } else { let span=document.createElement('span'); let id='cfgInput-'+(lastCEId++)+'-'+key.replace(/\./g, '-'); let label=span.appendChild(document.createElement('label')); label.innerText=data.name; if(config.getB('debug')) label.title=key; let input; if(data.type=='boolean') { input=document.createElement('input'); input.type='checkbox'; input.checked=config.getB(key); input.addEventListener('change', () => config.set(key, input.checked)); } else if(data.type=='choice') { input=document.createElement('select'); data.bounds.choices.forEach(choice => { let option=document.createElement('option'); option.value=choice; option.innerText=choice; input.appendChild(option); }); input.value=config.getS(key); input.addEventListener('change', () => config.set(key, input.value)); } else if(data.type=='number') { input=document.createElement('input'); input.type='number'; if(data.bounds) { input.setAttribute('min', data.bounds.min); input.setAttribute('max', data.bounds.max); input.setAttribute('step', data.bounds.inc); } input.value=config.getN(key); input.addEventListener('change', () => config.set(key, input.value)); } else if(data.type=='string') { input=document.createElement('input'); input.type='text'; input.value=config.getS(key); input.addEventListener('change', () => config.set(key, input.value)); } input.setAttribute('id', id); span.appendChild(input); label.setAttribute('for', id); this.addContent(span); if(data.excludes) { const setEnabled=() => { input.disabled= data.excludes .some(key => config.getB(key)); input.title=input.disabled?`Disable '${data.excludes.map(k => metaConfig[k].name).join('\', \'')}' to enable`:''; }; setEnabled(); data.excludes.forEach(key => { let c=config.watchB(key, setEnabled); this.watchers.push([key, c]); }); } else if(data.parent) { const setEnabled=() => { input.disabled=!config.getB(data.parent); input.title=input.disabled?`Enable '${metaConfig[data.parent].name}' to enable`:''; }; setEnabled(); let c=config.watchB(data.parent, setEnabled); this.watchers.push([data.parent, c]); } if(data.needsBackend) { if(window.serverless) { input.disabled=true; input.title="Needs backend"; } } } } this.large=true; } discard() { this.watchers.forEach(([k, c]) => config.unwatch(k, c)); } }; return module.exports={ show: async () => { let editor=new ConfigEditor(); await editor.display(); editor.discard(); } };