fix: hydration bug
This commit is contained in:
parent
af3fc3564c
commit
5f9ffcde27
@ -5,7 +5,6 @@ use crate::models::HoldRole;
|
|||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Wall() -> impl leptos::IntoView {
|
pub fn Wall() -> impl leptos::IntoView {
|
||||||
@ -30,21 +29,33 @@ fn WallReady(data: InitialData) -> impl leptos::IntoView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cells = vec![];
|
let (current_problem, current_problem_writer) = signal(None::<models::Problem>);
|
||||||
|
LocalResource::new(move || async move {
|
||||||
let current_problem = OnceResource::new(async move {
|
leptos::logging::log!("Loading random problem");
|
||||||
let problem = get_random_problem().await.unwrap();
|
let problem = get_random_problem().await.expect("cannot get random problem");
|
||||||
problem
|
current_problem_writer.set(Some(problem.into_inner()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut cells = vec![];
|
||||||
for &hold_position in &hold_positions {
|
for &hold_position in &hold_positions {
|
||||||
let role = move || current_problem.get().map(|problem| problem.holds.get(&hold_position).copied()).flatten();
|
let role = move || {
|
||||||
|
let x = current_problem
|
||||||
|
.get()
|
||||||
|
.map(|problem| {
|
||||||
|
let role = problem.holds.get(&hold_position)?;
|
||||||
|
// leptos::logging::log!("{hold_position:?}: {role:?}");
|
||||||
|
Some(*role)
|
||||||
|
})
|
||||||
|
.flatten();
|
||||||
|
x
|
||||||
|
};
|
||||||
|
let role = Signal::derive(role);
|
||||||
|
|
||||||
let cell = view! { <Cell role=Signal::derive(role)/> };
|
let cell = view! { <Cell role/> };
|
||||||
cells.push(cell);
|
cells.push(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
leptos::view! {
|
view! {
|
||||||
<div class="container mx-auto border">
|
<div class="container mx-auto border">
|
||||||
<div class="grid grid-rows-4 grid-cols-12 gap-4">{cells}</div>
|
<div class="grid grid-rows-4 grid-cols-12 gap-4">{cells}</div>
|
||||||
</div>
|
</div>
|
||||||
@ -52,30 +63,45 @@ fn WallReady(data: InitialData) -> impl leptos::IntoView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn Cell(role: Signal<Option<HoldRole>>) -> impl leptos::IntoView {
|
fn Cell(#[prop(into)] role: Signal<Option<HoldRole>>) -> impl leptos::IntoView {
|
||||||
let role_classes = move || {
|
let classes = move || {
|
||||||
role.get().map(|role| match role {
|
let role_classes = role.get().map(|role| match role {
|
||||||
HoldRole::Start => "outline outline-offset-2",
|
HoldRole::Start => "outline outline-offset-2 outline-green-500",
|
||||||
HoldRole::Normal => "outline outline-offset-2",
|
HoldRole::Normal => "outline outline-offset-2 outline-blue-500",
|
||||||
HoldRole::Zone => "outline outline-offset-2",
|
HoldRole::Zone => "outline outline-offset-2 outline-amber-500",
|
||||||
HoldRole::End => "outline outline-offset-2",
|
HoldRole::End => "outline outline-offset-2 outline-red-500",
|
||||||
})
|
});
|
||||||
};
|
|
||||||
|
|
||||||
let class = move || {
|
|
||||||
let mut s = "aspect-square rounded border-2 border-dashed border-sky-500 bg-indigo-100".to_string();
|
let mut s = "aspect-square rounded border-2 border-dashed border-sky-500 bg-indigo-100".to_string();
|
||||||
if let Some(c) = role_classes() {
|
if let Some(c) = role_classes {
|
||||||
s.push_str(" ");
|
s.push_str(" ");
|
||||||
s.push_str(c);
|
s.push_str(c);
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// let is_start = move || matches!(role.get(), Some(HoldRole::Start));
|
||||||
|
// let is_normal = move || matches!(role.get(), Some(HoldRole::Normal));
|
||||||
|
// let is_end = move || matches!(role.get(), Some(HoldRole::End));
|
||||||
|
|
||||||
|
// let classes_start = "outline outline-offset-2 outline-green-500";
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div class=class>
|
<div
|
||||||
|
class=move || classes()
|
||||||
|
|
||||||
|
// class="aspect-square rounded border-2 border-dashed border-sky-500 bg-indigo-100"
|
||||||
|
// class=move || (is_start().then_some("outline outline-offset-2 outline-green-500"))
|
||||||
|
// class=(["outline", "outline-offset-2", "outline-green-500"], is_start)
|
||||||
|
// class=(["outline", "outline-offset-2", "outline-blue-500"], is_normal)
|
||||||
|
// class=(["outline", "outline-offset-2", "outline-red-500"], is_end)
|
||||||
|
>
|
||||||
"o"
|
"o"
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// view! {
|
||||||
|
// {format!("{:?}", role)}
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
@ -101,5 +127,8 @@ async fn get_random_problem() -> Result<RonCodec<models::Problem>, ServerFnError
|
|||||||
|
|
||||||
// TODO: Actually randomize
|
// TODO: Actually randomize
|
||||||
let problem = state.persistent.with(|s| s.problems.problems.iter().next().unwrap().clone()).await;
|
let problem = state.persistent.with(|s| s.problems.problems.iter().next().unwrap().clone()).await;
|
||||||
|
|
||||||
|
tracing::debug!("Returning randomized problem: {problem:?}");
|
||||||
|
|
||||||
Ok(RonCodec::new(problem))
|
Ok(RonCodec::new(problem))
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,6 @@ async fn serve() -> Result<(), Error> {
|
|||||||
|
|
||||||
let server_state = load_state().await?;
|
let server_state = load_state().await?;
|
||||||
|
|
||||||
// build our application with a route
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.leptos_routes_with_context(&leptos_options, routes, move || provide_context(server_state.clone()), {
|
.leptos_routes_with_context(&leptos_options, routes, move || provide_context(server_state.clone()), {
|
||||||
let leptos_options = leptos_options.clone();
|
let leptos_options = leptos_options.clone();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user