Merge branch '0_15' into suspend

This commit is contained in:
Blaz Kristan
2024-01-09 18:30:27 +01:00
16 changed files with 634 additions and 231 deletions

View File

@@ -282,7 +282,7 @@
#define FX_MODE_RIPPLEPEAK 148
#define FX_MODE_2DFIRENOISE 149
#define FX_MODE_2DSQUAREDSWIRL 150
#define FX_MODE_2DFIRE2012 151
// #define FX_MODE_2DFIRE2012 151
#define FX_MODE_2DDNA 152
#define FX_MODE_2DMATRIX 153
#define FX_MODE_2DMETABALLS 154
@@ -292,7 +292,7 @@
#define FX_MODE_GRAVFREQ 158
#define FX_MODE_DJLIGHT 159
#define FX_MODE_2DFUNKYPLANK 160
#define FX_MODE_2DCENTERBARS 161
//#define FX_MODE_2DCENTERBARS 161
#define FX_MODE_2DPULSER 162
#define FX_MODE_BLURZ 163
#define FX_MODE_2DDRIFT 164

View File

@@ -785,7 +785,7 @@ input[type=range]::-moz-range-thumb {
#picker {
margin-top: 8px !important;
max-width: 260px;
max-width: max-content;
}
/* buttons */
@@ -1566,9 +1566,6 @@ dialog {
max-width: 280px;
font-size: 18px;
}
#picker {
width: 230px;
}
#putil .btn-s {
width: 114px;
}

View File

@@ -32,13 +32,14 @@ var cfg = {
labels:true, pcmbot:false, pid:true, seglen:false, segpwr:false, segexp:false,
css:true, hdays:false, fxdef:true, on:0, off:0, idsort: false}
};
// [year, month (0 -> January, 11 -> December), day, duration in days, image url]
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
[2025,3,20,2,"https://aircoookie.github.io/easter.png"],
[2024,2,31,2,"https://aircoookie.github.io/easter.png"],
[0,6,4,1,"https://images.alphacoders.com/516/516792.jpg"], // 4th of July
[0,0,1,1,"https://images.alphacoders.com/119/1198800.jpg"] // new year
[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
[2025, 3, 20, 2, "https://aircoookie.github.io/easter.png"], // easter 2025
[2024, 2, 31, 2, "https://aircoookie.github.io/easter.png"], // easter 2024
[0, 6, 4, 1, "https://images.alphacoders.com/516/516792.jpg"], // 4th of July
[0, 0, 1, 1, "https://images.alphacoders.com/119/1198800.jpg"] // new year
];
var cpick = new iro.ColorPicker("#picker", {
@@ -175,19 +176,19 @@ function cTheme(light) {
}
}
function loadBg(iUrl)
{
let bg = gId('bg');
let img = d.createElement("img");
function loadBg() {
const { url: iUrl, rnd: iRnd } = cfg.theme.bg;
const bg = gId('bg');
const img = d.createElement("img");
img.src = iUrl;
if (iUrl == "" || iUrl==="https://picsum.photos/1920/1080") {
var today = new Date();
for (var h of (hol||[])) {
var yr = h[0]==0 ? today.getFullYear() : h[0];
var hs = new Date(yr,h[1],h[2]);
var he = new Date(hs);
he.setDate(he.getDate() + h[3]);
if (today>=hs && today<=he) img.src = h[4];
if (!iUrl || iRnd) {
const today = new Date();
for (const holiday of (hol || [])) {
const year = holiday[0] == 0 ? today.getFullYear() : holiday[0];
const holidayStart = new Date(year, holiday[1], holiday[2]);
const holidayEnd = new Date(holidayStart);
holidayEnd.setDate(holidayEnd.getDate() + holiday[3]);
if (today >= holidayStart && today <= holidayEnd) img.src = holiday[4];
}
}
img.addEventListener('load', (e) => {
@@ -195,7 +196,6 @@ function loadBg(iUrl)
if (isNaN(a)) a = 0.6;
bg.style.opacity = a;
bg.style.backgroundImage = `url(${img.src})`;
img = null;
gId('namelabel').style.color = "var(--c-c)"; // improve namelabel legibility on background image
});
}
@@ -266,10 +266,10 @@ function onLoad()
console.log("No array of holidays in holidays.json. Defaults loaded.");
})
.finally(()=>{
loadBg(cfg.theme.bg.url);
loadBg();
});
} else
loadBg(cfg.theme.bg.url);
loadBg();
selectSlot(0);
updateTablinks(0);

View File

@@ -360,6 +360,22 @@ um_data_t* simulateSound(uint8_t simulationId);
void enumerateLedmaps();
uint8_t get_random_wheel_index(uint8_t pos);
// RAII guard class for the JSON Buffer lock
// Modeled after std::lock_guard
class JSONBufferGuard {
bool holding_lock;
public:
inline JSONBufferGuard(uint8_t module=255) : holding_lock(requestJSONBufferLock(module)) {};
inline ~JSONBufferGuard() { if (holding_lock) releaseJSONBufferLock(); };
inline JSONBufferGuard(const JSONBufferGuard&) = delete; // Noncopyable
inline JSONBufferGuard& operator=(const JSONBufferGuard&) = delete;
inline JSONBufferGuard(JSONBufferGuard&& r) : holding_lock(r.holding_lock) { r.holding_lock = false; }; // but movable
inline JSONBufferGuard& operator=(JSONBufferGuard&& r) { holding_lock |= r.holding_lock; r.holding_lock = false; return *this; };
inline bool owns_lock() const { return holding_lock; }
explicit inline operator bool() const { return owns_lock(); };
inline void release() { if (holding_lock) releaseJSONBufferLock(); holding_lock = false; }
};
#ifdef WLED_ADD_EEPROM_SUPPORT
//wled_eeprom.cpp
void applyMacro(byte index);

View File

@@ -209,7 +209,14 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
#endif
byte fx = seg.mode;
if (getVal(elem["fx"], &fx, 0, strip.getModeCount())) { //load effect ('r' random, '~' inc/dec, 0-255 exact value)
byte last = strip.getModeCount();
// partial fix for #3605
if (!elem["fx"].isNull() && elem["fx"].is<const char*>()) {
const char *tmp = elem["fx"].as<const char *>();
if (strlen(tmp) > 3 && (strchr(tmp,'r') || strchr(tmp,'~') != strrchr(tmp,'~'))) last = 0; // we have "X~Y(r|[w]~[-])" form
}
// end fix
if (getVal(elem["fx"], &fx, 0, last)) { //load effect ('r' random, '~' inc/dec, 0-255 exact value, 5~10r pick random between 5 & 10)
if (!presetId && currentPlaylist>=0) unloadPlaylist();
if (fx != seg.mode) seg.setMode(fx, elem[F("fxdef")]);
}
@@ -1010,15 +1017,19 @@ void serializeModeNames(JsonArray arr)
}
}
static volatile bool servingClient = false;
// Global buffer locking response helper class
class GlobalBufferAsyncJsonResponse: public JSONBufferGuard, public AsyncJsonResponse {
public:
inline GlobalBufferAsyncJsonResponse(bool isArray) : JSONBufferGuard(17), AsyncJsonResponse(pDoc, isArray) {};
virtual ~GlobalBufferAsyncJsonResponse() {};
// Other members are inherited
};
void serveJson(AsyncWebServerRequest* request)
{
if (servingClient) {
serveJsonError(request, 503, ERR_CONCURRENCY);
return;
}
servingClient = true;
byte subJson = 0;
const String& url = request->url();
if (url.indexOf("state") > 0) subJson = JSON_PATH_STATE;
@@ -1032,31 +1043,27 @@ void serveJson(AsyncWebServerRequest* request)
#ifdef WLED_ENABLE_JSONLIVE
else if (url.indexOf("live") > 0) {
serveLiveLeds(request);
servingClient = false;
return;
}
#endif
else if (url.indexOf("pal") > 0) {
request->send_P(200, "application/json", JSON_palette_names);
servingClient = false;
return;
}
else if (url.indexOf("cfg") > 0 && handleFileRead(request, "/cfg.json")) {
servingClient = false;
return;
}
else if (url.length() > 6) { //not just /json
serveJsonError(request, 501, ERR_NOT_IMPL);
servingClient = false;
return;
}
if (!requestJSONBufferLock(17)) {
GlobalBufferAsyncJsonResponse *response = new GlobalBufferAsyncJsonResponse(subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary
if (!response->owns_lock()) {
serveJsonError(request, 503, ERR_NOBUF);
servingClient = false;
delete response;
return;
}
AsyncJsonResponse *response = new AsyncJsonResponse(pDoc, subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary
JsonVariant lDoc = response->getRoot();
@@ -1099,8 +1106,6 @@ void serveJson(AsyncWebServerRequest* request)
DEBUG_PRINT(F("JSON content length: ")); DEBUG_PRINTLN(len);
request->send(response);
releaseJSONBufferLock();
servingClient = false;
}
#ifdef WLED_ENABLE_JSONLIVE

View File

@@ -41,7 +41,7 @@ enum struct PinOwner : uint8_t {
UM_Temperature = USERMOD_ID_TEMPERATURE, // 0x03 // Usermod "usermod_temperature.h"
// #define USERMOD_ID_FIXNETSERVICES // 0x04 // Usermod "usermod_Fix_unreachable_netservices.h" -- Does not allocate pins
UM_PIR = USERMOD_ID_PIRSWITCH, // 0x05 // Usermod "usermod_PIR_sensor_switch.h"
// #define USERMOD_ID_IMU // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Uses "standard" HW_I2C pins
UM_IMU = USERMOD_ID_IMU, // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Interrupt pin
UM_FourLineDisplay = USERMOD_ID_FOUR_LINE_DISP, // 0x07 // Usermod "usermod_v2_four_line_display.h -- May use "standard" HW_I2C pins
UM_RotaryEncoderUI = USERMOD_ID_ROTARY_ENC_UI, // 0x08 // Usermod "usermod_v2_rotary_encoder_ui.h"
// #define USERMOD_ID_AUTO_SAVE // 0x09 // Usermod "usermod_v2_auto_save.h" -- Does not allocate pins

View File

@@ -436,6 +436,8 @@ void exitRealtime() {
realtimeIP[0] = 0;
if (useMainSegmentOnly) { // unfreeze live segment again
strip.getMainSegment().freeze = false;
} else {
strip.show(); // possible fix for #3589
}
updateInterfaces(CALL_MODE_WS_SEND);
}

View File

@@ -197,6 +197,13 @@
#include "../usermods/pwm_outputs/usermod_pwm_outputs.h"
#endif
#ifdef USERMOD_MPU6050_IMU
#include "../usermods/mpu6050_imu/usermod_mpu6050_imu.h"
#endif
#ifdef USERMOD_MPU6050_IMU
#include "../usermods/mpu6050_imu/usermod_gyro_surge.h"
#endif
void registerUsermods()
{
@@ -206,6 +213,7 @@ void registerUsermods()
* \/ \/ \/
*/
//usermods.add(new MyExampleUsermod());
#ifdef USERMOD_BATTERY
usermods.add(new UsermodBattery());
#endif
@@ -373,4 +381,12 @@ void registerUsermods()
#ifdef USERMOD_INTERNAL_TEMPERATURE
usermods.add(new InternalTemperatureUsermod());
#endif
#ifdef USERMOD_MPU6050_IMU
static MPU6050Driver mpu6050; usermods.add(&mpu6050);
#endif
#ifdef USERMOD_GYRO_SURGE
static GyroSurge gyro_surge; usermods.add(&gyro_surge);
#endif
}

View File

@@ -8,7 +8,7 @@
*/
// version code in format yymmddb (b = daily build)
#define VERSION 2401040
#define VERSION 2401060
//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG

View File

@@ -15,8 +15,9 @@
* Integrated HTTP web server page declarations
*/
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request);
void setStaticContentCacheHeaders(AsyncWebServerResponse *response);
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request, int code, uint16_t eTagSuffix = 0);
void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix = 0);
void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip = true, uint16_t eTagSuffix = 0);
// define flash strings once (saves flash memory)
static const char s_redirecting[] PROGMEM = "Redirecting...";
@@ -113,22 +114,14 @@ void initServer()
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Headers"), "*");
#ifdef WLED_ENABLE_WEBSOCKETS
#ifndef WLED_DISABLE_2D
server.on("/liveview2D", HTTP_GET, [](AsyncWebServerRequest *request){
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_liveviewws2D, PAGE_liveviewws2D_length);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
request->send(response);
#ifndef WLED_DISABLE_2D
server.on("/liveview2D", HTTP_GET, [](AsyncWebServerRequest *request) {
handleStaticContent(request, "", 200, "text/html", PAGE_liveviewws2D, PAGE_liveviewws2D_length);
});
#endif
#endif
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_liveview, PAGE_liveview_length);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
request->send(response);
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request) {
handleStaticContent(request, "", 200, "text/html", PAGE_liveview, PAGE_liveview_length);
});
//settings page
@@ -138,17 +131,12 @@ void initServer()
// "/settings/settings.js&p=x" request also handled by serveSettings()
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
request->send(response);
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request) {
handleStaticContent(request, "/style.css", 200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length);
});
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request) {
if (handleFileRead(request, "/favicon.ico")) return;
request->send_P(200, "image/x-icon", favicon, 156);
handleStaticContent(request, "/favicon.ico", 200, "image/x-icon", favicon, favicon_length, false);
});
server.on("/skin.css", HTTP_GET, [](AsyncWebServerRequest *request) {
@@ -236,12 +224,8 @@ void initServer()
});
#ifdef WLED_ENABLE_USERMOD_PAGE
server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request){
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_usermod, PAGE_usermod_length);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
request->send(response);
server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request) {
handleStaticContent(request, "", 200, "text/html", PAGE_usermod, PAGE_usermod_length);
});
#endif
@@ -327,44 +311,29 @@ void initServer()
});
#endif
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
if (captivePortal(request)) return;
if (!showWelcomePage || request->hasArg(F("sliders"))){
serveIndex(request);
if (!showWelcomePage || request->hasArg(F("sliders"))) {
handleStaticContent(request, "/index.htm", 200, "text/html", PAGE_index, PAGE_index_L);
} else {
serveSettings(request);
}
});
#ifdef WLED_ENABLE_PIXART
server.on("/pixart.htm", HTTP_GET, [](AsyncWebServerRequest *request){
if (handleFileRead(request, "/pixart.htm")) return;
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_pixart, PAGE_pixart_L);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
request->send(response);
#ifdef WLED_ENABLE_PIXART
server.on("/pixart.htm", HTTP_GET, [](AsyncWebServerRequest *request) {
handleStaticContent(request, "/pixart.htm", 200, "text/html", PAGE_pixart, PAGE_pixart_L);
});
#endif
#ifndef WLED_DISABLE_PXMAGIC
server.on("/pxmagic.htm", HTTP_GET, [](AsyncWebServerRequest *request){
if (handleFileRead(request, "/pxmagic.htm")) return;
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_pxmagic, PAGE_pxmagic_L);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
request->send(response);
#ifndef WLED_DISABLE_PXMAGIC
server.on("/pxmagic.htm", HTTP_GET, [](AsyncWebServerRequest *request) {
handleStaticContent(request, "/pxmagic.htm", 200, "text/html", PAGE_pxmagic, PAGE_pxmagic_L);
});
#endif
#endif
server.on("/cpal.htm", HTTP_GET, [](AsyncWebServerRequest *request){
if (handleFileRead(request, "/cpal.htm")) return;
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_cpal, PAGE_cpal_L);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
request->send(response);
server.on("/cpal.htm", HTTP_GET, [](AsyncWebServerRequest *request) {
handleStaticContent(request, "/cpal.htm", 200, "text/html", PAGE_cpal, PAGE_cpal_L);
});
#ifdef WLED_ENABLE_WEBSOCKETS
@@ -390,26 +359,34 @@ void initServer()
#ifndef WLED_DISABLE_ALEXA
if(espalexa.handleAlexaApiCall(request)) return;
#endif
if(handleFileRead(request, request->url())) return;
AsyncWebServerResponse *response = request->beginResponse_P(404, "text/html", PAGE_404, PAGE_404_length);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
request->send(response);
handleStaticContent(request, request->url(), 404, "text/html", PAGE_404, PAGE_404_length);
});
}
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest *request) {
void generateEtag(char *etag, uint16_t eTagSuffix) {
sprintf_P(etag, PSTR("%7d-%02x-%04x"), VERSION, cacheInvalidate, eTagSuffix);
}
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest *request, int code, uint16_t eTagSuffix) {
// Only send 304 (Not Modified) if response code is 200 (OK)
if (code != 200) return false;
AsyncWebHeader *header = request->getHeader("If-None-Match");
char etag[11];
sprintf_P(etag, PSTR("%7d-%02x"), VERSION, cacheInvalidate);
char etag[14];
generateEtag(etag, eTagSuffix);
if (header && header->value() == etag) {
request->send(304);
AsyncWebServerResponse *response = request->beginResponse(304);
setStaticContentCacheHeaders(response, code, eTagSuffix);
request->send(response);
return true;
}
return false;
}
void setStaticContentCacheHeaders(AsyncWebServerResponse *response) {
void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix) {
// Only send ETag for 200 (OK) responses
if (code != 200) return;
// https://medium.com/@codebyamir/a-web-developers-guide-to-browser-caching-cc41f3b73e7c
#ifndef WLED_DEBUG
// this header name is misleading, "no-cache" will not disable cache,
@@ -418,25 +395,37 @@ void setStaticContentCacheHeaders(AsyncWebServerResponse *response) {
#else
response->addHeader(F("Cache-Control"), "no-store,max-age=0"); // prevent caching if debug build
#endif
char etag[11];
sprintf_P(etag, PSTR("%7d-%02x"), VERSION, cacheInvalidate);
char etag[14];
generateEtag(etag, eTagSuffix);
response->addHeader(F("ETag"), etag);
}
void serveIndex(AsyncWebServerRequest* request)
{
if (handleFileRead(request, "/index.htm")) return;
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_index, PAGE_index_L);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
/**
* Handels the request for a static file.
* If the file was found in the filesystem, it will be sent to the client.
* Otherwise it will be checked if the browser cached the file and if so, a 304 response will be sent.
* If the file was not found in the filesystem and not in the browser cache, the request will be handled as a 200 response with the content of the page.
*
* @param request The request object
* @param path If a file with this path exists in the filesystem, it will be sent to the client. Set to "" to skip this check.
* @param code The HTTP status code
* @param contentType The content type of the web page
* @param content Content of the web page
* @param len Length of the content
* @param gzip Optional. Defaults to true. If false, the gzip header will not be added.
* @param eTagSuffix Optional. Defaults to 0. A suffix that will be added to the ETag header. This can be used to invalidate the cache for a specific page.
*/
void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip, uint16_t eTagSuffix) {
if (path != "" && handleFileRead(request, path)) return;
if (handleIfNoneMatchCacheHeader(request, code, eTagSuffix)) return;
AsyncWebServerResponse *response = request->beginResponse_P(code, contentType, content, len);
if (gzip) response->addHeader(FPSTR(s_content_enc), "gzip");
setStaticContentCacheHeaders(response, code, eTagSuffix);
request->send(response);
}
String msgProcessor(const String& var)
{
if (var == "MSG") {
@@ -538,13 +527,11 @@ void serveSettingsJS(AsyncWebServerRequest* request)
}
void serveSettings(AsyncWebServerRequest* request, bool post)
{
void serveSettings(AsyncWebServerRequest* request, bool post) {
byte subPage = 0, originalSubPage = 0;
const String& url = request->url();
if (url.indexOf("sett") >= 0)
{
if (url.indexOf("sett") >= 0) {
if (url.indexOf(".js") > 0) subPage = SUBPAGE_JS;
else if (url.indexOf(".css") > 0) subPage = SUBPAGE_CSS;
else if (url.indexOf("wifi") > 0) subPage = SUBPAGE_WIFI;
@@ -605,22 +592,25 @@ void serveSettings(AsyncWebServerRequest* request, bool post)
}
}
AsyncWebServerResponse *response;
switch (subPage)
{
case SUBPAGE_WIFI : response = request->beginResponse_P(200, "text/html", PAGE_settings_wifi, PAGE_settings_wifi_length); break;
case SUBPAGE_LEDS : response = request->beginResponse_P(200, "text/html", PAGE_settings_leds, PAGE_settings_leds_length); break;
case SUBPAGE_UI : response = request->beginResponse_P(200, "text/html", PAGE_settings_ui, PAGE_settings_ui_length); break;
case SUBPAGE_SYNC : response = request->beginResponse_P(200, "text/html", PAGE_settings_sync, PAGE_settings_sync_length); break;
case SUBPAGE_TIME : response = request->beginResponse_P(200, "text/html", PAGE_settings_time, PAGE_settings_time_length); break;
case SUBPAGE_SEC : response = request->beginResponse_P(200, "text/html", PAGE_settings_sec, PAGE_settings_sec_length); break;
int code = 200;
String contentType = "text/html";
const uint8_t* content;
size_t len;
switch (subPage) {
case SUBPAGE_WIFI : content = PAGE_settings_wifi; len = PAGE_settings_wifi_length; break;
case SUBPAGE_LEDS : content = PAGE_settings_leds; len = PAGE_settings_leds_length; break;
case SUBPAGE_UI : content = PAGE_settings_ui; len = PAGE_settings_ui_length; break;
case SUBPAGE_SYNC : content = PAGE_settings_sync; len = PAGE_settings_sync_length; break;
case SUBPAGE_TIME : content = PAGE_settings_time; len = PAGE_settings_time_length; break;
case SUBPAGE_SEC : content = PAGE_settings_sec; len = PAGE_settings_sec_length; break;
#ifdef WLED_ENABLE_DMX
case SUBPAGE_DMX : response = request->beginResponse_P(200, "text/html", PAGE_settings_dmx, PAGE_settings_dmx_length); break;
case SUBPAGE_DMX : content = PAGE_settings_dmx; len = PAGE_settings_dmx_length; break;
#endif
case SUBPAGE_UM : response = request->beginResponse_P(200, "text/html", PAGE_settings_um, PAGE_settings_um_length); break;
case SUBPAGE_UPDATE : response = request->beginResponse_P(200, "text/html", PAGE_update, PAGE_update_length); break;
case SUBPAGE_UM : content = PAGE_settings_um; len = PAGE_settings_um_length; break;
case SUBPAGE_UPDATE : content = PAGE_update; len = PAGE_update_length; break;
#ifndef WLED_DISABLE_2D
case SUBPAGE_2D : response = request->beginResponse_P(200, "text/html", PAGE_settings_2D, PAGE_settings_2D_length); break;
case SUBPAGE_2D : content = PAGE_settings_2D; len = PAGE_settings_2D_length; break;
#endif
case SUBPAGE_LOCK : {
correctPIN = !strlen(settingsPIN); // lock if a pin is set
@@ -628,13 +618,11 @@ void serveSettings(AsyncWebServerRequest* request, bool post)
serveMessage(request, 200, strlen(settingsPIN) > 0 ? PSTR("Settings locked") : PSTR("No PIN set"), FPSTR(s_redirecting), 1);
return;
}
case SUBPAGE_PINREQ : response = request->beginResponse_P(401, "text/html", PAGE_settings_pin, PAGE_settings_pin_length); break;
case SUBPAGE_CSS : response = request->beginResponse_P(200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length); break;
case SUBPAGE_JS : serveSettingsJS(request); return;
case SUBPAGE_WELCOME : response = request->beginResponse_P(200, "text/html", PAGE_welcome, PAGE_welcome_length); break;
default: response = request->beginResponse_P(200, "text/html", PAGE_settings, PAGE_settings_length); break;
case SUBPAGE_PINREQ : content = PAGE_settings_pin; len = PAGE_settings_pin_length; code = 401; break;
case SUBPAGE_CSS : content = PAGE_settingsCss; len = PAGE_settingsCss_length; contentType = "text/css"; break;
case SUBPAGE_JS : serveSettingsJS(request); return;
case SUBPAGE_WELCOME : content = PAGE_welcome; len = PAGE_welcome_length; break;
default: content = PAGE_settings; len = PAGE_settings_length; break;
}
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
request->send(response);
handleStaticContent(request, "", code, contentType, content, len);
}