Boot splash and periodic announcement banner

Splash: resources/splash/splash.gif built into the binary, played once by
SplashOverlay over a black cover present from the first frame (no UI
flash), then fades into the UI; hides icons loading. GIF, so no
QtMultimedia/gstreamer. Toggle: splash.enabled.

Banner (InfoBanner): metro-style band that fades/slides in with a hold
pictogram; text that does not fit runs as a seamless ticker for two
rounds. Never takes touches; hidden during splash and settings. Config
section banner (enabled, text, intervalSec, showSec, position,
accentColor), editable in the web UI and on-device settings; shown once
after saving.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-10 10:58:16 +00:00
co-authored by Claude Opus 5.5
parent ec84133417
commit f07e153f09
22 changed files with 753 additions and 3 deletions
+10 -1
View File
@@ -49,6 +49,15 @@ def _defaults():
"pendingColor": "#ffffff",
"pendingWidth": 6,
},
"banner": {
"enabled": False,
"text": "Для вызова клининга удерживайте кнопку",
"intervalSec": 180,
"showSec": 10,
"position": "bottom",
"accentColor": "#e4002b",
},
"splash": {"enabled": True},
"settings": {
"darkMode": True,
"password": "admin_26",
@@ -68,7 +77,7 @@ def ensure_defaults(cfg):
if not isinstance(cfg, dict):
return base
cfg.setdefault("version", base["version"])
for section in ("layout", "background", "feedback", "settings"):
for section in ("layout", "background", "feedback", "banner", "splash", "settings"):
sec = cfg.setdefault(section, {})
if not isinstance(sec, dict):
sec = {}