Skip to content

Commit

Permalink
webui: Highlight currently selected animation on the list
Browse files Browse the repository at this point in the history
  • Loading branch information
mrozycki committed Dec 27, 2023
1 parent 4600b30 commit 43b1e0d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 27 deletions.
32 changes: 22 additions & 10 deletions animator/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use events::midi_generator::MidiEventGenerator;
use log::{info, warn};
use rustmas_light_client as client;
use rustmas_light_client::LightClientError;
use serde_json::{json, Map};
use serde_json::json;
use thiserror::Error;
use tokio::sync::mpsc::Sender;
use tokio::sync::{mpsc, Mutex};
Expand Down Expand Up @@ -194,14 +194,12 @@ impl Controller {
.event_generators
.iter()
.map(|(id, evg)| {
(
id.clone(),
json!({
"name": evg.get_name(),
"schema": evg.get_parameter_schema(),
"values": evg.get_parameters(),
}),
)
json!({
"id": id.clone(),
"name": evg.get_name(),
"schema": evg.get_parameter_schema(),
"values": evg.get_parameters(),
})
})
.collect()
}
Expand All @@ -212,11 +210,25 @@ impl Controller {
) -> Result<(), ControllerError> {
let mut state = self.state.lock().await;

for (id, parameters) in values.as_object().unwrap_or(&Map::new()) {
for parameters in values.as_array().unwrap_or(&Vec::new()) {
let Some(id) = parameters
.as_object()
.and_then(|p| p.get("id"))
.and_then(|p| p.as_str())
else {
warn!("No event generator id provided");
continue;
};
let Some(evg) = state.event_generators.get_mut(id) else {
warn!("No such event generator: {}", id);
continue;
};

let Some(parameters) = parameters.as_object().and_then(|o| o.get("values")) else {
warn!("No parameters provided for event generator: {}", id);
continue;
};

let parameters = serde_json::from_value(parameters.clone()).map_err(|e| {
ControllerError::InternalError {
reason: e.to_string(),
Expand Down
14 changes: 7 additions & 7 deletions webapi-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ struct ListAnimationsResponse {

#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct ParamsSchemaEntry {
pub id: String,
pub name: String,
pub schema: ParametersSchema,
pub values: HashMap<String, serde_json::Value>,
Expand Down Expand Up @@ -121,16 +122,15 @@ impl RustmasApiClient {
}

pub async fn restart_events(&self) -> Result<()> {
self.post::<()>("events/restart", &json!(())).await
self.post("events/restart", &json!(())).await
}

pub async fn events_schema(&self) -> Result<HashMap<String, ParamsSchemaEntry>> {
self.get::<HashMap<String, ParamsSchemaEntry>>("events/schema")
.await
pub async fn events_schema(&self) -> Result<Vec<ParamsSchemaEntry>> {
self.get("events/schema").await
}

pub async fn set_events_params(&self, params: &serde_json::Value) -> Result<()> {
self.post::<()>("events/values", params).await
self.post("events/values", params).await
}

pub async fn list_animations(&self) -> Result<Vec<AnimationEntry>> {
Expand All @@ -155,15 +155,15 @@ impl RustmasApiClient {
}

pub async fn turn_off(&self) -> Result<()> {
self.post::<()>("turn_off", &json!(())).await
self.post("turn_off", &json!(())).await
}

pub async fn get_params(&self) -> Result<Option<ParamsSchemaEntry>> {
Ok(self.get::<GetParamsResponse>("params").await?.animation)
}

pub async fn set_params(&self, params: &serde_json::Value) -> Result<()> {
self.post::<()>("params", params).await
self.post("params", params).await
}

pub async fn save_params(&self) -> Result<()> {
Expand Down
13 changes: 12 additions & 1 deletion webui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ impl Component for AnimationSelector {
.and_then(|w| w.screen().ok())
.and_then(|s| s.avail_width().ok())
.unwrap_or_default();
let animation_id = self
.parameters
.as_ref()
.map(|a| a.id.as_str())
.unwrap_or_default();
html! {
<ContextProvider<RustmasApiClient> context={self.api.clone()}>
<>
Expand All @@ -188,7 +193,13 @@ impl Component for AnimationSelector {
<hr />
{
animations.into_iter().map(|animation| html! {
<li><a onclick={link.callback(move |_| Msg::SwitchAnimation(animation.id.clone()))}>{ animation.name }</a></li>
<li class={
if animation.id == animation_id {
"selected"
} else {
""
}
}><a onclick={link.callback(move |_| Msg::SwitchAnimation(animation.id.clone()))}>{ animation.name }</a></li>
}).collect::<Html>()
}
</ul>
Expand Down
24 changes: 15 additions & 9 deletions webui/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::utils;

#[derive(Default)]
pub struct SettingsModal {
schema: Vec<(String, ParamsSchemaEntry)>,
schema: Vec<ParamsSchemaEntry>,
open_dummy: usize,
modal_ref: NodeRef,
}
Expand All @@ -37,7 +37,7 @@ pub enum Msg {
form: Option<HtmlFormElement>,
force: bool,
},
SchemaLoaded(HashMap<String, ParamsSchemaEntry>),
SchemaLoaded(Vec<ParamsSchemaEntry>),
}

fn get_api(ctx: &Context<SettingsModal>) -> RustmasApiClient {
Expand Down Expand Up @@ -115,9 +115,9 @@ impl Component for SettingsModal {
let params = self
.schema
.iter()
.map(|(id, evg)| {
.map(|evg| {
(
id.clone(),
evg.id.clone(),
evg.schema
.parameters
.iter()
Expand All @@ -126,7 +126,7 @@ impl Component for SettingsModal {
schema.id.clone(),
serde_json::from_str::<serde_json::Value>(
&form_data
.get(&format!("{}.{}", id, schema.id))
.get(&format!("{}.{}", evg.id, schema.id))
.as_string()
.unwrap(),
)
Expand All @@ -136,7 +136,13 @@ impl Component for SettingsModal {
.collect::<HashMap<_, _>>(),
)
})
.collect::<HashMap<_, _>>();
.map(|(id, values)| {
json!({
"id": id,
"values": values
})
})
.collect_vec();
let params = serde_json::to_value(params).unwrap();

let api = get_api(ctx);
Expand All @@ -151,7 +157,7 @@ impl Component for SettingsModal {
Msg::SchemaLoaded(schema) => {
self.schema = schema
.into_iter()
.sorted_by(|(_, evg1), (_, evg2)| evg1.name.cmp(&evg2.name))
.sorted_by(|evg1, evg2| evg1.name.cmp(&evg2.name))
.collect();
true
}
Expand All @@ -178,7 +184,7 @@ impl Component for SettingsModal {
Msg::ValuesChanged { form: utils::get_form(e.target()), force: true }
})}>
{
self.schema.iter().map(|(id, evg)| {
self.schema.iter().map(|evg| {
if evg.schema.parameters.is_empty() {
html! { }
} else {
Expand All @@ -189,7 +195,7 @@ impl Component for SettingsModal {
evg.schema.parameters.iter().cloned().map(|schema| {
let value = evg.values.get(&schema.id).unwrap_or(&json!(())).clone();
let schema = Parameter {
id: format!("{}.{}", id, schema.id),
id: format!("{}.{}", evg.id, schema.id),
..schema
};
error!("evg: {}, param: {}, value: {}", evg.name, &schema.id, value);
Expand Down
6 changes: 6 additions & 0 deletions webui/style_dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ nav a {
padding: 1rem;
width: 100%;
height: 100%;
border-left: 1px solid transparent;
cursor: pointer;
color: #888;
}
Expand All @@ -123,6 +124,11 @@ nav a:hover {
color: #ccc;
}

nav .selected a {
color: #ccc;
border-left: 1px solid #ccc;
}

nav hr {
border-bottom: 1px solid #333;
margin: 0.5rem 1rem;
Expand Down

0 comments on commit 43b1e0d

Please sign in to comment.