2019-11-27 22:28:13 +01:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
2020-12-23 21:43:30 +01:00
|
|
|
<head lang="en">
|
2021-04-01 17:12:45 +02:00
|
|
|
<meta charset="utf-8">
|
2019-11-27 22:28:13 +01:00
|
|
|
<meta name="viewport" content="width=500">
|
|
|
|
<title>UI Settings</title>
|
|
|
|
<script>
|
2020-08-30 23:31:58 +02:00
|
|
|
var d = document;
|
|
|
|
var initial_ds, initial_st;
|
|
|
|
var sett = null;
|
|
|
|
var l = {
|
|
|
|
"comp":{
|
2021-04-01 17:12:45 +02:00
|
|
|
"labels":"Show button labels",
|
|
|
|
"colors":{
|
|
|
|
"LABEL":"Color selection methods",
|
|
|
|
"picker": "Color Wheel",
|
|
|
|
"rgb": "RGB sliders",
|
|
|
|
"quick": "Quick color selectors",
|
|
|
|
"hex": "HEX color input"
|
|
|
|
},
|
|
|
|
"pcmbot": "Show bottom tab bar in PC mode",
|
|
|
|
"pid": "Show preset IDs",
|
|
|
|
"seglen": "Use LED Count instead of Stop LED on segments"
|
2020-08-30 23:31:58 +02:00
|
|
|
},
|
|
|
|
"theme":{
|
|
|
|
"alpha": {
|
|
|
|
"bg":"Background opacity",
|
|
|
|
"tab":"Button opacity"
|
|
|
|
},
|
|
|
|
"bg":{
|
2020-12-21 21:12:07 +01:00
|
|
|
"url":"BG image URL",
|
|
|
|
"random":"Random BG image"
|
2020-08-30 23:31:58 +02:00
|
|
|
},
|
|
|
|
"color":{
|
|
|
|
"bg":"BG HEX color"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2019-11-27 22:28:13 +01:00
|
|
|
function gId(s)
|
|
|
|
{
|
2020-08-30 23:31:58 +02:00
|
|
|
return d.getElementById(s);
|
|
|
|
}
|
|
|
|
function isObject(item) {
|
|
|
|
return (item && typeof item === 'object' && !Array.isArray(item));
|
|
|
|
}
|
|
|
|
function set(path, obj, val) {
|
|
|
|
var tar = obj;
|
|
|
|
var pList = path.split('_');
|
|
|
|
var len = pList.length;
|
|
|
|
for(var i = 0; i < len-1; i++) {
|
|
|
|
var elem = pList[i];
|
|
|
|
if( !tar[elem] ) tar[elem] = {}
|
|
|
|
tar = tar[elem];
|
|
|
|
}
|
|
|
|
tar[pList[len-1]] = val;
|
|
|
|
}
|
2021-06-06 20:36:19 +02:00
|
|
|
var timeout;
|
|
|
|
function showToast(text, error = false)
|
|
|
|
{
|
|
|
|
var x = gId("toast");
|
|
|
|
x.innerHTML = text;
|
|
|
|
x.className = error ? "error":"show";
|
|
|
|
clearTimeout(timeout);
|
|
|
|
x.style.animation = 'none';
|
|
|
|
timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900);
|
|
|
|
}
|
2020-08-30 23:31:58 +02:00
|
|
|
function addRec(s, path = "", label = null)
|
|
|
|
{
|
|
|
|
var str = "";
|
|
|
|
for (i in s)
|
|
|
|
{
|
|
|
|
var fk = path + (path?'_':'') + i;
|
|
|
|
if (isObject(s[i])) {
|
|
|
|
if (label && label[i] && label[i]["LABEL"]) str += `<h3>${label[i]["LABEL"]}</h3>`;
|
|
|
|
str += addRec(s[i], fk, label? label[i] : null);
|
|
|
|
} else {
|
|
|
|
var lb = fk;
|
|
|
|
if (label && label[i]) lb = label[i];
|
|
|
|
else if (s[i+'LABEL']) lb = s[i+'LABEL'];
|
|
|
|
if (i.indexOf('LABEL') > 0) continue;
|
|
|
|
var t = typeof s[i];
|
|
|
|
if (gId(fk)) { //already exists
|
|
|
|
if(t === 'boolean')
|
|
|
|
{
|
|
|
|
gId(fk).checked = s[i];
|
|
|
|
} else {
|
|
|
|
gId(fk).value = s[i];
|
|
|
|
}
|
|
|
|
if (gId(fk).previousElementSibling.matches('.l')) {
|
|
|
|
gId(fk).previousElementSibling.innerHTML = lb;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(t === 'boolean')
|
|
|
|
{
|
|
|
|
str += `${lb}: <input class="agi cb" type="checkbox" id=${fk} ${s[i]?"checked":""}><br>`;
|
|
|
|
} else if (t === 'number')
|
|
|
|
{
|
|
|
|
str += `${lb}: <input class="agi" type="number" id=${fk} value=${s[i]}><br>`;
|
|
|
|
} else if (t === 'string')
|
|
|
|
{
|
|
|
|
str += `${lb}:<br><input class="agi" id=${fk} value=${s[i]}><br>`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
function genForm(s) {
|
|
|
|
var str = "";
|
|
|
|
str = addRec(s,"",l);
|
|
|
|
|
|
|
|
gId('gen').innerHTML = str;
|
|
|
|
}
|
|
|
|
function GetLS()
|
|
|
|
{
|
|
|
|
sett = localStorage.getItem('wledUiCfg');
|
|
|
|
if (!sett) gId('lserr').style.display = "inline";
|
|
|
|
try {
|
|
|
|
sett = JSON.parse(sett);
|
|
|
|
} catch (e) {
|
|
|
|
sett = {};
|
|
|
|
gId('lserr').style.display = "inline";
|
|
|
|
gId('lserr').innerHTML = "⚠ Settings JSON parsing failed. (" + e + ")";
|
|
|
|
}
|
|
|
|
genForm(sett);
|
|
|
|
gId('dm').checked = (gId('theme_base').value === 'light');
|
|
|
|
}
|
|
|
|
|
|
|
|
function SetLS()
|
|
|
|
{
|
|
|
|
var l = d.querySelectorAll('.agi');
|
|
|
|
for (var i = 0; i < l.length; i++) {
|
|
|
|
var e = l[i];
|
|
|
|
var val = e.classList.contains('cb') ? e.checked : e.value;
|
|
|
|
set(e.id, sett, val);
|
|
|
|
console.log(`${e.id} set to ${val}`);
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
localStorage.setItem('wledUiCfg', JSON.stringify(sett));
|
|
|
|
gId('lssuc').style.display = "inline";
|
|
|
|
} catch (e) {
|
|
|
|
gId('lssuc').style.display = "none";
|
|
|
|
gId('lserr').style.display = "inline";
|
|
|
|
gId('lserr').innerHTML = "⚠ Settings JSON saving failed. (" + e + ")";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function Save() {
|
|
|
|
SetLS();
|
|
|
|
if (d.Sf.DS.value != initial_ds || d.Sf.ST.checked != initial_st) d.Sf.submit();
|
2019-11-27 22:28:13 +01:00
|
|
|
}
|
2020-08-30 23:31:58 +02:00
|
|
|
|
2019-11-27 22:28:13 +01:00
|
|
|
function S()
|
|
|
|
{
|
2020-08-30 23:31:58 +02:00
|
|
|
GetV();
|
|
|
|
initial_ds = d.Sf.DS.value;
|
|
|
|
initial_st = d.Sf.ST.checked;
|
|
|
|
GetLS();
|
2019-11-27 22:28:13 +01:00
|
|
|
}
|
|
|
|
function H()
|
|
|
|
{
|
|
|
|
window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");
|
|
|
|
}
|
|
|
|
function B()
|
|
|
|
{
|
|
|
|
window.open("/settings","_self");
|
|
|
|
}
|
2020-08-30 23:31:58 +02:00
|
|
|
function UI()
|
2019-11-27 22:28:13 +01:00
|
|
|
{
|
2020-08-30 23:31:58 +02:00
|
|
|
gId('idonthateyou').style.display = (gId('dm').checked) ? 'inline':'none';
|
|
|
|
var f = gId('theme_base');
|
|
|
|
if (f) f.value = (gId('dm').checked) ? 'light':'dark';
|
2019-11-27 22:28:13 +01:00
|
|
|
}
|
2020-12-21 21:12:07 +01:00
|
|
|
|
|
|
|
// random BG image
|
|
|
|
function setRandomBg() {
|
|
|
|
if (gId("theme_bg_random").checked) {
|
|
|
|
gId("theme_bg_url").value = "https://picsum.photos/1920/1080";
|
|
|
|
} else {
|
|
|
|
gId("theme_bg_url").value = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
function checkRandomBg() {
|
|
|
|
if (gId("theme_bg_url").value === "https://picsum.photos/1920/1080") {
|
|
|
|
gId("theme_bg_random").checked = true;
|
|
|
|
} else {
|
|
|
|
gId("theme_bg_random").checked = false;
|
|
|
|
}
|
|
|
|
}
|
2021-07-14 23:10:19 +02:00
|
|
|
function uploadFile(fO,name) {
|
2021-06-06 20:36:19 +02:00
|
|
|
var req = new XMLHttpRequest();
|
|
|
|
req.addEventListener('load', function(){showToast(this.responseText)});
|
|
|
|
req.addEventListener('error', function(e){showToast(e.stack,true);});
|
|
|
|
req.open("POST", "/upload");
|
|
|
|
var formData = new FormData();
|
2021-07-14 23:10:19 +02:00
|
|
|
formData.append("data", fO.files[0], name);
|
2021-06-06 20:36:19 +02:00
|
|
|
req.send(formData);
|
2021-07-14 23:10:19 +02:00
|
|
|
fO.value = '';
|
2021-06-06 20:36:19 +02:00
|
|
|
return false;
|
|
|
|
}
|
2021-05-11 23:21:57 +02:00
|
|
|
function GetV(){var d=document;}
|
2019-11-27 22:28:13 +01:00
|
|
|
</script>
|
2021-06-06 20:36:19 +02:00
|
|
|
<style>@import url("/style.css");</style>
|
|
|
|
<link href="/skin.css" rel="stylesheet">
|
2019-11-27 22:28:13 +01:00
|
|
|
</head>
|
|
|
|
<body onload="S()">
|
|
|
|
<form id="form_s" name="Sf" method="post">
|
2021-03-05 09:50:59 +01:00
|
|
|
<div class="toprow">
|
2019-11-27 22:28:13 +01:00
|
|
|
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
2020-08-30 23:31:58 +02:00
|
|
|
<button type="button" onclick="B()">Back</button><button type="button" onclick="Save()">Save</button><br>
|
|
|
|
<span id="lssuc" style="color:green; display:none">✔ Local UI settings saved!</span>
|
|
|
|
<span id="lserr" style="color:red; display:none">⚠ Could not access local storage. Make sure it is enabled in your browser.</span><hr>
|
|
|
|
</div>
|
2019-11-27 22:28:13 +01:00
|
|
|
<h2>Web Setup</h2>
|
2019-12-13 01:23:07 +01:00
|
|
|
Server description: <input name="DS" maxlength="32"><br>
|
2021-04-01 17:12:45 +02:00
|
|
|
Sync button toggles both send and receive: <input type="checkbox" name="ST"><br>
|
2020-08-30 23:31:58 +02:00
|
|
|
<i>The following UI customization settings are unique both to the WLED device and this browser.<br>
|
|
|
|
You will need to set them again if using a different browser, device or WLED IP address.<br>
|
|
|
|
Refresh the main UI to apply changes.</i><br>
|
|
|
|
|
|
|
|
<div id="gen">Loading settings...</div>
|
|
|
|
|
|
|
|
<h3>UI Appearance</h3>
|
|
|
|
<span class="l"></span>: <input type="checkbox" id="comp_labels" class="agi cb"><br>
|
2021-04-01 17:12:45 +02:00
|
|
|
<span class="l"></span>: <input type="checkbox" id="comp_pcmbot" class="agi cb"><br>
|
|
|
|
<span class="l"></span>: <input type="checkbox" id="comp_pid" class="agi cb"><br>
|
|
|
|
<span class="l"></span>: <input type="checkbox" id="comp_seglen" class="agi cb"><br>
|
2020-08-30 23:31:58 +02:00
|
|
|
I hate dark mode: <input type="checkbox" id="dm" onchange="UI()"><br>
|
|
|
|
<span id="idonthateyou" style="display:none"><i>Why would you? </i>🥺<br></span>
|
|
|
|
<span class="l"></span>: <input type="number" min=0.0 max=1.0 step=0.01 id="theme_alpha_tab" class="agi"><br>
|
|
|
|
<span class="l"></span>: <input type="number" min=0.0 max=1.0 step=0.01 id="theme_alpha_bg" class="agi"><br>
|
|
|
|
<span class="l"></span>: <input id="theme_color_bg" maxlength="9" class="agi"><br>
|
2020-12-21 21:12:07 +01:00
|
|
|
<span class="l">BG image URL</span>: <input id="theme_bg_url" class="agi" oninput="checkRandomBg()"><br>
|
|
|
|
<span class="l">Random BG image</span>: <input type="checkbox" id="theme_bg_random" class="agi cb" onchange="setRandomBg()"><br>
|
2020-08-30 23:31:58 +02:00
|
|
|
<input id="theme_base" class="agi" style="display:none">
|
2021-07-14 23:10:19 +02:00
|
|
|
<div id="skin">Skinning CSS: <input type="file" name="data" accept=".css"> <input type="button" value="Upload" onclick="uploadFile(d.Sf.data,'/skin.css');"><br></div>
|
|
|
|
<div id="holidays">Holidays: <input type="file" name="data2" accept=".json"> <input type="button" value="Upload" onclick="uploadFile(d.Sf.data2,'/holidays.json');"><br></div>
|
2021-06-06 20:36:19 +02:00
|
|
|
<div id="toast"></div>
|
2020-08-30 23:31:58 +02:00
|
|
|
<hr><button type="button" onclick="B()">Back</button><button type="button" onclick="Save()">Save</button>
|
2019-11-27 22:28:13 +01:00
|
|
|
</form>
|
|
|
|
</body>
|
|
|
|
</html>
|