feat: blurred letterbox, portrait pairs, overlay metadata, button fixes

- Letterbox: extend edge pixels outward with blur + fade to solid color
- Portrait: detect and pair portraits side-by-side, fallback to solo
- Metadata: add overlay mode (corner badge), time field, custom date/time
  format strings (strftime), font size 1.5x, region-aware for pairs
- Buttons: swap G9/G10 to match physical layout, double-press random
  button for deep sleep, SLP indicator drawn before sleep
- Boot: remove redundant 'Loading photos' screen (saves 17s refresh)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-03 15:53:06 -04:00
parent 1d4f94426d
commit 0399573edf
13 changed files with 515 additions and 72 deletions

View File

@@ -282,6 +282,8 @@ void AppWebServer::handleGetSettings(AsyncWebServerRequest* request) {
doc["img_quality"] = static_cast<uint8_t>(s.img_quality);
doc["meta_flags"] = s.meta_flags;
doc["meta_pos"] = static_cast<uint8_t>(s.meta_pos);
doc["date_fmt"] = s.date_fmt;
doc["time_fmt"] = s.time_fmt;
doc["led_brightness"] = s.led_brightness;
doc["immich_url"] = s.immich_url;
doc["immich_key"] = s.immich_key;
@@ -308,6 +310,8 @@ void AppWebServer::handlePostSettings(AsyncWebServerRequest* request,
if (!doc["img_quality"].isNull()) s.img_quality = static_cast<ImageQuality>((uint8_t)doc["img_quality"]);
if (!doc["meta_flags"].isNull()) s.meta_flags = doc["meta_flags"];
if (!doc["meta_pos"].isNull()) s.meta_pos = static_cast<MetaPosition>((uint8_t)doc["meta_pos"]);
if (!doc["date_fmt"].isNull()) s.date_fmt = doc["date_fmt"].as<String>();
if (!doc["time_fmt"].isNull()) s.time_fmt = doc["time_fmt"].as<String>();
if (!doc["led_brightness"].isNull()) s.led_brightness = doc["led_brightness"];
if (!doc["immich_url"].isNull()) s.immich_url = doc["immich_url"].as<String>();
if (!doc["immich_key"].isNull()) s.immich_key = doc["immich_key"].as<String>();