use wasm_bindgen::JsCast;
use web_sys::{HtmlButtonElement, HtmlInputElement};
use crate::frontend::util::web_idl::document;
use crate::shared::{Request, StepSettings};
use crate::{
frontend::{
client::{issue_command, view_singleton::lock_view},
util::web_idl::{get_element_by_id, setup_selector_listener},
},
shared::BackendStatus,
};
pub fn init() {
setup_selector_listener(
"#reset",
"click",
Box::new(|_e| {
wasm_bindgen_futures::spawn_local(on_reset_click());
}),
);
setup_selector_listener(
"#step",
"click",
Box::new(|_e| {
wasm_bindgen_futures::spawn_local(on_step_click());
}),
);
setup_selector_listener(
"#run",
"click",
Box::new(|_e| {
wasm_bindgen_futures::spawn_local(on_run_click());
}),
);
}
pub fn display_backend_status(backend_status: &BackendStatus) {
let reset_element: HtmlButtonElement = get_element_by_id("reset").dyn_into().unwrap();
let step_element: HtmlButtonElement = get_element_by_id("step").dyn_into().unwrap();
let run_element: HtmlButtonElement = get_element_by_id("run").dyn_into().unwrap();
let mut step_active = false;
let mut run_active = false;
let document = document();
if let Some(active_element) = document.active_element() {
if active_element == **step_element {
step_active = true;
} else if active_element == **run_element {
run_active = true;
}
}
const DATA_ACTIVE: &str = "data-active";
match backend_status {
BackendStatus::Cancelling => {
reset_element.set_disabled(true);
step_element.set_disabled(true);
run_element.set_disabled(true);
if run_active && run_element.get_attribute(DATA_ACTIVE).is_none() {
run_element.set_attribute(DATA_ACTIVE, "run").unwrap();
}
}
BackendStatus::Waiting => {
reset_element.set_disabled(false);
step_element.set_disabled(false);
run_element.set_disabled(false);
match run_element.get_attribute(DATA_ACTIVE).as_deref() {
Some("step") => {
step_element.focus().unwrap();
}
Some("run") => {
run_element.focus().unwrap();
}
_ => {}
};
run_element.remove_attribute(DATA_ACTIVE).unwrap();
}
BackendStatus::Running => {
reset_element.set_disabled(true);
step_element.set_disabled(true);
run_element.set_disabled(false);
if step_active {
run_element.set_attribute(DATA_ACTIVE, "step").unwrap();
run_element.focus().unwrap();
}
}
}
if backend_status.is_waiting() {
run_element.set_inner_text("\u{23F5}");
} else {
run_element.set_inner_text("\u{23F8}");
}
}
pub async fn on_reset_click() {
issue_command(Request::Reset).await;
}
pub async fn on_step_click() {
let input: HtmlInputElement = get_element_by_id("max_refinements")
.dyn_into()
.expect("The number of steps element should be an input");
let max_refinements = (input.value_as_number() as u64).max(1);
issue_step(Some(max_refinements)).await;
}
pub async fn on_run_click() {
let waiting = {
let view_guard = lock_view();
view_guard.as_ref().backend_info().status.is_waiting()
};
if waiting {
issue_step(None).await;
} else {
issue_command(Request::Cancel).await;
}
}
pub async fn issue_step(max_refinements: Option<u64>) {
let selected_property = {
let view_guard = lock_view();
let Some(selected_property) = view_guard.as_ref().selected_property_index() else {
return;
};
view_guard
.as_ref()
.snapshot()
.property_snapshot(selected_property)
.property
.clone()
};
issue_command(Request::Step(StepSettings {
max_refinements,
selected_property,
}))
.await;
}