mirror of
https://github.com/wled/WLED.git
synced 2025-04-25 07:17:18 +00:00
Introduce common.js in settings pages
This commit is contained in:
parent
ac8f919304
commit
ceed494cf7
@ -116,7 +116,8 @@ async function minify(str, type = "plain") {
|
|||||||
} else if (type == "css-minify") {
|
} else if (type == "css-minify") {
|
||||||
return new CleanCSS({}).minify(str).styles;
|
return new CleanCSS({}).minify(str).styles;
|
||||||
} else if (type == "js-minify") {
|
} else if (type == "js-minify") {
|
||||||
return await minifyHtml('<script>' + str + '</script>', options).replace(/<[\/]*script>/g, '');
|
let js = await minifyHtml('<script>' + str + '</script>', options);
|
||||||
|
return js.replace(/<[\/]*script>/g, '');
|
||||||
} else if (type == "html-minify") {
|
} else if (type == "html-minify") {
|
||||||
return await minifyHtml(str, options);
|
return await minifyHtml(str, options);
|
||||||
}
|
}
|
||||||
@ -252,6 +253,12 @@ writeChunks(
|
|||||||
str
|
str
|
||||||
.replace("%%", "%")
|
.replace("%%", "%")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
file: "common.js",
|
||||||
|
name: "JS_common",
|
||||||
|
method: "gzip",
|
||||||
|
filter: "js-minify",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
file: "settings.htm",
|
file: "settings.htm",
|
||||||
name: "PAGE_settings",
|
name: "PAGE_settings",
|
||||||
|
118
wled00/data/common.js
Normal file
118
wled00/data/common.js
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
var d=document;
|
||||||
|
var loc = false, locip, locproto = "http:";
|
||||||
|
|
||||||
|
function H(pg="") { window.open("https://kno.wled.ge/"+pg); }
|
||||||
|
function GH() { window.open("https://github.com/Aircoookie/WLED"); }
|
||||||
|
function gId(c) { return d.getElementById(c); } // getElementById
|
||||||
|
function cE(e) { return d.createElement(e); } // createElement
|
||||||
|
function gEBCN(c) { return d.getElementsByClassName(c); } // getElementsByClassName
|
||||||
|
function gN(s) { return d.getElementsByName(s)[0]; } // getElementsByName
|
||||||
|
function isE(o) { return Object.keys(o).length === 0; } // isEmpty
|
||||||
|
function isO(i) { return (i && typeof i === 'object' && !Array.isArray(i)); } // isObject
|
||||||
|
function isN(n) { return !isNaN(parseFloat(n)) && isFinite(n); } // isNumber
|
||||||
|
// https://stackoverflow.com/questions/3885817/how-do-i-check-that-a-number-is-float-or-integer
|
||||||
|
function isF(n) { return n === +n && n !== (n|0); } // isFloat
|
||||||
|
function isI(n) { return n === +n && n === (n|0); } // isInteger
|
||||||
|
function toggle(el) { gId(el).classList.toggle("hide"); gId('No'+el).classList.toggle("hide"); }
|
||||||
|
function tooltip(cont=null) {
|
||||||
|
d.querySelectorAll((cont?cont+" ":"")+"[title]").forEach((element)=>{
|
||||||
|
element.addEventListener("mouseover", ()=>{
|
||||||
|
// save title
|
||||||
|
element.setAttribute("data-title", element.getAttribute("title"));
|
||||||
|
const tooltip = d.createElement("span");
|
||||||
|
tooltip.className = "tooltip";
|
||||||
|
tooltip.textContent = element.getAttribute("title");
|
||||||
|
|
||||||
|
// prevent default title popup
|
||||||
|
element.removeAttribute("title");
|
||||||
|
|
||||||
|
let { top, left, width } = element.getBoundingClientRect();
|
||||||
|
|
||||||
|
d.body.appendChild(tooltip);
|
||||||
|
|
||||||
|
const { offsetHeight, offsetWidth } = tooltip;
|
||||||
|
|
||||||
|
const offset = element.classList.contains("sliderwrap") ? 4 : 10;
|
||||||
|
top -= offsetHeight + offset;
|
||||||
|
left += (width - offsetWidth) / 2;
|
||||||
|
|
||||||
|
tooltip.style.top = top + "px";
|
||||||
|
tooltip.style.left = left + "px";
|
||||||
|
tooltip.classList.add("visible");
|
||||||
|
});
|
||||||
|
|
||||||
|
element.addEventListener("mouseout", ()=>{
|
||||||
|
d.querySelectorAll('.tooltip').forEach((tooltip)=>{
|
||||||
|
tooltip.classList.remove("visible");
|
||||||
|
d.body.removeChild(tooltip);
|
||||||
|
});
|
||||||
|
// restore title
|
||||||
|
element.setAttribute("title", element.getAttribute("data-title"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
||||||
|
function loadJS(FILE_URL, async = true, preGetV = undefined, postGetV = undefined) {
|
||||||
|
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");
|
||||||
|
if (preGetV) preGetV();
|
||||||
|
GetV();
|
||||||
|
if (postGetV) postGetV();
|
||||||
|
});
|
||||||
|
// error event
|
||||||
|
scE.addEventListener("error", (ev) => {
|
||||||
|
console.log("Error on loading file", ev);
|
||||||
|
alert("Loading of configuration script failed.\nIncomplete page data!");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getLoc() {
|
||||||
|
let l = window.location;
|
||||||
|
if (l.protocol == "file:") {
|
||||||
|
loc = true;
|
||||||
|
locip = localStorage.getItem('locIp');
|
||||||
|
if (!locip) {
|
||||||
|
locip = prompt("File Mode. Please enter WLED IP!");
|
||||||
|
localStorage.setItem('locIp', locip);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// detect reverse proxy
|
||||||
|
let path = l.pathname;
|
||||||
|
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
|
||||||
|
if (paths.length > 1) paths.pop(); // remove subpage (or "settings")
|
||||||
|
if (paths.length > 0 && paths[paths.length-1]=="settings") paths.pop(); // remove "settings"
|
||||||
|
if (paths.length > 1) {
|
||||||
|
locproto = l.protocol;
|
||||||
|
loc = true;
|
||||||
|
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getURL(path) { return (loc ? locproto + "//" + locip : "") + path; }
|
||||||
|
function B() { window.open(getURL("/settings"),"_self"); }
|
||||||
|
var timeout;
|
||||||
|
function showToast(text, error = false) {
|
||||||
|
var x = gId("toast");
|
||||||
|
if (!x) return;
|
||||||
|
x.innerHTML = text;
|
||||||
|
x.className = error ? "error":"show";
|
||||||
|
clearTimeout(timeout);
|
||||||
|
x.style.animation = 'none';
|
||||||
|
timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900);
|
||||||
|
}
|
||||||
|
function uploadFile(fileObj, 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", fileObj.files[0], name);
|
||||||
|
req.send(formData);
|
||||||
|
fileObj.value = '';
|
||||||
|
return false;
|
||||||
|
}
|
@ -608,8 +608,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function generatePaletteDivs() {
|
function generatePaletteDivs() {
|
||||||
const palettesDiv = d.getElementById("palettes");
|
const palettesDiv = gId("palettes");
|
||||||
const staticPalettesDiv = d.getElementById("staticPalettes");
|
const staticPalettesDiv = gId("staticPalettes");
|
||||||
const paletteDivs = Array.from(palettesDiv.children).filter((child) => {
|
const paletteDivs = Array.from(palettesDiv.children).filter((child) => {
|
||||||
return child.id.match(/^palette\d$/); // match only elements with id starting with "palette" followed by a single digit
|
return child.id.match(/^palette\d$/); // match only elements with id starting with "palette" followed by a single digit
|
||||||
});
|
});
|
||||||
@ -620,25 +620,25 @@
|
|||||||
|
|
||||||
for (let i = 0; i < paletteArray.length; i++) {
|
for (let i = 0; i < paletteArray.length; i++) {
|
||||||
const palette = paletteArray[i];
|
const palette = paletteArray[i];
|
||||||
const paletteDiv = d.createElement("div");
|
const paletteDiv = cE("div");
|
||||||
paletteDiv.id = `palette${i}`;
|
paletteDiv.id = `palette${i}`;
|
||||||
paletteDiv.classList.add("palette");
|
paletteDiv.classList.add("palette");
|
||||||
const thisKey = Object.keys(palette)[0];
|
const thisKey = Object.keys(palette)[0];
|
||||||
paletteDiv.dataset.colarray = JSON.stringify(palette[thisKey]);
|
paletteDiv.dataset.colarray = JSON.stringify(palette[thisKey]);
|
||||||
|
|
||||||
const gradientDiv = d.createElement("div");
|
const gradientDiv = cE("div");
|
||||||
gradientDiv.id = `paletteGradient${i}`
|
gradientDiv.id = `paletteGradient${i}`
|
||||||
const buttonsDiv = d.createElement("div");
|
const buttonsDiv = cE("div");
|
||||||
buttonsDiv.id = `buttonsDiv${i}`;
|
buttonsDiv.id = `buttonsDiv${i}`;
|
||||||
buttonsDiv.classList.add("buttonsDiv")
|
buttonsDiv.classList.add("buttonsDiv")
|
||||||
|
|
||||||
const sendSpan = d.createElement("span");
|
const sendSpan = cE("span");
|
||||||
sendSpan.id = `sendSpan${i}`;
|
sendSpan.id = `sendSpan${i}`;
|
||||||
sendSpan.onclick = function() {initiateUpload(i)};
|
sendSpan.onclick = function() {initiateUpload(i)};
|
||||||
sendSpan.setAttribute('title', `Send current editor to slot ${i}`); // perhaps Save instead of Send?
|
sendSpan.setAttribute('title', `Send current editor to slot ${i}`); // perhaps Save instead of Send?
|
||||||
sendSpan.innerHTML = svgSave;
|
sendSpan.innerHTML = svgSave;
|
||||||
sendSpan.classList.add("sendSpan")
|
sendSpan.classList.add("sendSpan")
|
||||||
const editSpan = d.createElement("span");
|
const editSpan = cE("span");
|
||||||
editSpan.id = `editSpan${i}`;
|
editSpan.id = `editSpan${i}`;
|
||||||
editSpan.onclick = function() {loadForEdit(i)};
|
editSpan.onclick = function() {loadForEdit(i)};
|
||||||
editSpan.setAttribute('title', `Copy slot ${i} palette to editor`);
|
editSpan.setAttribute('title', `Copy slot ${i} palette to editor`);
|
||||||
|
@ -882,10 +882,8 @@
|
|||||||
hostnameLabel();
|
hostnameLabel();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function gId(id) {
|
function gId(e) {return d.getElementById(e);}
|
||||||
return d.getElementById(id);
|
function cE(e) {return d.createElement(e);}
|
||||||
}
|
|
||||||
|
|
||||||
function hostnameLabel() {
|
function hostnameLabel() {
|
||||||
const link = gId("wledEdit");
|
const link = gId("wledEdit");
|
||||||
link.href = WLED_URL + "/edit";
|
link.href = WLED_URL + "/edit";
|
||||||
@ -1675,7 +1673,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createCanvas(width, height) {
|
function createCanvas(width, height) {
|
||||||
const canvas = d.createElement("canvas");
|
const canvas = cE("canvas");
|
||||||
|
|
||||||
canvas.width = width;
|
canvas.width = width;
|
||||||
canvas.height = height;
|
canvas.height = height;
|
||||||
@ -1719,7 +1717,7 @@
|
|||||||
const blob = new Blob([text], { type: mimeType });
|
const blob = new Blob([text], { type: mimeType });
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
const anchorElement = d.createElement("a");
|
const anchorElement = cE("a");
|
||||||
anchorElement.href = url;
|
anchorElement.href = url;
|
||||||
anchorElement.download = `${filename}.${fileExtension}`;
|
anchorElement.download = `${filename}.${fileExtension}`;
|
||||||
|
|
||||||
@ -1790,7 +1788,7 @@
|
|||||||
hideElement = "preview"
|
hideElement = "preview"
|
||||||
) {
|
) {
|
||||||
const hide = gId(hideElement);
|
const hide = gId(hideElement);
|
||||||
const toast = d.createElement("div");
|
const toast = cE("div");
|
||||||
const wait = 100;
|
const wait = 100;
|
||||||
|
|
||||||
toast.style.animation = "fadeIn";
|
toast.style.animation = "fadeIn";
|
||||||
@ -1799,14 +1797,14 @@
|
|||||||
|
|
||||||
toast.classList.add("toast", type);
|
toast.classList.add("toast", type);
|
||||||
|
|
||||||
const body = d.createElement("span");
|
const body = cE("span");
|
||||||
body.classList.add("toast-body");
|
body.classList.add("toast-body");
|
||||||
|
|
||||||
body.textContent = message;
|
body.textContent = message;
|
||||||
|
|
||||||
toast.appendChild(body);
|
toast.appendChild(body);
|
||||||
|
|
||||||
const progress = d.createElement("div");
|
const progress = cE("div");
|
||||||
progress.classList.add("toast-progress");
|
progress.classList.add("toast-progress");
|
||||||
|
|
||||||
progress.style.animation = "progress";
|
progress.style.animation = "progress";
|
||||||
@ -1831,7 +1829,7 @@
|
|||||||
|
|
||||||
function carousel(id, images, delay = 3000) {
|
function carousel(id, images, delay = 3000) {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
const carousel = d.createElement("div");
|
const carousel = cE("div");
|
||||||
carousel.classList.add("carousel");
|
carousel.classList.add("carousel");
|
||||||
|
|
||||||
images.forEach((canvas, i) => {
|
images.forEach((canvas, i) => {
|
||||||
@ -1959,7 +1957,7 @@
|
|||||||
let errorElement = parent.querySelector(".error-message");
|
let errorElement = parent.querySelector(".error-message");
|
||||||
|
|
||||||
if (!errorElement) {
|
if (!errorElement) {
|
||||||
errorElement = d.createElement("div");
|
errorElement = cE("div");
|
||||||
errorElement.classList.add("error-message");
|
errorElement.classList.add("error-message");
|
||||||
parent.appendChild(errorElement);
|
parent.appendChild(errorElement);
|
||||||
}
|
}
|
||||||
|
@ -4,53 +4,12 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<title>WLED Settings</title>
|
<title>WLED Settings</title>
|
||||||
|
<script src="common.js" async type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
var d=document;
|
|
||||||
var loc = false, locip, locproto = "http:";
|
|
||||||
function gId(n){return d.getElementById(n);}
|
|
||||||
// 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();
|
|
||||||
});
|
|
||||||
// error event
|
|
||||||
scE.addEventListener("error", (ev) => {
|
|
||||||
console.log("Error on loading file", ev);
|
|
||||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function S() {
|
function S() {
|
||||||
let l = window.location;
|
getLoc();
|
||||||
if (l.protocol == "file:") {
|
|
||||||
loc = true;
|
|
||||||
locip = localStorage.getItem('locIp');
|
|
||||||
if (!locip) {
|
|
||||||
locip = prompt("File Mode. Please enter WLED IP!");
|
|
||||||
localStorage.setItem('locIp', locip);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// detect reverse proxy
|
|
||||||
let path = l.pathname;
|
|
||||||
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
|
|
||||||
if (paths.length > 1) {
|
|
||||||
paths.pop(); // remove "settings"
|
|
||||||
locproto = l.protocol;
|
|
||||||
loc = true;
|
|
||||||
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadJS(getURL('/settings/s.js?p=0'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
loadJS(getURL('/settings/s.js?p=0'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
||||||
}
|
}
|
||||||
function getURL(path) {
|
|
||||||
return (loc ? locproto + "//" + locip : "") + path;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
|
@ -4,62 +4,19 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<title>2D Set-up</title>
|
<title>2D Set-up</title>
|
||||||
|
<script src="common.js" async type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
var d=document;
|
|
||||||
var loc = false, locip, locproto = "http:";
|
|
||||||
var maxPanels=64;
|
var maxPanels=64;
|
||||||
var ctx = null; // WLEDMM
|
var ctx = null;
|
||||||
function H(){window.open("https://kno.wled.ge/features/2D");}
|
|
||||||
function B(){window.open(getURL("/settings"),"_self");}
|
|
||||||
function gId(n){return d.getElementById(n);}
|
|
||||||
function fS(){d.Sf.submit();} // <button type=submit> sometimes didn't work
|
function fS(){d.Sf.submit();} // <button type=submit> sometimes didn't work
|
||||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
function S() {
|
||||||
function loadJS(FILE_URL, async = true) {
|
getLoc();
|
||||||
let scE = d.createElement("script");
|
loadJS(getURL('/settings/s.js?p=10'), false, undefined, ()=>{
|
||||||
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();
|
|
||||||
UI();
|
UI();
|
||||||
Sf.MPC.setAttribute("max",maxPanels);
|
Sf.MPC.setAttribute("max",maxPanels);
|
||||||
});
|
}); // If we set async false, file is loaded and executed, then next statement is processed
|
||||||
// error event
|
|
||||||
scE.addEventListener("error", (ev) => {
|
|
||||||
console.log("Error on loading file", ev);
|
|
||||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function S() {
|
|
||||||
let l = window.location;
|
|
||||||
if (l.protocol == "file:") {
|
|
||||||
loc = true;
|
|
||||||
locip = localStorage.getItem('locIp');
|
|
||||||
if (!locip) {
|
|
||||||
locip = prompt("File Mode. Please enter WLED IP!");
|
|
||||||
localStorage.setItem('locIp', locip);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// detect reverse proxy
|
|
||||||
let path = l.pathname;
|
|
||||||
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
|
|
||||||
if (paths.length > 2) {
|
|
||||||
paths.pop(); // remove "2d"
|
|
||||||
paths.pop(); // remove "settings"
|
|
||||||
locproto = l.protocol;
|
|
||||||
loc = true;
|
|
||||||
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadJS(getURL('/settings/s.js?p=10'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
|
||||||
if (loc) d.Sf.action = getURL('/settings/2D');
|
if (loc) d.Sf.action = getURL('/settings/2D');
|
||||||
}
|
}
|
||||||
function getURL(path) {
|
|
||||||
return (loc ? locproto + "//" + locip : "") + path;
|
|
||||||
}
|
|
||||||
|
|
||||||
function UI() {
|
function UI() {
|
||||||
if (gId("somp").value === "0") {
|
if (gId("somp").value === "0") {
|
||||||
@ -71,29 +28,6 @@
|
|||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
function uploadFile(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", d.Sf.data.files[0], name);
|
|
||||||
req.send(formData);
|
|
||||||
d.Sf.data.value = '';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addPanels() {
|
function addPanels() {
|
||||||
let c = parseInt(d.Sf.MPC.value);
|
let c = parseInt(d.Sf.MPC.value);
|
||||||
let i = gId("panels").children.length;
|
let i = gId("panels").children.length;
|
||||||
@ -308,7 +242,7 @@ Y:<input name="P${i}Y" type="number" min="0" max="255" value="0" oninput="UI()">
|
|||||||
<body onload="S()">
|
<body onload="S()">
|
||||||
<form id="form_s" name="Sf" method="post">
|
<form id="form_s" name="Sf" method="post">
|
||||||
<div class="toprow">
|
<div class="toprow">
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H('features/2D')">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="button" onclick="fS()">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="button" onclick="fS()">Save</button><hr>
|
||||||
</div>
|
</div>
|
||||||
<h2>2D setup</h2>
|
<h2>2D setup</h2>
|
||||||
@ -351,7 +285,7 @@ Y:<input name="P${i}Y" type="number" min="0" max="255" value="0" oninput="UI()">
|
|||||||
<hr class="sml">
|
<hr class="sml">
|
||||||
<div id="MD"></div>
|
<div id="MD"></div>
|
||||||
<canvas id="canvas"></canvas>
|
<canvas id="canvas"></canvas>
|
||||||
<div id="json" >Gap file: <input type="file" name="data" accept=".json"><button type="button" class="sml" onclick="uploadFile('/2d-gaps.json')">Upload</button></div>
|
<div id="json" >Gap file: <input type="file" name="data" accept=".json"><button type="button" class="sml" onclick="uploadFile(d.Sf.data,'/2d-gaps.json')">Upload</button></div>
|
||||||
<i>Note: Gap file is a <b>.json</b> file containing an array with number of elements equal to the matrix size.<br>
|
<i>Note: Gap file is a <b>.json</b> file containing an array with number of elements equal to the matrix size.<br>
|
||||||
A value of -1 means that pixel at that position is missing, a value of 0 means never paint that pixel, and 1 means regular pixel.</i>
|
A value of -1 means that pixel at that position is missing, a value of 0 means never paint that pixel, and 1 means regular pixel.</i>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,88 +4,46 @@
|
|||||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>DMX Settings</title>
|
<title>DMX Settings</title>
|
||||||
|
<script src="common.js" async type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
var d=document;
|
function HW(){window.open("https://github.com/Aircoookie/WLED/wiki/DMX");}
|
||||||
var loc = false, locip, locproto = "http:";
|
|
||||||
function H(){window.open("https://github.com/Aircoookie/WLED/wiki/DMX");}
|
|
||||||
function B(){window.open(getURL("/settings"),"_self");}
|
|
||||||
function GCH(num) {
|
function GCH(num) {
|
||||||
d.getElementById('dmxchannels').innerHTML += "";
|
gId('dmxchannels').innerHTML += "";
|
||||||
for (i=0;i<num;i++) {
|
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";
|
gId('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(){
|
function mMap(){
|
||||||
numCh=document.Sf.CN.value;
|
numCh=document.Sf.CN.value;
|
||||||
numGap=document.Sf.CG.value;
|
numGap=document.Sf.CG.value;
|
||||||
if (parseInt(numCh)>parseInt(numGap)) {
|
if (parseInt(numCh)>parseInt(numGap)) {
|
||||||
d.getElementById("gapwarning").style.display="block";
|
gId("gapwarning").style.display="block";
|
||||||
} else {
|
} else {
|
||||||
d.getElementById("gapwarning").style.display="none";
|
gId("gapwarning").style.display="none";
|
||||||
}
|
}
|
||||||
for (i=0;i<15;i++) {
|
for (i=0;i<15;i++) {
|
||||||
if (i>=numCh) {
|
if (i>=numCh) {
|
||||||
d.getElementById("CH"+(i+1) + "s").style.opacity = "0.5";
|
gId("CH"+(i+1) + "s").style.opacity = "0.5";
|
||||||
d.getElementById("CH"+(i+1)).disabled = true;
|
gId("CH"+(i+1)).disabled = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
d.getElementById("CH"+(i+1) + "s").style.opacity = "1";
|
gId("CH"+(i+1) + "s").style.opacity = "1";
|
||||||
d.getElementById("CH"+(i+1)).disabled = false;
|
gId("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(){
|
function S(){
|
||||||
let l = window.location;
|
getLoc();
|
||||||
if (l.protocol == "file:") {
|
loadJS(getURL('/settings/s.js?p=7'), false, ()=>{GCH(15);}, ()=>{mMap();}); // If we set async false, file is loaded and executed, then next statement is processed
|
||||||
loc = true;
|
|
||||||
locip = localStorage.getItem('locIp');
|
|
||||||
if (!locip) {
|
|
||||||
locip = prompt("File Mode. Please enter WLED IP!");
|
|
||||||
localStorage.setItem('locIp', locip);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// detect reverse proxy
|
|
||||||
let path = l.pathname;
|
|
||||||
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
|
|
||||||
if (paths.length > 2) {
|
|
||||||
paths.pop(); // remove "dmx"
|
|
||||||
paths.pop(); // remove "settings"
|
|
||||||
locproto = l.protocol;
|
|
||||||
loc = true;
|
|
||||||
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadJS(getURL('/settings/s.js?p=7'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
|
||||||
if (loc) d.Sf.action = getURL('/settings/dmx');
|
if (loc) d.Sf.action = getURL('/settings/dmx');
|
||||||
}
|
}
|
||||||
function getURL(path) {
|
|
||||||
return (loc ? locproto + "//" + locip : "") + path;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style>@import url("style.css");</style>
|
<style>@import url("style.css");</style>
|
||||||
</head>
|
</head>
|
||||||
<body onload="S()">
|
<body onload="S()">
|
||||||
<form id="form_s" name="Sf" method="post">
|
<form id="form_s" name="Sf" method="post">
|
||||||
<div class="toprow">
|
<div class="toprow">
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="HW()">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||||
</div>
|
</div>
|
||||||
<h2>Imma firin ma lazer (if it has DMX support)</h2><!-- TODO: Change to something less-meme-related //-->
|
<h2>Imma firin ma lazer (if it has DMX support)</h2><!-- TODO: Change to something less-meme-related //-->
|
||||||
|
@ -4,20 +4,12 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<title>LED Settings</title>
|
<title>LED Settings</title>
|
||||||
|
<script src="common.js" async type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
var d=document,laprev=55,maxB=1,maxD=1,maxA=1,maxV=0,maxM=4000,maxPB=2048,maxL=1664,maxCO=5,maxLbquot=0; //maximum bytes for LED allocation: 4kB for 8266, 32kB for 32
|
var laprev=55,maxB=1,maxD=1,maxA=1,maxV=0,maxM=4000,maxPB=2048,maxL=1664,maxCO=5,maxLbquot=0; //maximum bytes for LED allocation: 4kB for 8266, 32kB for 32
|
||||||
var oMaxB=1;
|
var oMaxB=1;
|
||||||
d.ledTypes = [/*{i:22,c:1,t:"D",n:"WS2812"},{i:42,c:6,t:"AA",n:"PWM CCT"}*/]; // filled from GetV()
|
|
||||||
d.um_p = [];
|
|
||||||
d.rsvd = [];
|
|
||||||
d.ro_gpio = [];
|
|
||||||
d.max_gpio = 50;
|
|
||||||
var customStarts=false,startsDirty=[];
|
var customStarts=false,startsDirty=[];
|
||||||
var loc = false, locip, locproto = "http:";
|
function off(n) { gN(n).value = -1;}
|
||||||
function H(){window.open("https://kno.wled.ge/features/settings/#led-settings");}
|
|
||||||
function B(){window.open(getURL("/settings"),"_self");}
|
|
||||||
function gId(n){return d.getElementById(n);}
|
|
||||||
function off(n){d.getElementsByName(n)[0].value = -1;}
|
|
||||||
// these functions correspond to C macros found in const.h
|
// these functions correspond to C macros found in const.h
|
||||||
function gT(t) { for (let type of d.ledTypes) if (t == type.i) return type; } // getType from available ledTypes
|
function gT(t) { for (let type of d.ledTypes) if (t == type.i) return type; } // getType from available ledTypes
|
||||||
function isPWM(t) { return gT(t).t.charAt(0) === "A"; } // is PWM type
|
function isPWM(t) { return gT(t).t.charAt(0) === "A"; } // is PWM type
|
||||||
@ -31,37 +23,22 @@
|
|||||||
function hasCCT(t) { return !!(gT(t).c & 0x04); } // is white CCT enabled
|
function hasCCT(t) { return !!(gT(t).c & 0x04); } // is white CCT enabled
|
||||||
function is16b(t) { return !!(gT(t).c & 0x10); } // is digital 16 bit type
|
function is16b(t) { return !!(gT(t).c & 0x10); } // is digital 16 bit type
|
||||||
function numPins(t){ return Math.max(gT(t).t.length, 1); } // type length determines number of GPIO pins
|
function numPins(t){ return Math.max(gT(t).t.length, 1); } // type length determines number of GPIO pins
|
||||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
function S() {
|
||||||
function loadJS(FILE_URL, async = true) {
|
getLoc();
|
||||||
let scE = d.createElement("script");
|
loadJS(getURL('/settings/s.js?p=2'), false, ()=>{
|
||||||
scE.setAttribute("src", FILE_URL);
|
d.ledTypes = [/*{i:22,c:1,t:"D",n:"WS2812"},{i:42,c:6,t:"AA",n:"PWM CCT"}*/]; // filled from GetV()
|
||||||
scE.setAttribute("type", "text/javascript");
|
d.um_p = [];
|
||||||
scE.setAttribute("async", async);
|
d.rsvd = [];
|
||||||
d.body.appendChild(scE);
|
d.ro_gpio = [];
|
||||||
// success event
|
d.max_gpio = 50;
|
||||||
scE.addEventListener("load", () => {
|
}, ()=>{
|
||||||
GetV();
|
|
||||||
checkSi();
|
checkSi();
|
||||||
setABL();
|
setABL();
|
||||||
d.Sf.addEventListener("submit", trySubmit);
|
d.Sf.addEventListener("submit", trySubmit);
|
||||||
if (d.um_p[0]==-1) d.um_p.shift();
|
if (d.um_p[0]==-1) d.um_p.shift();
|
||||||
pinDropdowns();
|
pinDropdowns();
|
||||||
});
|
}); // If we set async false, file is loaded and executed, then next statement is processed
|
||||||
// error event
|
if (loc) d.Sf.action = getURL('/settings/leds');
|
||||||
scE.addEventListener("error", (ev) => {
|
|
||||||
console.log("Error on loading file", ev);
|
|
||||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
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(()=>{ x.className = x.className.replace("show", ""); }, 2900);
|
|
||||||
}
|
}
|
||||||
function bLimits(b,v,p,m,l,o=5,d=2,a=6) {
|
function bLimits(b,v,p,m,l,o=5,d=2,a=6) {
|
||||||
// maxB - max buses (can be changed if using ESP32 parallel I2S)
|
// maxB - max buses (can be changed if using ESP32 parallel I2S)
|
||||||
@ -403,7 +380,7 @@
|
|||||||
}
|
}
|
||||||
function addLEDs(n,init=true)
|
function addLEDs(n,init=true)
|
||||||
{
|
{
|
||||||
var o = d.getElementsByClassName("iST");
|
var o = gEBCN("iST");
|
||||||
var i = o.length;
|
var i = o.length;
|
||||||
let disable = (sel,opt) => { sel.querySelectorAll(opt).forEach((o)=>{o.disabled=true;}); }
|
let disable = (sel,opt) => { sel.querySelectorAll(opt).forEach((o)=>{o.disabled=true;}); }
|
||||||
|
|
||||||
@ -465,10 +442,10 @@ mA/LED: <select name="LAsel${s}" onchange="enLA(this,'${s}');UI();">
|
|||||||
</div>`;
|
</div>`;
|
||||||
f.insertAdjacentHTML("beforeend", cn);
|
f.insertAdjacentHTML("beforeend", cn);
|
||||||
// fill led types (credit @netmindz)
|
// fill led types (credit @netmindz)
|
||||||
d.Sf.querySelectorAll("#mLC select[name^=LT]").forEach((sel,n)=>{
|
f.querySelectorAll("select[name^=LT]").forEach((sel,n)=>{
|
||||||
if (sel.length == 0) { // ignore already updated
|
if (sel.length == 0) { // ignore already updated
|
||||||
for (let type of d.ledTypes) {
|
for (let type of d.ledTypes) {
|
||||||
let opt = d.createElement("option");
|
let opt = cE("option");
|
||||||
opt.value = type.i;
|
opt.value = type.i;
|
||||||
opt.text = type.n;
|
opt.text = type.n;
|
||||||
if (type.t != undefined && type.t != "") {
|
if (type.t != undefined && type.t != "") {
|
||||||
@ -499,7 +476,7 @@ mA/LED: <select name="LAsel${s}" onchange="enLA(this,'${s}');UI();">
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addCOM(start=0,len=1,co=0) {
|
function addCOM(start=0,len=1,co=0) {
|
||||||
var i = d.getElementsByClassName("com_entry").length;
|
var i = gEBCN("com_entry").length;
|
||||||
if (i >= maxCO) return;
|
if (i >= maxCO) return;
|
||||||
var s = String.fromCharCode((i<10?48:55)+i);
|
var s = String.fromCharCode((i<10?48:55)+i);
|
||||||
var b = `<div class="com_entry">
|
var b = `<div class="com_entry">
|
||||||
@ -530,7 +507,7 @@ Swap: <select id="xw${s}" name="XW${s}">
|
|||||||
}
|
}
|
||||||
|
|
||||||
function remCOM() {
|
function remCOM() {
|
||||||
var entries = d.getElementsByClassName("com_entry");
|
var entries = gEBCN("com_entry");
|
||||||
var i = entries.length;
|
var i = entries.length;
|
||||||
if (i === 0) return;
|
if (i === 0) return;
|
||||||
entries[i-1].remove();
|
entries[i-1].remove();
|
||||||
@ -542,7 +519,7 @@ Swap: <select id="xw${s}" name="XW${s}">
|
|||||||
if (_newMaxCOOverrides) {
|
if (_newMaxCOOverrides) {
|
||||||
maxCO = _newMaxCOOverrides;
|
maxCO = _newMaxCOOverrides;
|
||||||
}
|
}
|
||||||
for (let e of d.getElementsByClassName("com_entry")) {
|
for (let e of gEBCN("com_entry")) {
|
||||||
e.remove();
|
e.remove();
|
||||||
}
|
}
|
||||||
btnCOM(0);
|
btnCOM(0);
|
||||||
@ -578,25 +555,14 @@ Swap: <select id="xw${s}" name="XW${s}">
|
|||||||
}
|
}
|
||||||
function checkSi() { //on load, checks whether there are custom start fields
|
function checkSi() { //on load, checks whether there are custom start fields
|
||||||
var cs = false;
|
var cs = false;
|
||||||
for (var i=1; i < d.getElementsByClassName("iST").length; i++) {
|
for (var i=1; i < gEBCN("iST").length; i++) {
|
||||||
var v = parseInt(gId("ls"+(i-1)).value) + parseInt(d.getElementsByName("LC"+(i-1))[0].value);
|
var v = parseInt(gId("ls"+(i-1)).value) + parseInt(gN("LC"+(i-1)).value);
|
||||||
if (v != parseInt(gId("ls"+i).value)) {cs = true; startsDirty[i] = true;}
|
if (v != parseInt(gId("ls"+i).value)) {cs = true; startsDirty[i] = true;}
|
||||||
}
|
}
|
||||||
if (gId("ls0") && parseInt(gId("ls0").value) != 0) {cs = true; startsDirty[0] = true;}
|
if (gId("ls0") && parseInt(gId("ls0").value) != 0) {cs = true; startsDirty[0] = true;}
|
||||||
gId("si").checked = cs;
|
gId("si").checked = cs;
|
||||||
tglSi(cs);
|
tglSi(cs);
|
||||||
}
|
}
|
||||||
function uploadFile(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", d.Sf.data.files[0], name);
|
|
||||||
req.send(formData);
|
|
||||||
d.Sf.data.value = '';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// https://stackoverflow.com/questions/7346563/loading-local-json-file
|
// https://stackoverflow.com/questions/7346563/loading-local-json-file
|
||||||
function loadCfg(o) {
|
function loadCfg(o) {
|
||||||
var f, fr;
|
var f, fr;
|
||||||
@ -725,7 +691,7 @@ Swap: <select id="xw${s}" name="XW${s}">
|
|||||||
}
|
}
|
||||||
// https://stackoverflow.com/questions/39729741/javascript-change-input-text-to-select-option
|
// https://stackoverflow.com/questions/39729741/javascript-change-input-text-to-select-option
|
||||||
function addDropdown(field) {
|
function addDropdown(field) {
|
||||||
let sel = d.createElement('select');
|
let sel = cE('select');
|
||||||
sel.classList.add("pin");
|
sel.classList.add("pin");
|
||||||
let inp = d.getElementsByName(field)[0];
|
let inp = d.getElementsByName(field)[0];
|
||||||
if (inp && inp.tagName === "INPUT" && (inp.type === "text" || inp.type === "number")) { // may also use nodeName
|
if (inp && inp.tagName === "INPUT" && (inp.type === "text" || inp.type === "number")) { // may also use nodeName
|
||||||
@ -750,7 +716,7 @@ Swap: <select id="xw${s}" name="XW${s}">
|
|||||||
}
|
}
|
||||||
function addOption(sel,txt,val) {
|
function addOption(sel,txt,val) {
|
||||||
if (sel===null) return; // select object missing
|
if (sel===null) return; // select object missing
|
||||||
let opt = d.createElement("option");
|
let opt = cE("option");
|
||||||
opt.value = val;
|
opt.value = val;
|
||||||
opt.text = txt;
|
opt.text = txt;
|
||||||
sel.appendChild(opt);
|
sel.appendChild(opt);
|
||||||
@ -760,40 +726,13 @@ Swap: <select id="xw${s}" name="XW${s}">
|
|||||||
}
|
}
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
function S() {
|
|
||||||
let l = window.location;
|
|
||||||
if (l.protocol == "file:") {
|
|
||||||
loc = true;
|
|
||||||
locip = localStorage.getItem('locIp');
|
|
||||||
if (!locip) {
|
|
||||||
locip = prompt("File Mode. Please enter WLED IP!");
|
|
||||||
localStorage.setItem('locIp', locip);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// detect reverse proxy
|
|
||||||
let path = l.pathname;
|
|
||||||
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
|
|
||||||
if (paths.length > 2) {
|
|
||||||
paths.pop(); // remove "leds"
|
|
||||||
paths.pop(); // remove "settings"
|
|
||||||
locproto = l.protocol;
|
|
||||||
loc = true;
|
|
||||||
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadJS(getURL('/settings/s.js?p=2'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
|
||||||
if (loc) d.Sf.action = getURL('/settings/leds');
|
|
||||||
}
|
|
||||||
function getURL(path) {
|
|
||||||
return (loc ? locproto + "//" + locip : "") + path;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style>@import url("style.css");</style>
|
<style>@import url("style.css");</style>
|
||||||
</head>
|
</head>
|
||||||
<body onload="S()">
|
<body onload="S()">
|
||||||
<form id="form_s" name="Sf" method="post">
|
<form id="form_s" name="Sf" method="post">
|
||||||
<div class="toprow">
|
<div class="toprow">
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H('features/settings/#led-settings')">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||||
</div>
|
</div>
|
||||||
<h2>LED & Hardware setup</h2>
|
<h2>LED & Hardware setup</h2>
|
||||||
@ -861,7 +800,7 @@ Swap: <select id="xw${s}" name="XW${s}">
|
|||||||
<option value=8>JSON remote</option>
|
<option value=8>JSON remote</option>
|
||||||
</select><span style="cursor: pointer;" onclick="off('IR')"> ✕</span><br>
|
</select><span style="cursor: pointer;" onclick="off('IR')"> ✕</span><br>
|
||||||
Apply IR change to main segment only: <input type="checkbox" name="MSO"><br>
|
Apply IR change to main segment only: <input type="checkbox" name="MSO"><br>
|
||||||
<div id="json" style="display:none;">JSON file: <input type="file" name="data" accept=".json"><button type="button" class="sml" onclick="uploadFile('/ir.json')">Upload</button><br></div>
|
<div id="json" style="display:none;">JSON file: <input type="file" name="data" accept=".json"><button type="button" class="sml" onclick="uploadFile(d.Sf.data,'/ir.json')">Upload</button><br></div>
|
||||||
<a href="https://kno.wled.ge/interfaces/infrared/" target="_blank">IR info</a><br>
|
<a href="https://kno.wled.ge/interfaces/infrared/" target="_blank">IR info</a><br>
|
||||||
<hr class="sml">
|
<hr class="sml">
|
||||||
Relay GPIO: <input type="number" min="-1" max="48" name="RL" onchange="UI()" class="xs"><span style="cursor: pointer;" onclick="off('RL')"> ✕</span><br>
|
Relay GPIO: <input type="number" min="-1" max="48" name="RL" onchange="UI()" class="xs"><span style="cursor: pointer;" onclick="off('RL')"> ✕</span><br>
|
||||||
|
@ -4,55 +4,9 @@
|
|||||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Misc Settings</title>
|
<title>Misc Settings</title>
|
||||||
|
<script src="common.js" async type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
var d = document;
|
|
||||||
var loc = false, locip, locproto = "http:";
|
|
||||||
function H() { window.open("https://kno.wled.ge/features/settings/#security-settings"); }
|
|
||||||
function B() { window.open(getURL("/settings"),"_self"); }
|
|
||||||
function U() { window.open(getURL("/update"),"_self"); }
|
function U() { window.open(getURL("/update"),"_self"); }
|
||||||
function gId(s) { return d.getElementById(s); }
|
|
||||||
function isObj(o) { return (o && typeof o === 'object' && !Array.isArray(o)); }
|
|
||||||
// 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();
|
|
||||||
setBckFilename(gId("bckcfg"));
|
|
||||||
setBckFilename(gId("bckpresets"));
|
|
||||||
});
|
|
||||||
// error event
|
|
||||||
scE.addEventListener("error", (ev) => {
|
|
||||||
console.log("Error on loading file", ev);
|
|
||||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
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 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", getURL("/upload"));
|
|
||||||
var formData = new FormData();
|
|
||||||
formData.append("data", fO.files[0], name);
|
|
||||||
req.send(formData);
|
|
||||||
fO.value = '';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
function checkNum(o) {
|
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"];
|
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
|
// true if key is a number or a special key
|
||||||
@ -64,36 +18,17 @@
|
|||||||
x.setAttribute("download","wled_" + x.getAttribute("download") + (sd=="WLED"?"":("_" +sd)));
|
x.setAttribute("download","wled_" + x.getAttribute("download") + (sd=="WLED"?"":("_" +sd)));
|
||||||
}
|
}
|
||||||
function S() {
|
function S() {
|
||||||
let l = window.location;
|
getLoc();
|
||||||
if (l.protocol == "file:") {
|
|
||||||
loc = true;
|
|
||||||
locip = localStorage.getItem('locIp');
|
|
||||||
if (!locip) {
|
|
||||||
locip = prompt("File Mode. Please enter WLED IP!");
|
|
||||||
localStorage.setItem('locIp', locip);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// detect reverse proxy
|
|
||||||
let path = l.pathname;
|
|
||||||
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
|
|
||||||
if (paths.length > 2) {
|
|
||||||
paths.pop(); // remove "sec"
|
|
||||||
paths.pop(); // remove "settings"
|
|
||||||
locproto = l.protocol;
|
|
||||||
loc = true;
|
|
||||||
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (loc) {
|
if (loc) {
|
||||||
gId("bckcfg").setAttribute('href',getURL(gId("bckcfg").pathname));
|
gId("bckcfg").setAttribute('href',getURL(gId("bckcfg").pathname));
|
||||||
gId("bckpresets").setAttribute('href',getURL(gId("bckpresets").pathname));
|
gId("bckpresets").setAttribute('href',getURL(gId("bckpresets").pathname));
|
||||||
}
|
}
|
||||||
loadJS(getURL('/settings/s.js?p=6'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
loadJS(getURL('/settings/s.js?p=6'), false, undefined, ()=>{
|
||||||
|
setBckFilename(gId("bckcfg"));
|
||||||
|
setBckFilename(gId("bckpresets"));
|
||||||
|
}); // If we set async false, file is loaded and executed, then next statement is processed
|
||||||
if (loc) d.Sf.action = getURL('/settings/sec');
|
if (loc) d.Sf.action = getURL('/settings/sec');
|
||||||
}
|
}
|
||||||
function getURL(path) {
|
|
||||||
return (loc ? locproto + "//" + locip : "") + path;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
@import url("style.css");
|
@import url("style.css");
|
||||||
@ -102,7 +37,7 @@
|
|||||||
<body onload="S()">
|
<body onload="S()">
|
||||||
<form id="form_s" name="Sf" method="post">
|
<form id="form_s" name="Sf" method="post">
|
||||||
<div class="toprow">
|
<div class="toprow">
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H('features/settings/#security-settings')">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||||
</div>
|
</div>
|
||||||
<h2>Security & Update setup</h2>
|
<h2>Security & Update setup</h2>
|
||||||
|
@ -4,32 +4,10 @@
|
|||||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Sync Settings</title>
|
<title>Sync Settings</title>
|
||||||
<script>var d=document;
|
<script src="common.js" async type="text/javascript"></script>
|
||||||
var loc = false, locip, locproto = "http:";
|
<script>
|
||||||
function gId(s){return d.getElementById(s);}
|
|
||||||
function toggle(el){gId(el).classList.toggle("hide"); gId('No'+el).classList.toggle("hide");}
|
|
||||||
function H(){window.open("https://kno.wled.ge/interfaces/udp-notifier/");}
|
|
||||||
function B(){window.open(getURL("/settings"),"_self");}
|
|
||||||
function adj(){if (d.Sf.DI.value == 6454) {if (d.Sf.EU.value == 1) d.Sf.EU.value = 0;}
|
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;} }
|
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()
|
function FC()
|
||||||
{
|
{
|
||||||
for(j=0;j<8;j++)
|
for(j=0;j<8;j++)
|
||||||
@ -55,26 +33,8 @@
|
|||||||
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 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 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(){
|
function S(){
|
||||||
let l = window.location;
|
getLoc();
|
||||||
if (l.protocol == "file:") {
|
loadJS(getURL('/settings/s.js?p=4'), false, undefined, ()=>{SetVal();}); // If we set async false, file is loaded and executed, then next statement is processed
|
||||||
loc = true;
|
|
||||||
locip = localStorage.getItem('locIp');
|
|
||||||
if (!locip) {
|
|
||||||
locip = prompt("File Mode. Please enter WLED IP!");
|
|
||||||
localStorage.setItem('locIp', locip);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// detect reverse proxy
|
|
||||||
let paths = l.pathname.slice(1,l.pathname.endsWith('/')?-1:undefined).split("/");
|
|
||||||
if (paths.length > 2) {
|
|
||||||
paths.pop(); // remove "sync"
|
|
||||||
paths.pop(); // remove "settings"
|
|
||||||
locproto = l.protocol;
|
|
||||||
loc = true;
|
|
||||||
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadJS(getURL('/settings/s.js?p=4'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
|
||||||
if (loc) d.Sf.action = getURL('/settings/sync');
|
if (loc) d.Sf.action = getURL('/settings/sync');
|
||||||
}
|
}
|
||||||
function getURL(path) {
|
function getURL(path) {
|
||||||
@ -86,7 +46,7 @@
|
|||||||
<body onload="S()">
|
<body onload="S()">
|
||||||
<form id="form_s" name="Sf" method="post" onsubmit="GC()">
|
<form id="form_s" name="Sf" method="post" onsubmit="GC()">
|
||||||
<div class="toprow">
|
<div class="toprow">
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H('interfaces/udp-notifier/')">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||||
</div>
|
</div>
|
||||||
<h2>Sync setup</h2>
|
<h2>Sync setup</h2>
|
||||||
|
@ -4,60 +4,19 @@
|
|||||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Time Settings</title>
|
<title>Time Settings</title>
|
||||||
|
<script src="common.js" async type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
var d=document;
|
|
||||||
var loc = false, locip, locproto = "http:";
|
|
||||||
var el=false;
|
var el=false;
|
||||||
var ms=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
|
var ms=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
|
||||||
function H() { window.open("https://kno.wled.ge/features/settings/#time-settings"); }
|
|
||||||
function B() { window.open(getURL("/settings"),"_self"); }
|
|
||||||
function gId(s) { return d.getElementById(s); }
|
|
||||||
function gN(s) { return d.getElementsByName(s)[0]; }
|
|
||||||
// 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");
|
|
||||||
BTa();GetV();updLoc();Cs();FC();
|
|
||||||
});
|
|
||||||
// error event
|
|
||||||
scE.addEventListener("error", (ev) => {
|
|
||||||
console.log("Error on loading file", ev);
|
|
||||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function S() {
|
function S() {
|
||||||
let l = window.location;
|
getLoc();
|
||||||
if (l.protocol == "file:") {
|
loadJS(getURL('/settings/s.js?p=5'), false, ()=>{BTa();}, ()=>{
|
||||||
loc = true;
|
updLatLon();
|
||||||
locip = localStorage.getItem('locIp');
|
Cs();
|
||||||
if (!locip) {
|
FC();
|
||||||
locip = prompt("File Mode. Please enter WLED IP!");
|
}); // If we set async false, file is loaded and executed, then next statement is processed
|
||||||
localStorage.setItem('locIp', locip);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// detect reverse proxy
|
|
||||||
let path = l.pathname;
|
|
||||||
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
|
|
||||||
if (paths.length > 2) {
|
|
||||||
paths.pop(); // remove "time"
|
|
||||||
paths.pop(); // remove "settings"
|
|
||||||
locproto = l.protocol;
|
|
||||||
loc = true;
|
|
||||||
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadJS(getURL('/settings/s.js?p=5'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
|
||||||
if (loc) d.Sf.action = getURL('/settings/time');
|
if (loc) d.Sf.action = getURL('/settings/time');
|
||||||
}
|
}
|
||||||
function getURL(path) {
|
|
||||||
return (loc ? locproto + "//" + locip : "") + path;
|
|
||||||
}
|
|
||||||
function expand(o,i)
|
function expand(o,i)
|
||||||
{
|
{
|
||||||
var t = gId("WD"+i);
|
var t = gId("WD"+i);
|
||||||
@ -141,21 +100,21 @@
|
|||||||
td = tr.insertCell(3);
|
td = tr.insertCell(3);
|
||||||
td.innerHTML = `<input name="MD${b}" type="number" class="s" min="0" max="250" value="${d}" required>`;
|
td.innerHTML = `<input name="MD${b}" type="number" class="s" min="0" max="250" value="${d}" required>`;
|
||||||
}
|
}
|
||||||
function getLoc() {
|
function getLatLon() {
|
||||||
if (!el) {
|
if (!el) {
|
||||||
window.addEventListener("message", (event) => {
|
window.addEventListener("message", (event) => {
|
||||||
if (event.origin !== "https://locate.wled.me") return;
|
if (event.origin !== "https://locate.wled.me") return;
|
||||||
if (event.data instanceof Object) {
|
if (event.data instanceof Object) {
|
||||||
d.Sf.LT.value = event.data.lat;
|
d.Sf.LT.value = event.data.lat;
|
||||||
d.Sf.LN.value = event.data.lon;
|
d.Sf.LN.value = event.data.lon;
|
||||||
updLoc();
|
updLatLon();
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
el = true;
|
el = true;
|
||||||
}
|
}
|
||||||
window.open("https://locate.wled.me","_blank");
|
window.open("https://locate.wled.me","_blank");
|
||||||
}
|
}
|
||||||
function updLoc(i) {
|
function updLatLon(i) {
|
||||||
if (parseFloat(d.Sf.LT.value)<0) { d.Sf.LTR.value = "S"; d.Sf.LT.value = -1*parseFloat(d.Sf.LT.value); } else d.Sf.LTR.value = "N";
|
if (parseFloat(d.Sf.LT.value)<0) { d.Sf.LTR.value = "S"; d.Sf.LT.value = -1*parseFloat(d.Sf.LT.value); } else d.Sf.LTR.value = "N";
|
||||||
if (parseFloat(d.Sf.LN.value)<0) { d.Sf.LNR.value = "W"; d.Sf.LN.value = -1*parseFloat(d.Sf.LN.value); } else d.Sf.LNR.value = "E";
|
if (parseFloat(d.Sf.LN.value)<0) { d.Sf.LNR.value = "W"; d.Sf.LN.value = -1*parseFloat(d.Sf.LN.value); } else d.Sf.LNR.value = "E";
|
||||||
}
|
}
|
||||||
@ -165,7 +124,7 @@
|
|||||||
<body onload="S()">
|
<body onload="S()">
|
||||||
<form id="form_s" name="Sf" method="post" onsubmit="Wd()">
|
<form id="form_s" name="Sf" method="post" onsubmit="Wd()">
|
||||||
<div class="toprow">
|
<div class="toprow">
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H('features/settings/#time-settings')">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||||
</div>
|
</div>
|
||||||
<h2>Time setup</h2>
|
<h2>Time setup</h2>
|
||||||
@ -202,7 +161,7 @@
|
|||||||
Current local time is <span class="times">unknown</span>.<br>
|
Current local time is <span class="times">unknown</span>.<br>
|
||||||
Latitude: <select name="LTR"><option value="N">N</option><option value="S">S</option></select><input name="LT" type="number" class="xl" min="0" max="66.6" step="0.01"><br>
|
Latitude: <select name="LTR"><option value="N">N</option><option value="S">S</option></select><input name="LT" type="number" class="xl" min="0" max="66.6" step="0.01"><br>
|
||||||
Longitude: <select name="LNR"><option value="E">E</option><option value="W">W</option></select><input name="LN" type="number" class="xl" min="0" max="180" step="0.01"><br>
|
Longitude: <select name="LNR"><option value="E">E</option><option value="W">W</option></select><input name="LN" type="number" class="xl" min="0" max="180" step="0.01"><br>
|
||||||
<button type="button" id="locbtn" onclick="getLoc()">Get location</button>
|
<button type="button" id="locbtn" onclick="getLatLon()">Get location</button>
|
||||||
<div><i>(opens new tab, only works in browser)</i></div>
|
<div><i>(opens new tab, only works in browser)</i></div>
|
||||||
<div id="sun" class="times"></div>
|
<div id="sun" class="times"></div>
|
||||||
<h3>Clock</h3>
|
<h3>Clock</h3>
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<title>UI Settings</title>
|
<title>UI Settings</title>
|
||||||
|
<script src="common.js" async type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
var d = document;
|
|
||||||
var loc = false, locip, locproto = "http:";
|
|
||||||
var initial_ds, initial_st, initial_su, oldUrl;
|
var initial_ds, initial_st, initial_su, oldUrl;
|
||||||
var sett = null;
|
var sett = null;
|
||||||
var l = {
|
var l = {
|
||||||
@ -47,11 +46,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
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) {
|
function set(path, obj, val) {
|
||||||
var tar = obj;
|
var tar = obj;
|
||||||
var pList = path.split('_');
|
var pList = path.split('_');
|
||||||
@ -63,23 +57,13 @@
|
|||||||
}
|
}
|
||||||
tar[pList[len-1]] = val;
|
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)
|
function addRec(s, path = "", label = null)
|
||||||
{
|
{
|
||||||
var str = "";
|
var str = "";
|
||||||
for (let i in s)
|
for (let i in s)
|
||||||
{
|
{
|
||||||
var fk = path + (path?'_':'') + i;
|
var fk = path + (path?'_':'') + i;
|
||||||
if (isObject(s[i])) {
|
if (isO(s[i])) {
|
||||||
if (label && label[i] && label[i]["LABEL"]) str += `<h3>${label[i]["LABEL"]}</h3>`;
|
if (label && label[i] && label[i]["LABEL"]) str += `<h3>${label[i]["LABEL"]}</h3>`;
|
||||||
str += addRec(s[i], fk, label? label[i] : null);
|
str += addRec(s[i], fk, label? label[i] : null);
|
||||||
} else {
|
} else {
|
||||||
@ -174,57 +158,16 @@
|
|||||||
if (d.Sf.DS.value != initial_ds || /*d.Sf.ST.checked != initial_st ||*/ d.Sf.SU.checked != initial_su) d.Sf.submit();
|
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 S() {
|
||||||
function loadJS(FILE_URL, async = true) {
|
getLoc();
|
||||||
let scE = d.createElement("script");
|
loadJS(getURL('/settings/s.js?p=3'), false, undefined, ()=>{
|
||||||
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_ds = d.Sf.DS.value;
|
||||||
//initial_st = d.Sf.ST.checked;
|
//initial_st = d.Sf.ST.checked;
|
||||||
initial_su = d.Sf.SU.checked;
|
initial_su = d.Sf.SU.checked;
|
||||||
GetLS();
|
GetLS();
|
||||||
});
|
}); // If we set async false, file is loaded and executed, then next statement is processed
|
||||||
// error event
|
|
||||||
scE.addEventListener("error", (ev) => {
|
|
||||||
console.log("Error on loading file", ev);
|
|
||||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function S() {
|
|
||||||
let l = window.location;
|
|
||||||
if (l.protocol == "file:") {
|
|
||||||
loc = true;
|
|
||||||
locip = localStorage.getItem('locIp');
|
|
||||||
if (!locip) {
|
|
||||||
locip = prompt("File Mode. Please enter WLED IP!");
|
|
||||||
localStorage.setItem('locIp', locip);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// detect reverse proxy
|
|
||||||
let path = l.pathname;
|
|
||||||
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
|
|
||||||
if (paths.length > 2) {
|
|
||||||
paths.pop(); // remove "ui"
|
|
||||||
paths.pop(); // remove "settings"
|
|
||||||
locproto = l.protocol;
|
|
||||||
loc = true;
|
|
||||||
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadJS(getURL('/settings/s.js?p=3'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
|
||||||
if (loc) d.Sf.action = getURL('/settings/ui');
|
if (loc) d.Sf.action = getURL('/settings/ui');
|
||||||
}
|
}
|
||||||
function getURL(path) {
|
|
||||||
return (loc ? locproto + "//" + locip : "") + path;
|
|
||||||
}
|
|
||||||
function H() { window.open("https://kno.wled.ge/features/settings/#user-interface-settings"); }
|
|
||||||
function B() { window.open(getURL("/settings"),"_self"); }
|
|
||||||
function UI()
|
function UI()
|
||||||
{
|
{
|
||||||
gId('idonthateyou').style.display = (gId('dm').checked) ? 'inline':'none';
|
gId('idonthateyou').style.display = (gId('dm').checked) ? 'inline':'none';
|
||||||
@ -264,25 +207,13 @@
|
|||||||
if (gId("theme_bg_rnd").checked) toggle("Image");
|
if (gId("theme_bg_rnd").checked) toggle("Image");
|
||||||
gId("theme_bg_rnd").checked = false;
|
gId("theme_bg_rnd").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>
|
</script>
|
||||||
<style>@import url("style.css");</style>
|
<style>@import url("style.css");</style>
|
||||||
</head>
|
</head>
|
||||||
<body onload="S()">
|
<body onload="S()">
|
||||||
<form id="form_s" name="Sf" method="post">
|
<form id="form_s" name="Sf" method="post">
|
||||||
<div class="toprow">
|
<div class="toprow">
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H('features/settings/#user-interface-settings')">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="button" onclick="Save()">Save</button><br>
|
<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="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>
|
<span id="lserr" style="color:red; display:none">⚠ Could not access local storage. Make sure it is enabled in your browser.</span><hr>
|
||||||
|
@ -4,75 +4,55 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<title>Usermod Settings</title>
|
<title>Usermod Settings</title>
|
||||||
|
<script src="common.js" async type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
var d = document;
|
|
||||||
d.max_gpio = 50;
|
|
||||||
d.um_p = [];
|
|
||||||
d.rsvd = [];
|
|
||||||
d.ro_gpio = [];
|
|
||||||
d.extra = [];
|
|
||||||
var umCfg = {};
|
var umCfg = {};
|
||||||
var pins = [], pinO = [], owner;
|
var pins = [], pinO = [], owner;
|
||||||
var loc = false, locip, locproto = "http:";
|
|
||||||
var urows;
|
var urows;
|
||||||
var numM = 0;
|
var numM = 0;
|
||||||
function gId(s) { return d.getElementById(s); }
|
|
||||||
function isO(i) { return (i && typeof i === 'object' && !Array.isArray(i)); }
|
|
||||||
function H() { window.open("https://github.com/Aircoookie/WLED/wiki/Settings#usermod-settings"); }
|
|
||||||
function B() { window.open(getURL("/settings"),"_self"); }
|
|
||||||
// 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", () => {
|
|
||||||
GetV();
|
|
||||||
for (let r of d.rsvd) { pins.push(r); pinO.push("rsvd"); } // reserved pins
|
|
||||||
if (d.um_p[0]==-1) d.um_p.shift(); // remove filler
|
|
||||||
d.Sf.SDA.max = d.Sf.SCL.max = d.Sf.MOSI.max = d.Sf.SCLK.max = d.Sf.MISO.max = d.max_gpio-1;
|
|
||||||
//for (let i of d.getElementsByTagName("input")) if (i.type === "number" && i.name.replace("[]","").substr(-3) === "pin") i.max = d.max_gpio-1;
|
|
||||||
pinDD(); // convert INPUT to SELECT for pins
|
|
||||||
});
|
|
||||||
// error event
|
|
||||||
scE.addEventListener("error", (ev) => {
|
|
||||||
console.log("Error on loading file", ev);
|
|
||||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function S() {
|
function S() {
|
||||||
let l = window.location;
|
getLoc();
|
||||||
if (l.protocol == "file:") {
|
// load settings and insert values into DOM
|
||||||
loc = true;
|
fetch(getURL('/cfg.json'), {
|
||||||
locip = localStorage.getItem('locIp');
|
method: 'get'
|
||||||
if (!locip) {
|
})
|
||||||
locip = prompt("File Mode. Please enter WLED IP!");
|
.then(res => {
|
||||||
localStorage.setItem('locIp', locip);
|
if (!res.ok) gId('lserr').style.display = "inline";
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(json => {
|
||||||
|
umCfg = json.um;
|
||||||
|
getPins(json);
|
||||||
|
urows="";
|
||||||
|
if (isO(umCfg)) {
|
||||||
|
for (const [k,o] of Object.entries(umCfg)) {
|
||||||
|
urows += `<hr><h3>${k}</h3>`;
|
||||||
|
addField(k,'unknown',o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
if (urows==="") urows = "Usermods configuration not found.<br>Press <i>Save</i> to initialize defaults.";
|
||||||
// detect reverse proxy
|
gId("um").innerHTML = urows;
|
||||||
let path = l.pathname;
|
loadJS(getURL('/settings/s.js?p=8'), false, ()=>{
|
||||||
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
|
d.max_gpio = 50;
|
||||||
if (paths.length > 2) {
|
d.um_p = [];
|
||||||
paths.pop(); // remove "um"
|
d.rsvd = [];
|
||||||
paths.pop(); // remove "settings"
|
d.ro_gpio = [];
|
||||||
locproto = l.protocol;
|
d.extra = [];
|
||||||
loc = true;
|
}, ()=>{
|
||||||
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
for (let r of d.rsvd) { pins.push(r); pinO.push("rsvd"); } // reserved pins
|
||||||
}
|
if (d.um_p[0]==-1) d.um_p.shift(); // remove filler
|
||||||
}
|
d.Sf.SDA.max = d.Sf.SCL.max = d.Sf.MOSI.max = d.Sf.SCLK.max = d.Sf.MISO.max = d.max_gpio;
|
||||||
ldS();
|
//for (let i of d.getElementsByTagName("input")) if (i.type === "number" && i.name.replace("[]","").substr(-3) === "pin") i.max = d.max_gpio;
|
||||||
|
pinDD(); // convert INPUT to SELECT for pins
|
||||||
|
}); // If we set async false, file is loaded and executed, then next statement is processed
|
||||||
|
})
|
||||||
|
.catch((error)=>{
|
||||||
|
gId('lserr').style.display = "inline";
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
if (!numM) gId("um").innerHTML = "No Usermods installed.";
|
if (!numM) gId("um").innerHTML = "No Usermods installed.";
|
||||||
if (loc) d.Sf.action = getURL('/settings/um');
|
if (loc) d.Sf.action = getURL('/settings/um');
|
||||||
}
|
}
|
||||||
function getURL(path) {
|
|
||||||
return (loc ? locproto + "//" + locip : "") + path;
|
|
||||||
}
|
|
||||||
// https://stackoverflow.com/questions/3885817/how-do-i-check-that-a-number-is-float-or-integer
|
|
||||||
function isF(n) { return n === +n && n !== (n|0); }
|
|
||||||
function isI(n) { return n === +n && n === (n|0); }
|
|
||||||
function check(o,k) { // input object, pin owner key
|
function check(o,k) { // input object, pin owner key
|
||||||
/* no longer necessary with pin dropdown fields
|
/* no longer necessary with pin dropdown fields
|
||||||
var n = o.name.replace("[]","").substr(-3);
|
var n = o.name.replace("[]","").substr(-3);
|
||||||
@ -220,7 +200,7 @@
|
|||||||
}
|
}
|
||||||
// https://stackoverflow.com/questions/39729741/javascript-change-input-text-to-select-option
|
// https://stackoverflow.com/questions/39729741/javascript-change-input-text-to-select-option
|
||||||
function addDD(um,fld) {
|
function addDD(um,fld) {
|
||||||
let sel = d.createElement('select');
|
let sel = cE('select');
|
||||||
if (typeof(fld) === "string") { // parameter from usermod (field name)
|
if (typeof(fld) === "string") { // parameter from usermod (field name)
|
||||||
if (fld.includes("pin")) sel.classList.add("pin");
|
if (fld.includes("pin")) sel.classList.add("pin");
|
||||||
um += ":"+fld;
|
um += ":"+fld;
|
||||||
@ -258,7 +238,7 @@
|
|||||||
var addDropdown = addDD; // backwards compatibility
|
var addDropdown = addDD; // backwards compatibility
|
||||||
function addO(sel,txt,val) {
|
function addO(sel,txt,val) {
|
||||||
if (sel===null) return; // select object missing
|
if (sel===null) return; // select object missing
|
||||||
let opt = d.createElement("option");
|
let opt = cE("option");
|
||||||
opt.value = val;
|
opt.value = val;
|
||||||
opt.text = txt;
|
opt.text = txt;
|
||||||
sel.appendChild(opt);
|
sel.appendChild(opt);
|
||||||
@ -284,34 +264,6 @@
|
|||||||
function addHB(um) {
|
function addHB(um) {
|
||||||
addI(um + ':help',0,`<button onclick="location.href='https://kno.wled.ge/usermods/${um}'" type="button">?</button>`);
|
addI(um + ':help',0,`<button onclick="location.href='https://kno.wled.ge/usermods/${um}'" type="button">?</button>`);
|
||||||
}
|
}
|
||||||
// load settings and insert values into DOM
|
|
||||||
function ldS() {
|
|
||||||
fetch(getURL('/cfg.json'), {
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
if (!res.ok) gId('lserr').style.display = "inline";
|
|
||||||
return res.json();
|
|
||||||
})
|
|
||||||
.then(json => {
|
|
||||||
umCfg = json.um;
|
|
||||||
getPins(json);
|
|
||||||
urows="";
|
|
||||||
if (isO(umCfg)) {
|
|
||||||
for (const [k,o] of Object.entries(umCfg)) {
|
|
||||||
urows += `<hr><h3>${k}</h3>`;
|
|
||||||
addField(k,'unknown',o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (urows==="") urows = "Usermods configuration not found.<br>Press <i>Save</i> to initialize defaults.";
|
|
||||||
gId("um").innerHTML = urows;
|
|
||||||
loadJS(getURL('/settings/s.js?p=8'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
|
||||||
})
|
|
||||||
.catch((error)=>{
|
|
||||||
gId('lserr').style.display = "inline";
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function svS(e) {
|
function svS(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (d.Sf.checkValidity()) d.Sf.submit(); //https://stackoverflow.com/q/37323914
|
if (d.Sf.checkValidity()) d.Sf.submit(); //https://stackoverflow.com/q/37323914
|
||||||
|
@ -4,16 +4,10 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
|
||||||
<title>WiFi Settings</title>
|
<title>WiFi Settings</title>
|
||||||
|
<script src="common.js" async type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
var d = document;
|
|
||||||
var loc = false, locip, locproto = "http:";
|
|
||||||
var scanLoops = 0, preScanSSID = "";
|
var scanLoops = 0, preScanSSID = "";
|
||||||
var maxNetworks = 3;
|
var maxNetworks = 3;
|
||||||
function gId(e) { return d.getElementById(e); }
|
|
||||||
function cE(e) { return d.createElement(e); }
|
|
||||||
function toggle(el){gId(el).classList.toggle("hide"); gId('No'+el).classList.toggle("hide");}
|
|
||||||
function H(){window.open("https://kno.wled.ge/features/settings/#wifi-settings");}
|
|
||||||
function B(){window.open(getURL("/settings"),"_self");}
|
|
||||||
function N() {
|
function N() {
|
||||||
const button = gId("scan");
|
const button = gId("scan");
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
@ -137,58 +131,18 @@ Static subnet mask:<br>
|
|||||||
entries[i-1].remove();
|
entries[i-1].remove();
|
||||||
btnWiFi(i-1);
|
btnWiFi(i-1);
|
||||||
}
|
}
|
||||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
|
||||||
function loadJS(FILE_URL, async = true) {
|
|
||||||
let scE = cE("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();
|
|
||||||
});
|
|
||||||
// error event
|
|
||||||
scE.addEventListener("error", (ev) => {
|
|
||||||
console.log("Error on loading file", ev);
|
|
||||||
alert("Loading of configuration script failed.\nIncomplete page data!");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function S() {
|
function S() {
|
||||||
let l = window.location;
|
getLoc();
|
||||||
if (l.protocol == "file:") {
|
|
||||||
loc = true;
|
|
||||||
locip = localStorage.getItem('locIp');
|
|
||||||
if (!locip) {
|
|
||||||
locip = prompt("File Mode. Please enter WLED IP!");
|
|
||||||
localStorage.setItem('locIp', locip);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// detect reverse proxy
|
|
||||||
let path = l.pathname;
|
|
||||||
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
|
|
||||||
if (paths.length > 2) {
|
|
||||||
paths.pop(); // remove "wifi"
|
|
||||||
paths.pop(); // remove "settings"
|
|
||||||
locproto = l.protocol;
|
|
||||||
loc = true;
|
|
||||||
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadJS(getURL('/settings/s.js?p=1'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
loadJS(getURL('/settings/s.js?p=1'), false); // If we set async false, file is loaded and executed, then next statement is processed
|
||||||
if (loc) d.Sf.action = getURL('/settings/wifi');
|
if (loc) d.Sf.action = getURL('/settings/wifi');
|
||||||
}
|
}
|
||||||
function getURL(path) {
|
|
||||||
return (loc ? locproto + "//" + locip : "") + path;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style>@import url("style.css");</style>
|
<style>@import url("style.css");</style>
|
||||||
</head>
|
</head>
|
||||||
<body onload="S()">
|
<body onload="S()">
|
||||||
<form id="form_s" name="Sf" method="post">
|
<form id="form_s" name="Sf" method="post">
|
||||||
<div class="toprow">
|
<div class="toprow">
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H('features/settings/#wifi-settings')">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button><hr>
|
||||||
</div>
|
</div>
|
||||||
<h2>WiFi setup</h2>
|
<h2>WiFi setup</h2>
|
||||||
|
@ -18,6 +18,7 @@ static const char s_unlock_ota [] PROGMEM = "Please unlock OTA in security setti
|
|||||||
static const char s_unlock_cfg [] PROGMEM = "Please unlock settings using PIN code!";
|
static const char s_unlock_cfg [] PROGMEM = "Please unlock settings using PIN code!";
|
||||||
static const char s_notimplemented[] PROGMEM = "Not implemented";
|
static const char s_notimplemented[] PROGMEM = "Not implemented";
|
||||||
static const char s_accessdenied[] PROGMEM = "Access Denied";
|
static const char s_accessdenied[] PROGMEM = "Access Denied";
|
||||||
|
static const char _common_js[] PROGMEM = "/common.js";
|
||||||
|
|
||||||
//Is this an IP?
|
//Is this an IP?
|
||||||
static bool isIp(String str) {
|
static bool isIp(String str) {
|
||||||
@ -237,6 +238,10 @@ void initServer()
|
|||||||
handleStaticContent(request, "", 200, FPSTR(CONTENT_TYPE_HTML), PAGE_liveview, PAGE_liveview_length);
|
handleStaticContent(request, "", 200, FPSTR(CONTENT_TYPE_HTML), PAGE_liveview, PAGE_liveview_length);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.on(_common_js, HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
handleStaticContent(request, FPSTR(_common_js), 200, FPSTR(CONTENT_TYPE_JAVASCRIPT), JS_common, JS_common_length);
|
||||||
|
});
|
||||||
|
|
||||||
//settings page
|
//settings page
|
||||||
server.on(F("/settings"), HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on(F("/settings"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveSettings(request);
|
serveSettings(request);
|
||||||
@ -511,6 +516,10 @@ void serveJsonError(AsyncWebServerRequest* request, uint16_t code, uint16_t erro
|
|||||||
|
|
||||||
void serveSettingsJS(AsyncWebServerRequest* request)
|
void serveSettingsJS(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
|
if (request->url().indexOf(FPSTR(_common_js)) > 0) {
|
||||||
|
handleStaticContent(request, FPSTR(_common_js), 200, FPSTR(CONTENT_TYPE_JAVASCRIPT), JS_common, JS_common_length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
char buf[SETTINGS_STACK_BUF_SIZE+37];
|
char buf[SETTINGS_STACK_BUF_SIZE+37];
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
byte subPage = request->arg(F("p")).toInt();
|
byte subPage = request->arg(F("p")).toInt();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user