theme config, layout preview, container alignment
Server: ThemeConfig entity + CRUD (GET/PUT /theme), SQLite persistence, ThemeUpdate broadcast to ESP32 on save and initial connect. Client: render engine uses theme colors, full-screen redraw on theme change. SPA: theme page with color pickers + presets, layout preview with TS port of layout engine, justify/align controls on containers. DisplayHint refactored to struct (kind + h_align + v_align).
This commit is contained in:
@@ -3,6 +3,7 @@ mod clients;
|
||||
mod data_sources;
|
||||
mod layout;
|
||||
mod presets;
|
||||
mod theme;
|
||||
mod webhook;
|
||||
mod widgets;
|
||||
|
||||
@@ -70,6 +71,11 @@ where
|
||||
get(layout::get_layout::<C, E, W, B, R, A, H>)
|
||||
.put(layout::update_layout::<C, E, W, B, R, A, H>),
|
||||
)
|
||||
.route(
|
||||
"/theme",
|
||||
get(theme::get_theme::<C, E, W, B, R, A, H>)
|
||||
.put(theme::update_theme::<C, E, W, B, R, A, H>),
|
||||
)
|
||||
.route(
|
||||
"/presets",
|
||||
get(presets::list_presets::<C, E, W, B, R, A, H>)
|
||||
|
||||
46
crates/adapters/http-api/src/routes/theme.rs
Normal file
46
crates/adapters/http-api/src/routes/theme.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use crate::AppState;
|
||||
use crate::extractors::AuthUser;
|
||||
use api_types::ThemeDto;
|
||||
use application::ConfigService;
|
||||
use axum::{extract::State, http::StatusCode, response::Json};
|
||||
use domain::{ConfigRepository, EventPublisher};
|
||||
|
||||
type S<C, E, W, B, R, A, H> = State<AppState<C, E, W, B, R, A, H>>;
|
||||
|
||||
pub async fn get_theme<C, E, W, B, R, A, H>(
|
||||
_auth: AuthUser,
|
||||
State(state): S<C, E, W, B, R, A, H>,
|
||||
) -> Result<Json<ThemeDto>, StatusCode>
|
||||
where
|
||||
C: ConfigRepository,
|
||||
C::Error: std::fmt::Debug,
|
||||
E: EventPublisher,
|
||||
E::Error: std::fmt::Debug,
|
||||
{
|
||||
let theme = state
|
||||
.config
|
||||
.get_theme()
|
||||
.await
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
|
||||
.unwrap_or_default();
|
||||
Ok(Json(ThemeDto::from(&theme)))
|
||||
}
|
||||
|
||||
pub async fn update_theme<C, E, W, B, R, A, H>(
|
||||
_auth: AuthUser,
|
||||
State(state): S<C, E, W, B, R, A, H>,
|
||||
Json(body): Json<ThemeDto>,
|
||||
) -> Result<StatusCode, (StatusCode, String)>
|
||||
where
|
||||
C: ConfigRepository,
|
||||
C::Error: std::fmt::Debug,
|
||||
E: EventPublisher,
|
||||
E::Error: std::fmt::Debug,
|
||||
{
|
||||
let theme = body.into_domain();
|
||||
let svc = ConfigService::new(state.config.as_ref(), state.events.as_ref());
|
||||
svc.update_theme(theme)
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e}")))?;
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
Reference in New Issue
Block a user