diff --git a/crates/ascend/src/components/problem_info.rs b/crates/ascend/src/components/problem_info.rs index 89ff02c..36d41fc 100644 --- a/crates/ascend/src/components/problem_info.rs +++ b/crates/ascend/src/components/problem_info.rs @@ -23,7 +23,7 @@ pub fn ProblemInfo(#[prop(into)] problem: Signal) -> impl IntoV #[tracing::instrument(skip_all)] fn NameValue(#[prop(into)] name: Signal, #[prop(into)] value: Signal) -> impl IntoView { view! { -

{name.get()}

+

{name.get()}

{value.get()}

} } diff --git a/crates/ascend/src/models.rs b/crates/ascend/src/models.rs index 9973c4e..bcebb08 100644 --- a/crates/ascend/src/models.rs +++ b/crates/ascend/src/models.rs @@ -94,13 +94,6 @@ pub mod v2 { pub holds: BTreeMap, pub problems: BTreeSet, } - impl Wall { - pub fn random_problem(&self) -> Option { - use rand::seq::IteratorRandom; - let mut rng = rand::rng(); - self.problems.iter().choose(&mut rng).copied() - } - } #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct WallDimensions { diff --git a/crates/ascend/src/pages/wall.rs b/crates/ascend/src/pages/wall.rs index 37b1512..c8fefb1 100644 --- a/crates/ascend/src/pages/wall.rs +++ b/crates/ascend/src/pages/wall.rs @@ -70,6 +70,7 @@ pub fn Wall() -> impl IntoView { }); let wall = crate::resources::wall_by_uid(wall_uid); + let problems = crate::resources::problems_for_wall(wall_uid); let header_items = move || HeaderItems { left: vec![], @@ -98,7 +99,8 @@ pub fn Wall() -> impl IntoView { {move || Suspend::new(async move { tracing::info!("executing main suspend"); let wall = wall.await?; - let v = view! { }; + let problems = problems.await?; + let v = view! { }; Ok::<_, ServerFnError>(v) })} @@ -117,7 +119,7 @@ fn WithProblem(#[prop(into)] problem: Signal) -> impl IntoView #[component] #[tracing::instrument(skip_all)] -fn WithWall(#[prop(into)] wall: Signal) -> impl IntoView { +fn WithWall(#[prop(into)] wall: Signal, #[prop(into)] problems: Signal>) -> impl IntoView { tracing::trace!("Enter"); let wall_uid = Signal::derive(move || wall.read().uid); @@ -137,18 +139,36 @@ fn WithWall(#[prop(into)] wall: Signal) -> impl IntoView { }); }; + let filtered_problems = Memo::new(move |_prev_val| { + let filter_holds = filter_holds.get(); + problems.with(|problems| { + problems + .iter() + .filter(|problem| filter_holds.iter().all(|hold_pos| problem.holds.contains_key(hold_pos))) + .cloned() + .collect::>() + }) + }); + let problem = crate::resources::problem_by_uid_optional(wall_uid, problem_uid.into()); let user_interaction = crate::resources::user_interaction(wall_uid, problem_uid.into()); - let fn_next_problem = move |wall: &models::Wall| { - set_problem_uid.set(wall.random_problem()); + let fn_next_problem = move || { + let problems = filtered_problems.read(); + + use rand::seq::IteratorRandom; + let mut rng = rand::rng(); + let problem = problems.iter().choose(&mut rng); + let problem_uid = problem.map(|p| p.uid); + + set_problem_uid.set(problem_uid); }; // Set a problem when wall is set (loaded) Effect::new(move |_prev_value| { if problem_uid.get().is_none() { tracing::debug!("Setting next problem"); - fn_next_problem(&wall.read()); + fn_next_problem(); } }); @@ -156,6 +176,7 @@ fn WithWall(#[prop(into)] wall: Signal) -> impl IntoView { let problem_signal = Signal::derive(move || problem.get().transpose().map(Option::flatten)); let on_click_hold = move |hold_position: models::HoldPosition| { + // Add/Remove hold position to problem filter set_filter_holds.update(|set| { if !set.remove(&hold_position) { set.insert(hold_position); @@ -163,26 +184,18 @@ fn WithWall(#[prop(into)] wall: Signal) -> impl IntoView { }); }; - let grid = { - let wall = wall.clone(); - view! { - - { - let wall = wall.clone(); - move || { - let wall = wall.clone(); - Suspend::new(async move { - let wall = wall.clone(); - tracing::info!("executing grid suspend"); - let view = view! { - - }; - Ok::<_, ServerFnError>(view) - }) - } - } - - } + let grid = view! { + + {move || { + Suspend::new(async move { + tracing::debug!("executing grid suspend"); + let view = view! { + + }; + Ok::<_, ServerFnError>(view) + }) + }} + }; let filter = move || { @@ -205,14 +218,30 @@ fn WithWall(#[prop(into)] wall: Signal) -> impl IntoView { } } - view! {
{cells}
} + let problems_counter = { + let name = view! {

{"Problems:"}

}; + let value = view! {

{filtered_problems.read().len()}

}; + view! { +
+ {name} {value} +
+ } + }; + + let sep = (!cells.is_empty()).then_some(view! { }); + + view! { +
{cells}
+ {sep} + {problems_counter} + } }; view! {
{grid}
-
+
{filter}
@@ -222,7 +251,7 @@ fn WithWall(#[prop(into)] wall: Signal) -> impl IntoView {