state recovery, polling optimizations, error rendering

widget states cached to SQLite, loaded on startup to seed DataProjection
so server restart preserves last-known data for reconnecting clients.

polling: first poll runs immediately, widget list cached per-task with
30s refresh, static text polled once inline instead of looping.

poll failures propagate WidgetError::SourceUnavailable to clients.
render engine prepends [offline] prefix in accent color, stale data
preserved below.
This commit is contained in:
2026-06-19 12:56:12 +02:00
parent 8b1dac9669
commit 13497dd53c
12 changed files with 338 additions and 40 deletions

View File

@@ -2,7 +2,7 @@ use client_application::ClientApp;
use client_domain::NetworkPort;
use client_domain::{BoundingBox, DisplayPort, FontMetrics, RenderEngine, ThemeConfig};
use display_terminal::TerminalDisplay;
use domain::DisplayHint;
use domain::{DisplayHint, WidgetError};
use protocol::decode_server_message;
use std::sync::mpsc;
use std::thread;
@@ -85,7 +85,10 @@ fn main() {
.map(|kv| (kv.key.clone(), kv.value.clone().into()))
.collect();
let draw_cmds = engine.render_widget(&hint, &data, cmd.bounds, 0);
let error: Option<WidgetError> =
cmd.state.error.as_ref().map(|e| e.clone().into());
let draw_cmds =
engine.render_widget(&hint, &data, cmd.bounds, 0, error.as_ref());
for dc in &draw_cmds {
display
.draw_text_span(&dc.text, dc.x, dc.y, dc.color, dc.font)