Merge remote-tracking branch 'upstream/main' into mdev
This commit is contained in:
@@ -731,7 +731,7 @@ function populateSegments(s)
|
||||
let rvXck = `<label class="check revchkl">Reverse ${isM?'':'direction'}<input type="checkbox" id="seg${i}rev" onchange="setRev(${i})" ${inst.rev?"checked":""}><span class="checkmark"></span></label>`;
|
||||
let miXck = `<label class="check revchkl">Mirror<input type="checkbox" id="seg${i}mi" onchange="setMi(${i})" ${inst.mi?"checked":""}><span class="checkmark"></span></label>`;
|
||||
let rvYck = "", miYck ="";
|
||||
if (isM) {
|
||||
if (isM && staX<mw*mh) {
|
||||
rvYck = `<label class="check revchkl">Reverse<input type="checkbox" id="seg${i}rY" onchange="setRevY(${i})" ${inst.rY?"checked":""}><span class="checkmark"></span></label>`;
|
||||
miYck = `<label class="check revchkl">Mirror<input type="checkbox" id="seg${i}mY" onchange="setMiY(${i})" ${inst.mY?"checked":""}><span class="checkmark"></span></label>`;
|
||||
}
|
||||
@@ -775,19 +775,19 @@ function populateSegments(s)
|
||||
<input type="text" class="ptxt noslide" id="seg${i}t" autocomplete="off" maxlength=32 value="${inst.n?inst.n:""}" placeholder="Enter name..."/>
|
||||
<table class="infot segt">
|
||||
<tr>
|
||||
<td>${isM?'Start X':'Start LED'}</td>
|
||||
<td>${isM?(cfg.comp.seglen?"Width":"Stop X"):(cfg.comp.seglen?"LED count":"Stop LED")}</td>
|
||||
<td>${isM?'':'Offset'}</td>
|
||||
<td>${isM&&staX<mw*mh?'Start X':'Start LED'}</td>
|
||||
<td>${isM&&staX<mw*mh?(cfg.comp.seglen?"Width":"Stop X"):(cfg.comp.seglen?"LED count":"Stop LED")}</td>
|
||||
<td>${isM&&staX<mw*mh?'':'Offset'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="noslide segn" id="seg${i}s" type="number" min="0" max="${(isM?mw:ledCount)-1}" value="${staX}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}e" type="number" min="0" max="${(isM?mw:ledCount)-(cfg.comp.seglen?staX:0)}" value="${stoX-(cfg.comp.seglen?staX:0)}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td style="text-align:revert;">${isM?miXck+'<br>'+rvXck:''}<input class="noslide segn ${isM?'hide':''}" id="seg${i}of" type="number" value="${inst.of}" oninput="updateLen(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}s" type="number" min="0" max="${(isM&&staX<mw*mh?mw:ledCount)-1}" value="${staX}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}e" type="number" min="0" max="${(isM&&staX<mw*mh?mw:ledCount)}" value="${stoX-(cfg.comp.seglen?staX:0)}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td style="text-align:revert;">${isM&&staX<mw*mh?miXck+'<br>'+rvXck:''}<input class="noslide segn ${isM&&staX<mw*mh?'hide':''}" id="seg${i}of" type="number" value="${inst.of}" oninput="updateLen(${i})"></td>
|
||||
</tr>
|
||||
${isM ? '<tr><td>Start Y</td><td>'+(cfg.comp.seglen?'Height':'Stop Y')+'</td><td></td></tr>'+
|
||||
${isM&&staX<mw*mh ? '<tr><td>Start Y</td><td>'+(cfg.comp.seglen?'Height':'Stop Y')+'</td><td></td></tr>'+
|
||||
'<tr>'+
|
||||
'<td><input class="noslide segn" id="seg'+i+'sY" type="number" min="0" max="'+(mh-1)+'" value="'+staY+'" oninput="updateLen('+i+')" onkeydown="segEnter('+i+')"></td>'+
|
||||
'<td><input class="noslide segn" id="seg'+i+'eY" type="number" min="0" max="'+(mh-(cfg.comp.seglen?staY:0))+'" value="'+(stoY-(cfg.comp.seglen?staY:0))+'" oninput="updateLen('+i+')" onkeydown="segEnter('+i+')"></td>'+
|
||||
'<td><input class="noslide segn" id="seg'+i+'eY" type="number" min="0" max="'+mh+'" value="'+(stoY-(cfg.comp.seglen?staY:0))+'" oninput="updateLen('+i+')" onkeydown="segEnter('+i+')"></td>'+
|
||||
'<td style="text-align:revert;">'+miYck+'<br>'+rvYck+'</td>'+
|
||||
'</tr>':''}
|
||||
<tr>
|
||||
@@ -798,17 +798,18 @@ function populateSegments(s)
|
||||
<tr>
|
||||
<td><input class="noslide segn" id="seg${i}grp" type="number" min="1" max="255" value="${inst.grp}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}spc" type="number" min="0" max="255" value="${inst.spc}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td style="text-align:left;"><button class="btn btn-xs" onclick="setSeg(${i})"><i class="icons btn-icon" id="segc${i}"></i></button></td>
|
||||
<td style="text-align:revert;"><button class="btn btn-xs" onclick="setSeg(${i})"><i class="icons btn-icon" id="segc${i}"></i></button></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="h bp" id="seg${i}len"></div>
|
||||
${!isM?rvXck:''}
|
||||
${isM&&stoY-staY>1&&stoX-staX>1?map2D:''}
|
||||
${!(isM&&staX<mw*mh)?rvXck:''}
|
||||
${isM&&staX<mw*mh&&stoY-staY>1&&stoX-staX>1?map2D:''}
|
||||
${s.AudioReactive && s.AudioReactive.on ? "" : sndSim}
|
||||
${s.CustomEffects && s.CustomEffects.on && fxName.includes("Custom Effect") ? cusEff : ""}
|
||||
<label class="check revchkl" id="seg${i}lbtm">
|
||||
${isM?'Transpose':'Mirror effect'}
|
||||
<input type="checkbox" id="seg${i}${isM?'tp':'mi'}" onchange="${(isM?'setTp(':'setMi(')+i})" ${isM?(inst.tp?"checked":""):(inst.mi?"checked":"")}>
|
||||
${isM&&staX<mw*mh?'Transpose':'Mirror effect'}${isM&&staX<mw*mh?
|
||||
'<input type="checkbox" id="seg'+i+'tp" onchange="setTp('+i+')" '+(inst.tp?"checked":"")+'>':
|
||||
'<input type="checkbox" id="seg'+i+'mi" onchange="setMi('+i+')" '+(inst.mi?"checked":"")+'>'}
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
<div class="del">
|
||||
@@ -1078,29 +1079,50 @@ function updateLen(s)
|
||||
var start = parseInt(gId(`seg${s}s`).value);
|
||||
var stop = parseInt(gId(`seg${s}e`).value) + (cfg.comp.seglen?start:0);
|
||||
var len = stop - start;
|
||||
let sY = gId(`seg${s}sY`);
|
||||
let eY = gId(`seg${s}eY`);
|
||||
let sX = gId(`seg${s}s`);
|
||||
let eX = gId(`seg${s}e`);
|
||||
let of = gId(`seg${s}of`);
|
||||
let mySH = gId("mkSYH");
|
||||
let mySD = gId("mkSYD");
|
||||
if (isM) {
|
||||
// matrix setup
|
||||
let startY = parseInt(gId(`seg${s}sY`).value);
|
||||
let stopY = parseInt(gId(`seg${s}eY`).value) + (cfg.comp.seglen?startY:0);
|
||||
len *= (stopY-startY);
|
||||
let tPL = gId(`seg${s}lbtm`);
|
||||
if (stop-start>1 && stopY-startY>1) {
|
||||
// 2D segment
|
||||
if (tPL) tPL.classList.remove('hide'); // unhide transpose checkbox
|
||||
let sE = gId('fxlist').querySelector(`.lstI[data-id="${selectedFx}"]`);
|
||||
if (sE) {
|
||||
let sN = sE.querySelector(".lstIname").innerText;
|
||||
let seg = gId(`seg${s}map2D`);
|
||||
if (seg) {
|
||||
if(sN.indexOf("\u25A6")<0) seg.classList.remove('hide'); // unhide mapping for 1D effects (| in name)
|
||||
else seg.classList.add('hide'); // hide mapping otherwise
|
||||
}
|
||||
}
|
||||
// do we have 1D segment *after* the matrix?
|
||||
if (start >= mw*mh) {
|
||||
if (sY) { sY.value = 0; sY.max = 0; sY.min = 0; }
|
||||
if (eY) { eY.value = 1; eY.max = 1; eY.min = 0; }
|
||||
sX.min = mw*mh; sX.max = ledCount-1;
|
||||
eX.min = mw*mh+1; eX.max = ledCount;
|
||||
if (mySH) mySH.classList.add("hide");
|
||||
if (mySD) mySD.classList.add("hide");
|
||||
if (of) of.classList.remove("hide");
|
||||
} else {
|
||||
// 1D segment in 2D set-up
|
||||
if (tPL) {
|
||||
tPL.classList.add('hide'); // hide transpose checkbox
|
||||
gId(`seg${s}tp`).checked = false; // and uncheck it
|
||||
// matrix setup
|
||||
if (mySH) mySH.classList.remove("hide");
|
||||
if (mySD) mySD.classList.remove("hide");
|
||||
if (of) of.classList.add("hide");
|
||||
let startY = parseInt(sY.value);
|
||||
let stopY = parseInt(eY.value) + (cfg.comp.seglen?startY:0);
|
||||
len *= (stopY-startY);
|
||||
let tPL = gId(`seg${s}lbtm`);
|
||||
if (stop-start>1 && stopY-startY>1) {
|
||||
// 2D segment
|
||||
if (tPL) tPL.classList.remove('hide'); // unhide transpose checkbox
|
||||
let sE = gId('fxlist').querySelector(`.lstI[data-id="${selectedFx}"]`);
|
||||
if (sE) {
|
||||
let sN = sE.querySelector(".lstIname").innerText;
|
||||
let seg = gId(`seg${s}map2D`);
|
||||
if (seg) {
|
||||
if(sN.indexOf("\u25A6")<0) seg.classList.remove('hide'); // unhide mapping for 1D effects (| in name)
|
||||
else seg.classList.add('hide'); // hide mapping otherwise
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 1D segment in 2D set-up
|
||||
if (tPL) {
|
||||
tPL.classList.add('hide'); // hide transpose checkbox
|
||||
gId(`seg${s}tp`).checked = false; // and uncheck it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1119,6 +1141,7 @@ function updateLen(s)
|
||||
var virt = Math.ceil(len/(grp + spc));
|
||||
if (!isNaN(virt) && (grp > 1 || spc > 0)) out += ` (${virt} virtual)`;
|
||||
}
|
||||
if (isM && start >= mw*mh) out += " [strip]";
|
||||
|
||||
gId(`seg${s}len`).innerHTML = out;
|
||||
draw();
|
||||
@@ -1840,11 +1863,11 @@ function makeSeg()
|
||||
<td><input class="noslide segn" id="seg${lu}e" type="number" min="0" max="${ct}" value="${ct}" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><button class="btn btn-xs" onclick="setSeg(${lu});"><i class="icons bth-icon" id="segc${lu}"></i></button></td>
|
||||
</tr>
|
||||
${isM ? '<tr><td>Start Y</td><td>'+(cfg.comp.seglen?'Height':'Stop Y')+'</td></tr>'+
|
||||
'<tr>'+
|
||||
'<td><input class="noslide segn" id="seg'+lu+'sY" type="number" min="0" max="'+(mh-1)+'" value="'+0+'" oninput="updateLen('+lu+')" onkeydown="segEnter('+lu+')"></td>'+
|
||||
'<td><input class="noslide segn" id="seg'+lu+'eY" type="number" min="0" max="'+mh+'" value="'+mh+'" oninput="updateLen('+lu+')" onkeydown="segEnter('+lu+')"></td>'+
|
||||
'</tr>':''}
|
||||
<tr id="mkSYH" class="${isM?"":"hide"}"><td>Start Y</td><td>${cfg.comp.seglen?'Height':'Stop Y'}</td></tr>
|
||||
<tr id="mkSYD" class="${isM?"":"hide"}">
|
||||
<td><input class="noslide segn" id="seg${lu}sY" type="number" min="0" max="${mh-1}" value="0" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><input class="noslide segn" id="seg${lu}eY" type="number" min="0" max="${mh}" value="${isM?mh:1}" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="h" id="seg${lu}len">${ledCount - ns} LEDs</div>
|
||||
<div class="c"><button class="btn btn-p" onclick="resetUtil()">Cancel</button></div>
|
||||
@@ -2174,25 +2197,26 @@ function setSeg(s)
|
||||
let sX = gId(`seg${s}s`);
|
||||
let eX = gId(`seg${s}e`);
|
||||
var start = parseInt(sX.value);
|
||||
var stop = parseInt(eX.value);
|
||||
var stop = parseInt(eX.value) + (cfg.comp.seglen?start:0);
|
||||
if (start<sX.min || start>sX.max) {sX.value=sX.min; return;} // prevent out of bounds
|
||||
if (stop<eX.min || stop>eX.max) {eX.value=eX.max; return;} // prevent out of bounds
|
||||
if (stop<eX.min || stop-(cfg.comp.seglen?start:0)>eX.max) {eX.value=eX.max; return;} // prevent out of bounds
|
||||
if ((cfg.comp.seglen && stop == 0) || (!cfg.comp.seglen && stop <= start)) {delSeg(s); return;}
|
||||
var obj = {"seg": {"id": s, "n": name, "start": start, "stop": (cfg.comp.seglen?start:0)+stop}};
|
||||
if (isM) {
|
||||
var obj = {"seg": {"id": s, "n": name, "start": start, "stop": stop}};
|
||||
if (isM && start<mw*mh) {
|
||||
let sY = gId(`seg${s}sY`);
|
||||
let eY = gId(`seg${s}eY`);
|
||||
var startY = parseInt(sY.value);
|
||||
var stopY = parseInt(eY.value);
|
||||
var stopY = parseInt(eY.value) + (cfg.comp.seglen?startY:0);
|
||||
if (startY<sY.min || startY>sY.max) {sY.value=sY.min; return;} // prevent out of bounds
|
||||
if (stopY<eY.min || stopY>eY.max) {eY.value=eY.max; return;} // prevent out of bounds
|
||||
obj.seg.startY = startY;
|
||||
obj.seg.stopY = (cfg.comp.seglen?startY:0)+stopY;
|
||||
obj.seg.stopY = stopY;
|
||||
}
|
||||
if (gId(`seg${s}grp`)) { // advanced options, not present in new segment dialog (makeSeg())
|
||||
var grp = parseInt(gId(`seg${s}grp`).value);
|
||||
var spc = parseInt(gId(`seg${s}spc`).value);
|
||||
var ofs = parseInt(gId(`seg${s}of` ).value);
|
||||
let g = gId(`seg${s}grp`);
|
||||
if (g) { // advanced options, not present in new segment dialog (makeSeg())
|
||||
let grp = parseInt(g.value);
|
||||
let spc = parseInt(gId(`seg${s}spc`).value);
|
||||
let ofs = parseInt(gId(`seg${s}of` ).value);
|
||||
obj.seg.grp = grp;
|
||||
obj.seg.spc = spc;
|
||||
obj.seg.of = ofs;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<title>2D Set-up</title>
|
||||
<script>
|
||||
var d=document;
|
||||
var loc = false, locip;
|
||||
var loc = false, locip;
|
||||
var maxPanels=64;
|
||||
var ctx = null; // WLEDMM
|
||||
var ledIndex = 0; // WLEDMM
|
||||
@@ -38,15 +38,15 @@
|
||||
});
|
||||
}
|
||||
function S() {
|
||||
if (window.location.protocol == "file:") {
|
||||
loc = true;
|
||||
locip = localStorage.getItem('locIp');
|
||||
if (!locip) {
|
||||
locip = prompt("File Mode. Please enter WLED IP!");
|
||||
localStorage.setItem('locIp', locip);
|
||||
}
|
||||
}
|
||||
var url = (loc?`http://${locip}`:'') + '/settings/s.js?p=10';
|
||||
if (window.location.protocol == "file:") {
|
||||
loc = true;
|
||||
locip = localStorage.getItem('locIp');
|
||||
if (!locip) {
|
||||
locip = prompt("File Mode. Please enter WLED IP!");
|
||||
localStorage.setItem('locIp', locip);
|
||||
}
|
||||
}
|
||||
var url = (loc?`http://${locip}`:'') + '/settings/s.js?p=10';
|
||||
loadJS(url, false); // If we set async false, file is loaded and executed, then next statement is processed
|
||||
}
|
||||
|
||||
@@ -91,12 +91,12 @@ Y:<input id="P${i}Y" name="P${i}Y" type="number" min="0" max="256" value="0" oni
|
||||
p.insertAdjacentHTML("beforeend", b);
|
||||
}
|
||||
|
||||
function remPanel() {
|
||||
function remPanel() {
|
||||
let p = gId("panels").children;
|
||||
var i = p.length;
|
||||
if (i <= 1) return;
|
||||
p[i-1].remove();
|
||||
}
|
||||
var i = p.length;
|
||||
if (i <= 1) return;
|
||||
p[i-1].remove();
|
||||
}
|
||||
|
||||
function resetPanels() {
|
||||
d.Sf.MPC.value = 1;
|
||||
@@ -350,7 +350,7 @@ Y:<input id="P${i}Y" name="P${i}Y" type="number" min="0" max="256" value="0" oni
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||
</div>
|
||||
<h2>2D setup</h2>
|
||||
Strip or panel:
|
||||
Strip or panel:
|
||||
<select id="somp" name="SOMP" onchange="resetPanels();addPanels();UI();" >
|
||||
<option value="0">1D Strip</option>
|
||||
<option value="1">2D Matrix</option>
|
||||
|
||||
@@ -1,72 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=500">
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
|
||||
<meta charset="utf-8">
|
||||
<title>DMX Settings</title>
|
||||
<script>
|
||||
var d=document;
|
||||
var loc = false, locip;
|
||||
function H(){window.open("https://github.com/Aircoookie/WLED/wiki/DMX");}
|
||||
function B(){window.history.back();}
|
||||
function GCH(num) {
|
||||
d.getElementById('dmxchannels').innerHTML += "";
|
||||
for (i=0;i<num;i++) {
|
||||
d.getElementById('dmxchannels').innerHTML += "<span id=CH" + (i+1) + "s >Channel " + (i+1) + ": <select name=CH" + (i+1) + " id=\"CH" + (i+1) + "\"><option value=0>Set to 0</option><option value=1>Red</option><option value=2>Green</option><option value=3>Blue</option><option value=4>White</option><option value=5>Shutter (Brightness)</option><option value=6>Set to 255</option></select></span><br />\n";
|
||||
}
|
||||
}
|
||||
function mMap(){
|
||||
numCh=document.Sf.CN.value;
|
||||
numGap=document.Sf.CG.value;
|
||||
if (parseInt(numCh)>parseInt(numGap)) {
|
||||
d.getElementById("gapwarning").style.display="block";
|
||||
} else {
|
||||
d.getElementById("gapwarning").style.display="none";
|
||||
}
|
||||
for (i=0;i<15;i++) {
|
||||
if (i>=numCh) {
|
||||
d.getElementById("CH"+(i+1) + "s").style.opacity = "0.5";
|
||||
d.getElementById("CH"+(i+1)).disabled = true;
|
||||
|
||||
} else {
|
||||
d.getElementById("CH"+(i+1) + "s").style.opacity = "1";
|
||||
d.getElementById("CH"+(i+1)).disabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
||||
function loadJS(FILE_URL, async = true) {
|
||||
let scE = d.createElement("script");
|
||||
scE.setAttribute("src", FILE_URL);
|
||||
scE.setAttribute("type", "text/javascript");
|
||||
scE.setAttribute("async", async);
|
||||
d.body.appendChild(scE);
|
||||
// success event
|
||||
scE.addEventListener("load", () => {
|
||||
//console.log("File loaded");
|
||||
GCH(15);GetV();mMap();
|
||||
});
|
||||
// error event
|
||||
scE.addEventListener("error", (ev) => {
|
||||
console.log("Error on loading file", ev);
|
||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
||||
});
|
||||
}
|
||||
function S(){
|
||||
if (window.location.protocol == "file:") {
|
||||
loc = true;
|
||||
locip = localStorage.getItem('locIp');
|
||||
if (!locip) {
|
||||
locip = prompt("File Mode. Please enter WLED IP!");
|
||||
localStorage.setItem('locIp', locip);
|
||||
}
|
||||
}
|
||||
var url = (loc?`http://${locip}`:'') + '/settings/s.js?p=7';
|
||||
loadJS(url, false); // If we set async false, file is loaded and executed, then next statement is processed
|
||||
}
|
||||
</script>
|
||||
<style>@import url("style.css");</style>
|
||||
<meta name="viewport" content="width=500">
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
|
||||
<meta charset="utf-8">
|
||||
<title>DMX Settings</title>
|
||||
<script>
|
||||
var d=document;
|
||||
var loc = false, locip;
|
||||
function H(){window.open("https://github.com/Aircoookie/WLED/wiki/DMX");}
|
||||
function B(){window.history.back();}
|
||||
function GCH(num) {
|
||||
d.getElementById('dmxchannels').innerHTML += "";
|
||||
for (i=0;i<num;i++) {
|
||||
d.getElementById('dmxchannels').innerHTML += "<span id=CH" + (i+1) + "s >Channel " + (i+1) + ": <select name=CH" + (i+1) + " id=\"CH" + (i+1) + "\"><option value=0>Set to 0</option><option value=1>Red</option><option value=2>Green</option><option value=3>Blue</option><option value=4>White</option><option value=5>Shutter (Brightness)</option><option value=6>Set to 255</option></select></span><br />\n";
|
||||
}
|
||||
}
|
||||
function mMap(){
|
||||
numCh=document.Sf.CN.value;
|
||||
numGap=document.Sf.CG.value;
|
||||
if (parseInt(numCh)>parseInt(numGap)) {
|
||||
d.getElementById("gapwarning").style.display="block";
|
||||
} else {
|
||||
d.getElementById("gapwarning").style.display="none";
|
||||
}
|
||||
for (i=0;i<15;i++) {
|
||||
if (i>=numCh) {
|
||||
d.getElementById("CH"+(i+1) + "s").style.opacity = "0.5";
|
||||
d.getElementById("CH"+(i+1)).disabled = true;
|
||||
|
||||
} else {
|
||||
d.getElementById("CH"+(i+1) + "s").style.opacity = "1";
|
||||
d.getElementById("CH"+(i+1)).disabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
||||
function loadJS(FILE_URL, async = true) {
|
||||
let scE = d.createElement("script");
|
||||
scE.setAttribute("src", FILE_URL);
|
||||
scE.setAttribute("type", "text/javascript");
|
||||
scE.setAttribute("async", async);
|
||||
d.body.appendChild(scE);
|
||||
// success event
|
||||
scE.addEventListener("load", () => {
|
||||
//console.log("File loaded");
|
||||
GCH(15);GetV();mMap();
|
||||
});
|
||||
// error event
|
||||
scE.addEventListener("error", (ev) => {
|
||||
console.log("Error on loading file", ev);
|
||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
||||
});
|
||||
}
|
||||
function S(){
|
||||
if (window.location.protocol == "file:") {
|
||||
loc = true;
|
||||
locip = localStorage.getItem('locIp');
|
||||
if (!locip) {
|
||||
locip = prompt("File Mode. Please enter WLED IP!");
|
||||
localStorage.setItem('locIp', locip);
|
||||
}
|
||||
}
|
||||
var url = (loc?`http://${locip}`:'') + '/settings/s.js?p=7';
|
||||
loadJS(url, false); // If we set async false, file is loaded and executed, then next statement is processed
|
||||
}
|
||||
</script>
|
||||
<style>@import url("style.css");</style>
|
||||
</head>
|
||||
<body onload="S()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,7 @@
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<h2>Please enter settings PIN code</h2>
|
||||
<input type="password" name="PIN" size="4" maxlength="4" minlength="4" pattern="[0-9]*" inputmode="numeric" autofocus>
|
||||
<hr>
|
||||
<hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Submit</button>
|
||||
</form>
|
||||
</body>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
req.send(formData);
|
||||
fO.value = '';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function checkNum(o) {
|
||||
const specialkeys = ["Backspace", "Tab", "Enter", "Shift", "Control", "Alt", "Pause", "CapsLock", "Escape", "Space", "PageUp", "PageDown", "End", "Home", "ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown", "Insert", "Delete"];
|
||||
// true if key is a number or a special key
|
||||
|
||||
@@ -1,76 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=500">
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
|
||||
<meta charset="utf-8">
|
||||
<title>Sync Settings</title>
|
||||
<script>var d=document;
|
||||
var loc = false, locip;
|
||||
function gId(s){return d.getElementById(s);}
|
||||
function toggle(el){gId(el).classList.toggle("hide"); gId('No'+el).classList.toggle("hide");}
|
||||
function hideNoDMX(){gId("dmxOnOff2").style.display="none";}
|
||||
function hideNoLOX(){gId("loxOnOff2").style.display="none";}
|
||||
function H(){window.open("https://mm.kno.wled.ge/interfaces/udp-notifier/");}
|
||||
function B(){window.open("/settings","_self");}
|
||||
function adj(){if (d.Sf.DI.value == 6454) {if (d.Sf.EU.value == 1) d.Sf.EU.value = 0;}
|
||||
else if (d.Sf.DI.value == 5568) {if (d.Sf.DA.value == 0) d.Sf.DA.value = 1; if (d.Sf.EU.value == 0) d.Sf.EU.value = 1;} }
|
||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
||||
function loadJS(FILE_URL, async = true) {
|
||||
let scE = d.createElement("script");
|
||||
scE.setAttribute("src", FILE_URL);
|
||||
scE.setAttribute("type", "text/javascript");
|
||||
scE.setAttribute("async", async);
|
||||
d.body.appendChild(scE);
|
||||
// success event
|
||||
scE.addEventListener("load", () => {
|
||||
//console.log("File loaded");
|
||||
GetV();SetVal();
|
||||
});
|
||||
// error event
|
||||
scE.addEventListener("error", (ev) => {
|
||||
console.log("Error on loading file", ev);
|
||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
||||
});
|
||||
}
|
||||
function FC()
|
||||
{
|
||||
for(j=0;j<8;j++)
|
||||
{
|
||||
gId("G"+(j+1)).checked=gId("GS").value>>j&1;
|
||||
gId("R"+(j+1)).checked=gId("GR").value>>j&1;
|
||||
}
|
||||
}
|
||||
function GC()
|
||||
{
|
||||
var a=0, b=0;
|
||||
<meta name="viewport" content="width=500">
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
|
||||
<meta charset="utf-8">
|
||||
<title>Sync Settings</title>
|
||||
<script>var d=document;
|
||||
var loc = false, locip;
|
||||
function gId(s){return d.getElementById(s);}
|
||||
function toggle(el){gId(el).classList.toggle("hide"); gId('No'+el).classList.toggle("hide");}
|
||||
function hideNoDMX(){gId("dmxOnOff2").style.display="none";} //WLEDMM
|
||||
function hideNoLOX(){gId("loxOnOff2").style.display="none";} //WLEDMM
|
||||
function H(){window.open("https://mm.kno.wled.ge/interfaces/udp-notifier/");}
|
||||
function B(){window.open("/settings","_self");}
|
||||
function adj(){if (d.Sf.DI.value == 6454) {if (d.Sf.EU.value == 1) d.Sf.EU.value = 0;}
|
||||
else if (d.Sf.DI.value == 5568) {if (d.Sf.DA.value == 0) d.Sf.DA.value = 1; if (d.Sf.EU.value == 0) d.Sf.EU.value = 1;} }
|
||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
||||
function loadJS(FILE_URL, async = true) {
|
||||
let scE = d.createElement("script");
|
||||
scE.setAttribute("src", FILE_URL);
|
||||
scE.setAttribute("type", "text/javascript");
|
||||
scE.setAttribute("async", async);
|
||||
d.body.appendChild(scE);
|
||||
// success event
|
||||
scE.addEventListener("load", () => {
|
||||
//console.log("File loaded");
|
||||
GetV();SetVal();
|
||||
});
|
||||
// error event
|
||||
scE.addEventListener("error", (ev) => {
|
||||
console.log("Error on loading file", ev);
|
||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
||||
});
|
||||
}
|
||||
function FC()
|
||||
{
|
||||
for(j=0;j<8;j++)
|
||||
{
|
||||
gId("G"+(j+1)).checked=gId("GS").value>>j&1;
|
||||
gId("R"+(j+1)).checked=gId("GR").value>>j&1;
|
||||
}
|
||||
}
|
||||
function GC()
|
||||
{
|
||||
var a=0, b=0;
|
||||
|
||||
var m=1;
|
||||
for(j=0;j<8;j++)
|
||||
{
|
||||
a+=gId("G"+(j+1)).checked*m;
|
||||
b+=gId("R"+(j+1)).checked*m;
|
||||
m*=2;
|
||||
}
|
||||
gId("GS").value=a;
|
||||
gId("GR").value=b;
|
||||
}
|
||||
function SP(){var p = d.Sf.DI.value; gId("xp").style.display = (p > 0)?"none":"block"; if (p > 0) d.Sf.EP.value = p;}
|
||||
function SetVal(){switch(parseInt(d.Sf.EP.value)){case 5568: d.Sf.DI.value = 5568; break; case 6454: d.Sf.DI.value = 6454; break; case 4048: d.Sf.DI.value = 4048; break; }; SP();FC();}
|
||||
function S(){
|
||||
if (window.location.protocol == "file:") {
|
||||
loc = true;
|
||||
locip = localStorage.getItem('locIp');
|
||||
if (!locip) {
|
||||
locip = prompt("File Mode. Please enter WLED IP!");
|
||||
localStorage.setItem('locIp', locip);
|
||||
}
|
||||
var m=1;
|
||||
for(j=0;j<8;j++)
|
||||
{
|
||||
a+=gId("G"+(j+1)).checked*m;
|
||||
b+=gId("R"+(j+1)).checked*m;
|
||||
m*=2;
|
||||
}
|
||||
gId("GS").value=a;
|
||||
gId("GR").value=b;
|
||||
}
|
||||
function SP(){var p = d.Sf.DI.value; gId("xp").style.display = (p > 0)?"none":"block"; if (p > 0) d.Sf.EP.value = p;}
|
||||
function SetVal(){switch(parseInt(d.Sf.EP.value)){case 5568: d.Sf.DI.value = 5568; break; case 6454: d.Sf.DI.value = 6454; break; case 4048: d.Sf.DI.value = 4048; break; }; SP();FC();}
|
||||
function S(){
|
||||
if (window.location.protocol == "file:") {
|
||||
loc = true;
|
||||
locip = localStorage.getItem('locIp');
|
||||
if (!locip) {
|
||||
locip = prompt("File Mode. Please enter WLED IP!");
|
||||
localStorage.setItem('locIp', locip);
|
||||
}
|
||||
var url = (loc?`http://${locip}`:'') + '/settings/s.js?p=4';
|
||||
loadJS(url, false); // If we set async false, file is loaded and executed, then next statement is processed
|
||||
}
|
||||
</script>
|
||||
<style>@import url("style.css");</style>
|
||||
}
|
||||
var url = (loc?`http://${locip}`:'') + '/settings/s.js?p=4';
|
||||
loadJS(url, false); // If we set async false, file is loaded and executed, then next statement is processed
|
||||
}
|
||||
</script>
|
||||
<style>@import url("style.css");</style>
|
||||
</head>
|
||||
<body onload="S()">
|
||||
<form id="form_s" name="Sf" method="post" onsubmit="GC()">
|
||||
@@ -86,39 +86,39 @@ UDP Port: <input name="UP" type="number" min="1" max="65535" class="d5" required
|
||||
<input name="GS" id="GS" type="number" style="display: none;"><!-- hidden inputs for bitwise group checkboxes -->
|
||||
<input name="GR" id="GR" type="number" style="display: none;">
|
||||
<table style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>1</td>
|
||||
<td>2</td>
|
||||
<td>3</td>
|
||||
<td>4</td>
|
||||
<td>5</td>
|
||||
<td>6</td>
|
||||
<td>7</td>
|
||||
<td>8</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Send:</td>
|
||||
<td><input type="checkbox" id="G1" name="G1"></td>
|
||||
<td><input type="checkbox" id="G2" name="G2"></td>
|
||||
<td><input type="checkbox" id="G3" name="G3"></td>
|
||||
<td><input type="checkbox" id="G4" name="G4"></td>
|
||||
<td><input type="checkbox" id="G5" name="G5"></td>
|
||||
<td><input type="checkbox" id="G6" name="G6"></td>
|
||||
<td><input type="checkbox" id="G7" name="G7"></td>
|
||||
<td><input type="checkbox" id="G8" name="G8"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Receive:</td>
|
||||
<td><input type="checkbox" id="R1" name="R1"></td>
|
||||
<td><input type="checkbox" id="R2" name="R2"></td>
|
||||
<td><input type="checkbox" id="R3" name="R3"></td>
|
||||
<td><input type="checkbox" id="R4" name="R4"></td>
|
||||
<td><input type="checkbox" id="R5" name="R5"></td>
|
||||
<td><input type="checkbox" id="R6" name="R6"></td>
|
||||
<td><input type="checkbox" id="R7" name="R7"></td>
|
||||
<td><input type="checkbox" id="R8" name="R8"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>1</td>
|
||||
<td>2</td>
|
||||
<td>3</td>
|
||||
<td>4</td>
|
||||
<td>5</td>
|
||||
<td>6</td>
|
||||
<td>7</td>
|
||||
<td>8</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Send:</td>
|
||||
<td><input type="checkbox" id="G1" name="G1"></td>
|
||||
<td><input type="checkbox" id="G2" name="G2"></td>
|
||||
<td><input type="checkbox" id="G3" name="G3"></td>
|
||||
<td><input type="checkbox" id="G4" name="G4"></td>
|
||||
<td><input type="checkbox" id="G5" name="G5"></td>
|
||||
<td><input type="checkbox" id="G6" name="G6"></td>
|
||||
<td><input type="checkbox" id="G7" name="G7"></td>
|
||||
<td><input type="checkbox" id="G8" name="G8"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Receive:</td>
|
||||
<td><input type="checkbox" id="R1" name="R1"></td>
|
||||
<td><input type="checkbox" id="R2" name="R2"></td>
|
||||
<td><input type="checkbox" id="R3" name="R3"></td>
|
||||
<td><input type="checkbox" id="R4" name="R4"></td>
|
||||
<td><input type="checkbox" id="R5" name="R5"></td>
|
||||
<td><input type="checkbox" id="R6" name="R6"></td>
|
||||
<td><input type="checkbox" id="R7" name="R7"></td>
|
||||
<td><input type="checkbox" id="R8" name="R8"></td>
|
||||
</tr>
|
||||
</table><br>
|
||||
Receive: <nowrap><input type="checkbox" name="RB">Brightness,</nowrap> <nowrap><input type="checkbox" name="RC">Color,</nowrap> <nowrap>and <input type="checkbox" name="RX">Effects</nowrap><br>
|
||||
<input type="checkbox" name="SO"> Segment options, <input type="checkbox" name="SG"> bounds<br>
|
||||
@@ -170,13 +170,13 @@ Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
|
||||
Force max brightness: <input type="checkbox" name="FB"><br>
|
||||
Disable realtime gamma correction: <input type="checkbox" name="RG"><br>
|
||||
Realtime LED offset: <input name="WO" type="number" min="-255" max="255" required>
|
||||
<div id="dmxOnOff2">
|
||||
<div id="dmxOnOff2"> <!--WLEDMM-->
|
||||
<br><em style="color:darkorange">This firmware build does not include DMX output support. <br></em>
|
||||
</div>
|
||||
<hr class="sml">
|
||||
<h3>Alexa Voice Assistant</h3>
|
||||
<div id="NoAlexa" class="hide">
|
||||
<em style="color:#fa0;">This firmware build does not include Alexa support.<br></em><br>
|
||||
<em style="color:#fa0;">This firmware build does not include Alexa support.<br></em><br>
|
||||
</div>
|
||||
<div id="Alexa">
|
||||
Emulate Alexa device: <input type="checkbox" name="AL"><br>
|
||||
@@ -192,7 +192,7 @@ For best results, only use one of these services at a time.<br>
|
||||
<hr class="sml">
|
||||
<h3>Blynk</h3>
|
||||
<div id="NoBlynk" class="hide">
|
||||
<em style="color:#fa0;">This firmware build does not include Blynk support.<br></em>
|
||||
<em style="color:#fa0;">This firmware build does not include Blynk support.<br></em>
|
||||
</div>
|
||||
<div id="Blynk">
|
||||
Host: <input type="text" name="BH" maxlength="32">
|
||||
@@ -202,7 +202,7 @@ Device Auth token: <input name="BK" maxlength="33"><br>
|
||||
</div>
|
||||
<h3>MQTT</h3>
|
||||
<div id="NoMQTT" class="hide">
|
||||
<em style="color:#fa0;">This firmware build does not include MQTT support.<br></em>
|
||||
<em style="color:#fa0;">This firmware build does not include MQTT support.<br></em>
|
||||
</div>
|
||||
<div id="MQTT">
|
||||
Enable MQTT: <input type="checkbox" name="MQ"><br>
|
||||
@@ -220,7 +220,7 @@ Publish on button press: <input type="checkbox" name="BM"><br>
|
||||
</div>
|
||||
<h3>Philips Hue</h3>
|
||||
<div id="NoHue" class="hide">
|
||||
<em style="color:#fa0;">This firmware build does not include Philips Hue support.<br></em>
|
||||
<em style="color:#fa0;">This firmware build does not include Philips Hue support.<br></em>
|
||||
</div>
|
||||
<div id="Hue">
|
||||
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
||||
@@ -235,7 +235,7 @@ Hue Bridge IP:<br>
|
||||
(when first connecting)<br>
|
||||
</div>
|
||||
Hue status: <span class="sip"> Disabled in this build </span>
|
||||
<div id="loxOnOff2">
|
||||
<div id="loxOnOff2"> <!--WLEDMM-->>
|
||||
<br><em style="color:darkorange">This firmware build does not include Loxone Lighting support. <br></em>
|
||||
</div>
|
||||
<h3>Serial</h3>
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<meta charset="utf-8">
|
||||
<title>Time Settings</title>
|
||||
<script>
|
||||
var d=document;
|
||||
var loc = false, locip;
|
||||
var d=document;
|
||||
var loc = false, locip;
|
||||
var el=false;
|
||||
var ms=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
|
||||
function H() { window.open("https://mm.kno.wled.ge/features/settings/#time-settings"); }
|
||||
@@ -156,7 +156,7 @@
|
||||
</div>
|
||||
<h2>Time setup</h2>
|
||||
Get time from NTP server: <input type="checkbox" name="NT"><br>
|
||||
<input type="text" name="NS" maxlength="32"><br>
|
||||
<input type="text" name="NS" maxlength="32"><br>
|
||||
Use 24h format: <input type="checkbox" name="CF"><br>
|
||||
Time zone:
|
||||
<select name="TZ">
|
||||
|
||||
@@ -6,234 +6,234 @@
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
|
||||
<title>UI Settings</title>
|
||||
<script>
|
||||
var d = document;
|
||||
var loc = false, locip;
|
||||
var initial_ds, initial_st, initial_su;
|
||||
var sett = null;
|
||||
var l = {
|
||||
"comp":{
|
||||
"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": "Set segment length instead of stop LED",
|
||||
"segpwr": "Hide segment power & brightness",
|
||||
"segexp" : "Always expand first segment",
|
||||
"css": "Enable custom CSS",
|
||||
"hdays": "Enable custom Holidays list"
|
||||
var d = document;
|
||||
var loc = false, locip;
|
||||
var initial_ds, initial_st, initial_su;
|
||||
var sett = null;
|
||||
var l = {
|
||||
"comp":{
|
||||
"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": "Set segment length instead of stop LED",
|
||||
"segpwr": "Hide segment power & brightness",
|
||||
"segexp" : "Always expand first segment",
|
||||
"css": "Enable custom CSS",
|
||||
"hdays": "Enable custom Holidays list"
|
||||
},
|
||||
"theme":{
|
||||
"alpha": {
|
||||
"bg":"Background opacity",
|
||||
"tab":"Button opacity"
|
||||
},
|
||||
"theme":{
|
||||
"alpha": {
|
||||
"bg":"Background opacity",
|
||||
"tab":"Button opacity"
|
||||
},
|
||||
"bg":{
|
||||
"url":"BG image URL",
|
||||
"random":"Random BG image"
|
||||
},
|
||||
"color":{
|
||||
"bg":"BG HEX color"
|
||||
}
|
||||
"bg":{
|
||||
"url":"BG image URL",
|
||||
"random":"Random BG image"
|
||||
},
|
||||
"color":{
|
||||
"bg":"BG HEX color"
|
||||
}
|
||||
};
|
||||
function gId(s) { return d.getElementById(s); }
|
||||
function toggle(el) { gId(el).classList.toggle("hide"); gId('No'+el).classList.toggle("hide"); }
|
||||
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;
|
||||
};
|
||||
function gId(s) { return d.getElementById(s); }
|
||||
function toggle(el) { gId(el).classList.toggle("hide"); gId('No'+el).classList.toggle("hide"); }
|
||||
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];
|
||||
}
|
||||
var timeout;
|
||||
function showToast(text, error = false)
|
||||
tar[pList[len-1]] = val;
|
||||
}
|
||||
var timeout;
|
||||
function showToast(text, error = false)
|
||||
{
|
||||
var x = gId("toast");
|
||||
x.innerHTML = text;
|
||||
x.classList.add(error ? "error":"show");
|
||||
clearTimeout(timeout);
|
||||
x.style.animation = 'none';
|
||||
timeout = setTimeout(function(){ x.classList.remove("show"); }, 2900);
|
||||
}
|
||||
function addRec(s, path = "", label = null)
|
||||
{
|
||||
var str = "";
|
||||
for (i in s)
|
||||
{
|
||||
var x = gId("toast");
|
||||
x.innerHTML = text;
|
||||
x.classList.add(error ? "error":"show");
|
||||
clearTimeout(timeout);
|
||||
x.style.animation = 'none';
|
||||
timeout = setTimeout(function(){ x.classList.remove("show"); }, 2900);
|
||||
}
|
||||
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;
|
||||
}
|
||||
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 {
|
||||
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>`;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function genForm(s) {
|
||||
var str = "";
|
||||
str = addRec(s,"",l);
|
||||
|
||||
gId('gen').innerHTML = 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 + ")";
|
||||
}
|
||||
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');
|
||||
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 cLS()
|
||||
{
|
||||
localStorage.removeItem('wledP');
|
||||
localStorage.removeItem('wledPmt');
|
||||
localStorage.removeItem('wledPalx');
|
||||
showToast("Cleared.");
|
||||
}
|
||||
|
||||
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.SU.checked != initial_su) d.Sf.submit();
|
||||
}
|
||||
|
||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
||||
function loadJS(FILE_URL, async = true) {
|
||||
let scE = d.createElement("script");
|
||||
scE.setAttribute("src", FILE_URL);
|
||||
scE.setAttribute("type", "text/javascript");
|
||||
scE.setAttribute("async", async);
|
||||
d.body.appendChild(scE);
|
||||
// success event
|
||||
scE.addEventListener("load", () => {
|
||||
//console.log("File loaded");
|
||||
GetV();
|
||||
initial_ds = d.Sf.DS.value;
|
||||
initial_st = d.Sf.ST.checked;
|
||||
initial_su = d.Sf.SU.checked;
|
||||
GetLS();
|
||||
});
|
||||
// error event
|
||||
scE.addEventListener("error", (ev) => {
|
||||
console.log("Error on loading file", ev);
|
||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
||||
});
|
||||
}
|
||||
function S()
|
||||
{
|
||||
if (window.location.protocol == "file:") {
|
||||
loc = true;
|
||||
locip = localStorage.getItem('locIp');
|
||||
if (!locip) {
|
||||
locip = prompt("File Mode. Please enter WLED IP!");
|
||||
localStorage.setItem('locIp', locip);
|
||||
}
|
||||
}
|
||||
var url = (loc?`http://${locip}`:'') + '/settings/s.js?p=3';
|
||||
loadJS(url, false); // If we set async false, file is loaded and executed, then next statement is processed
|
||||
}
|
||||
function H() { window.open("https://mm.kno.wled.ge/features/settings/#user-interface-settings"); }
|
||||
function B() { window.open("/settings","_self"); }
|
||||
function UI()
|
||||
{
|
||||
gId('idonthateyou').style.display = (gId('dm').checked) ? 'inline':'none';
|
||||
var f = gId('theme_base');
|
||||
if (f) f.value = (gId('dm').checked) ? 'light':'dark';
|
||||
}
|
||||
|
||||
function cLS()
|
||||
{
|
||||
localStorage.removeItem('wledP');
|
||||
localStorage.removeItem('wledPmt');
|
||||
localStorage.removeItem('wledPalx');
|
||||
showToast("Cleared.");
|
||||
// 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 Save() {
|
||||
SetLS();
|
||||
if (d.Sf.DS.value != initial_ds || d.Sf.ST.checked != initial_st || d.Sf.SU.checked != initial_su) d.Sf.submit();
|
||||
}
|
||||
|
||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
||||
function loadJS(FILE_URL, async = true) {
|
||||
let scE = d.createElement("script");
|
||||
scE.setAttribute("src", FILE_URL);
|
||||
scE.setAttribute("type", "text/javascript");
|
||||
scE.setAttribute("async", async);
|
||||
d.body.appendChild(scE);
|
||||
// success event
|
||||
scE.addEventListener("load", () => {
|
||||
//console.log("File loaded");
|
||||
GetV();
|
||||
initial_ds = d.Sf.DS.value;
|
||||
initial_st = d.Sf.ST.checked;
|
||||
initial_su = d.Sf.SU.checked;
|
||||
GetLS();
|
||||
});
|
||||
// error event
|
||||
scE.addEventListener("error", (ev) => {
|
||||
console.log("Error on loading file", ev);
|
||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
||||
});
|
||||
}
|
||||
function S()
|
||||
{
|
||||
if (window.location.protocol == "file:") {
|
||||
loc = true;
|
||||
locip = localStorage.getItem('locIp');
|
||||
if (!locip) {
|
||||
locip = prompt("File Mode. Please enter WLED IP!");
|
||||
localStorage.setItem('locIp', locip);
|
||||
}
|
||||
}
|
||||
var url = (loc?`http://${locip}`:'') + '/settings/s.js?p=3';
|
||||
loadJS(url, false); // If we set async false, file is loaded and executed, then next statement is processed
|
||||
}
|
||||
function H() { window.open("https://mm.kno.wled.ge/features/settings/#user-interface-settings"); }
|
||||
function B() { window.open("/settings","_self"); }
|
||||
function UI()
|
||||
{
|
||||
gId('idonthateyou').style.display = (gId('dm').checked) ? 'inline':'none';
|
||||
var f = gId('theme_base');
|
||||
if (f) f.value = (gId('dm').checked) ? 'light':'dark';
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
function uploadFile(fO,name) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400)});
|
||||
req.addEventListener('error', function(e){showToast(e.stack,true);});
|
||||
req.open("POST", "/upload");
|
||||
var formData = new FormData();
|
||||
formData.append("data", fO.files[0], name);
|
||||
req.send(formData);
|
||||
fO.value = '';
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
function uploadFile(fO,name) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400)});
|
||||
req.addEventListener('error', function(e){showToast(e.stack,true);});
|
||||
req.open("POST", "/upload");
|
||||
var formData = new FormData();
|
||||
formData.append("data", fO.files[0], name);
|
||||
req.send(formData);
|
||||
fO.value = '';
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
<style>@import url("style.css");</style>
|
||||
</head>
|
||||
|
||||
Reference in New Issue
Block a user