From 2e9bd477d921607e50c7d863145946988f849512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Mon, 26 Jul 2021 00:10:36 +0200 Subject: [PATCH] Upload files & skinning (#2084) * Skinning WLED & uploading files. Backup & restore configuration & presets. External holidays.json * Option for segment count instead of stop. * Small fixes and improvements * Further improvements * Enable custom CSS by default Co-authored-by: Christian Schwinne --- wled00/data/index.js | 74 +- wled00/data/settings_leds.htm | 28 +- wled00/data/settings_sec.htm | 39 + wled00/data/settings_ui.htm | 66 +- wled00/data/style.css | 47 +- wled00/file.cpp | 2 +- wled00/html_settings.h | 60 +- wled00/html_ui.h | 1615 +++++++++++++++++---------------- wled00/wled.h | 2 +- wled00/wled_server.cpp | 55 +- 10 files changed, 1107 insertions(+), 881 deletions(-) diff --git a/wled00/data/index.js b/wled00/data/index.js index 40111e78..418dbb11 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -26,8 +26,16 @@ var ws; var fxlist = d.getElementById('fxlist'), pallist = d.getElementById('pallist'); var cfg = { theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}}, - comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, labels:true, pcmbot:false, pid:true} + comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, + labels:true, pcmbot:false, pid:true, seglen:false, css:true, hdays:false} }; +var hol = [ + [0,11,24,4,"https://aircoookie.github.io/xmas.png"], // christmas + [0,2,17,1,"https://images.alphacoders.com/491/491123.jpg"], // st. Patrick's day + [2022,3,17,2,"https://aircoookie.github.io/easter.png"], + [2023,3,9,2,"https://aircoookie.github.io/easter.png"], + [2024,2,31,2,"https://aircoookie.github.io/easter.png"] +]; var cpick = new iro.ColorPicker("#picker", { width: 260, @@ -158,13 +166,6 @@ function loadBg(iUrl) { img.src = iUrl; if (iUrl == "") { var today = new Date(); - var hol = [ - [0,11,24,4,"https://aircoookie.github.io/xmas.png"], // christmas - [0,2,17,1,"https://images.alphacoders.com/491/491123.jpg"], // st. Patrick's day - [2022,3,17,2,"https://aircoookie.github.io/easter.png"], - [2023,3,9,2,"https://aircoookie.github.io/easter.png"], - [2024,2,31,2,"https://aircoookie.github.io/easter.png"] - ]; for (var i=0; i { + //if (!res.ok) showErrorToast(); + return res.json(); + }) + .then(json => { + if (Array.isArray(json)) hol = json; + //TODO: do some parsing first + }) + .catch(function (error) { + console.log("holidays.json does not contain array of holidays. Defaults loaded."); + }) + .finally(function(){ + loadBg(cfg.theme.bg.url); + }); + } else + loadBg(cfg.theme.bg.url); + if (cfg.comp.css) loadSkinCSS('skinCss'); var cd = d.getElementById('csl').children; for (var i = 0; i < cd.length; i++) { @@ -211,7 +247,7 @@ function onLoad() { setColor(1); }); pmtLS = localStorage.getItem('wledPmt'); - setTimeout(function(){requestJson(null, false);}, 25); + setTimeout(function(){requestJson(null, false);}, 50); d.addEventListener("visibilitychange", handleVisibilityChange, false); size(); d.getElementById("cv").style.opacity=0; @@ -557,12 +593,12 @@ function populateSegments(s) - + - +
Start LEDStop LED${cfg.comp.seglen?"Length":"Stop LED"} Offset
@@ -661,13 +697,12 @@ function populatePalettes(palettes) var html = ``; for (let i = 0; i < palettes.length; i++) { - let previewCss = genPalPrevCss(palettes[i].id); html += generateListItemHtml( 'palette', palettes[i].id, palettes[i].name, 'setPalette', - `
`, + `
`, palettes[i].class, ); } @@ -693,7 +728,6 @@ function genPalPrevCss(id) return; } var paletteData = palettesData[id]; - var previewCss = ""; if (!paletteData) { return 'display: none'; @@ -855,7 +889,7 @@ function updateLen(s) if (!d.getElementById(`seg${s}s`)) return; var start = parseInt(d.getElementById(`seg${s}s`).value); var stop = parseInt(d.getElementById(`seg${s}e`).value); - var len = stop - start; + var len = stop - (cfg.comp.seglen?0:start); var out = "(delete)"; if (len > 1) { out = `${len} LEDs`; @@ -1218,7 +1252,7 @@ function toggleNodes() { function makeSeg() { var ns = 0; if (lowestUnused > 0) { - var pend = d.getElementById(`seg${lowestUnused -1}e`).value; + var pend = parseInt(d.getElementById(`seg${lowestUnused -1}e`).value,10) + (cfg.comp.seglen?parseInt(d.getElementById(`seg${lowestUnused -1}s`).value,10):0); if (pend < ledCount) ns = pend; } var cn = `
@@ -1230,11 +1264,11 @@ function makeSeg() { - + - +
Start LEDStop LED${cfg.comp.seglen?"Length":"Stop LED"}
${ledCount - ns} LED${ledCount - ns >1 ? "s":""}
@@ -1467,7 +1501,7 @@ function setSeg(s){ var start = parseInt(d.getElementById(`seg${s}s`).value); var stop = parseInt(d.getElementById(`seg${s}e`).value); if (stop <= start) {delSeg(s); return;} - var obj = {"seg": {"id": s, "start": start, "stop": stop}}; + var obj = {"seg": {"id": s, "start": start, "stop": (cfg.comp.seglen?start:0)+stop}}; if (d.getElementById(`seg${s}grp`)) { var grp = parseInt(d.getElementById(`seg${s}grp`).value); diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 6c59929f..2dfb6ab2 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -18,6 +18,16 @@ function off(n){ d.getElementsByName(n)[0].value = -1; } + 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 bLimits(b,p,m) { maxB = b; maxM = m; maxPB = p; } @@ -204,6 +214,7 @@ s2 += "A is enough)
"; gId('psu').innerHTML = s; gId('psu2').innerHTML = isWS2815 ? "" : s2; + gId("json").style.display = d.Sf.IT.value==8 ? "" : "none"; } function lastEnd(i) { if (i<1) return 0; @@ -293,6 +304,17 @@ Reverse (rotated 180°): c += ``; c += ` ×
`; gId("btns").innerHTML = c; + } + function uploadFile(name) { + var req = new XMLHttpRequest(); + req.addEventListener('load', function(){showToast(this.responseText)}); + req.addEventListener('error', function(e){showToast(e.stack,true);}); + req.open("POST", "/upload"); + var formData = new FormData(); + formData.append("data", d.Sf.data.files[0], name); + req.send(formData); + d.Sf.data.value = ''; + return false; } function GetV() { @@ -350,7 +372,7 @@ Reverse (rotated 180°):

Touch threshold:
- IR pin:     ×
+ +
IR info
Relay pin: Invert  ×

@@ -404,7 +428,7 @@ Reverse (rotated 180°):

- + diff --git a/wled00/data/settings_sec.htm b/wled00/data/settings_sec.htm index 22c4386e..27f36f12 100644 --- a/wled00/data/settings_sec.htm +++ b/wled00/data/settings_sec.htm @@ -5,6 +5,7 @@ Misc Settings - +
@@ -198,7 +216,7 @@

Web Setup

Server description:
- Sync button toggles both send and receive:
+ Sync button toggles both send and receive:
The following UI customization settings are unique both to the WLED device and this browser.
You will need to set them again if using a different browser, device or WLED IP address.
Refresh the main UI to apply changes.

@@ -207,8 +225,9 @@

UI Appearance

:
- :
- :
+ :
+ :
+ :
I hate dark mode:
:
@@ -217,6 +236,11 @@ BG image URL:
Random BG image:
+ :
+
Custom CSS:
+ :
+
Holidays:
+

diff --git a/wled00/data/style.css b/wled00/data/style.css index 5a6196c6..7f633439 100644 --- a/wled00/data/style.css +++ b/wled00/data/style.css @@ -9,16 +9,20 @@ body { hr { border-color: #666; } -button { +button, .btn { background: #333; color: #fff; font-family: Verdana, sans-serif; border: 0.3ch solid #333; display: inline-block; font-size: 20px; - margin: 8px; - margin-top: 12px; + margin: 12px 8px 8px; + padding: 1px 6px; cursor: pointer; + text-decoration: none; +} +.lnk { + border: 0; } .helpB { text-align: left; @@ -42,16 +46,16 @@ input[type="number"].xl { width: 85px; } input[type="number"].l { - width: 60px; + width: 63px; } input[type="number"].m { - width: 55px; + width: 56px; } input[type="number"].s { - width: 42px; + width: 49px; } input[type="number"].xs { - width: 35px; + width: 42px; } input[type="checkbox"] { transform: scale(1.5); @@ -69,3 +73,32 @@ td { .d5 { width: 4.5em !important; } + +#toast { + opacity: 0; + background-color: #444; + border-radius: 5px; + bottom: 64px; + color: #fff; + font-size: 17px; + padding: 16px; + pointer-events: none; + position: fixed; + text-align: center; + z-index: 5; + transform: translateX(-50%%); /* %% because of AsyncWebServer */ + max-width: 90%%; /* %% because of AsyncWebServer */ + left: 50%%; /* %% because of AsyncWebServer */ +} + +#toast.show { + opacity: 1; + background-color: #264; + animation: fadein 0.5s, fadein 0.5s 2.5s reverse; +} + +#toast.error { + opacity: 1; + background-color: #b21; + animation: fadein 0.5s; +} diff --git a/wled00/file.cpp b/wled00/file.cpp index e6c0d2cd..0d0f59ca 100644 --- a/wled00/file.cpp +++ b/wled00/file.cpp @@ -379,7 +379,7 @@ String getContentType(AsyncWebServerRequest* request, String filename){ if(request->hasArg("download")) return "application/octet-stream"; else if(filename.endsWith(".htm")) return "text/html"; else if(filename.endsWith(".html")) return "text/html"; -// else if(filename.endsWith(".css")) return "text/css"; + else if(filename.endsWith(".css")) return "text/css"; // else if(filename.endsWith(".js")) return "application/javascript"; else if(filename.endsWith(".json")) return "application/json"; else if(filename.endsWith(".png")) return "image/png"; diff --git a/wled00/html_settings.h b/wled00/html_settings.h index d8722f20..51e331d9 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -6,7 +6,7 @@ */ // Autogenerated from wled00/data/style.css, do not edit!! -const char PAGE_settingsCss[] PROGMEM = R"=====()====="; +const char PAGE_settingsCss[] PROGMEM = R"=====()====="; // Autogenerated from wled00/data/settings.htm, do not edit!! @@ -77,7 +77,7 @@ onclick="B()">Back // Autogenerated from wled00/data/settings_leds.htm, do not edit!! const char PAGE_settings_leds[] PROGMEM = R"=====(LED Settings