add SPA config UI, wire media/rss adapters, event-driven layout push

- React SPA: dashboard, data sources CRUD, widgets CRUD, layout builder,
  presets. TanStack Router + Query, shadcn/ui, Vite proxy to :3000
- wire media + rss adapters into polling loop, remove xtb source type
- media adapter: read username/password from headers, proper subsonic auth
- event handler: subscribe to LayoutChanged, push screen update to clients
- fix clippy warnings across workspace (Default impls, collapsible ifs,
  redundant closures, is_none_or, unused imports)
This commit is contained in:
2026-06-19 00:12:42 +02:00
parent 21c08911df
commit 26ebfad3a2
175 changed files with 12338 additions and 801 deletions

View File

@@ -1,15 +1,18 @@
use std::collections::HashMap;
use domain::{DataSourceId, Value, WidgetConfig, WidgetId, WidgetState};
use std::collections::HashMap;
#[derive(Default)]
pub struct DataProjection {
current: HashMap<WidgetId, WidgetState>,
}
impl DataProjection {
pub fn new() -> Self {
Self {
current: HashMap::new(),
}
Self::default()
}
pub fn get_state(&self, widget_id: WidgetId) -> Option<&WidgetState> {
self.current.get(&widget_id)
}
pub fn apply_poll_result(
@@ -27,9 +30,10 @@ impl DataProjection {
let new_state = config.extract(raw);
let is_changed = self.current
let is_changed = self
.current
.get(&config.id)
.map_or(true, |prev| *prev != new_state);
.is_none_or(|prev| *prev != new_state);
if is_changed {
self.current.insert(config.id, new_state.clone());