diff --git a/web/src/components/recipe.rs b/web/src/components/recipe.rs index f4159a8..55f98a8 100644 --- a/web/src/components/recipe.rs +++ b/web/src/components/recipe.rs @@ -14,7 +14,7 @@ use sycamore::{futures::spawn_local_scoped, prelude::*}; use tracing::{debug, error}; -use crate::app_state; +use crate::app_state::{self, Message, StateHandler}; use recipes::{self, RecipeEntry}; fn check_recipe_parses( @@ -34,8 +34,15 @@ fn check_recipe_parses( } } +#[derive(Props)] +pub struct RecipeComponentProps<'ctx> { + recipe_id: String, + sh: StateHandler<'ctx>, +} + #[component] -pub fn Editor(cx: Scope, recipe_id: String) -> View { +pub fn Editor<'ctx, G: Html>(cx: Scope<'ctx>, props: RecipeComponentProps<'ctx>) -> View { + let RecipeComponentProps { recipe_id, sh } = props; let store = crate::api::HttpStore::get_from_context(cx); let recipe: &Signal = create_signal(cx, RecipeEntry::new(&recipe_id, String::new())); @@ -73,7 +80,6 @@ pub fn Editor(cx: Scope, recipe_id: String) -> View { debug!("Recipe text is changed"); spawn_local_scoped(cx, { let store = crate::api::HttpStore::get_from_context(cx); - let state = app_state::State::get_from_context(cx); async move { debug!("Attempting to save recipe"); if let Err(e) = store @@ -89,10 +95,10 @@ pub fn Editor(cx: Scope, recipe_id: String) -> View { // We also need to set recipe in our state dirty.set(false); if let Ok(recipe) = recipes::parse::as_recipe(text.get_untracked().as_ref()) { - state - .recipes - .modify() - .insert(id.get_untracked().as_ref().to_owned(), recipe); + sh.dispatch(Message::SetRecipe( + id.get_untracked().as_ref().to_owned(), + recipe, + )); } }; } @@ -154,13 +160,21 @@ fn Steps(cx: Scope, steps: Vec) -> View { } #[component] -pub fn Viewer(cx: Scope, recipe_id: String) -> View { +pub fn Viewer<'ctx, G: Html>(cx: Scope<'ctx>, props: RecipeComponentProps<'ctx>) -> View { + let RecipeComponentProps { recipe_id, sh } = props; let state = app_state::State::get_from_context(cx); let view = create_signal(cx, View::empty()); - if let Some(recipe) = state.recipes.get_untracked().get(&recipe_id) { - let title = recipe.title.clone(); - let desc = recipe.desc.clone().unwrap_or_else(|| String::new()); - let steps = recipe.steps.clone(); + let recipe_signal = sh.get_selector(cx, |state| { + if let Some(recipe) = state.get().recipes.get(&recipe_id) { + let title = recipe.title.clone(); + let desc = recipe.desc.clone().unwrap_or_else(|| String::new()); + let steps = recipe.steps.clone(); + Some((title, desc, steps)) + } else { + None + } + }); + if let Some((title, desc, steps)) = recipe_signal.get().as_ref().clone() { debug!("Viewing recipe."); view.set(view! {cx, div(class="recipe") { diff --git a/web/src/pages/manage/staples.rs b/web/src/pages/manage/staples.rs index d3aa9af..318b4a2 100644 --- a/web/src/pages/manage/staples.rs +++ b/web/src/pages/manage/staples.rs @@ -23,6 +23,6 @@ pub fn StaplesPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> Vi view! {cx, ManagePage( selected=Some("Staples".to_owned()), - ) { Editor("staples.txt".to_owned()) } + ) { Editor(recipe_id="staples.txt".to_owned(), sh=sh) } } } diff --git a/web/src/pages/recipe/edit.rs b/web/src/pages/recipe/edit.rs index fa6e9b5..d3ca8e3 100644 --- a/web/src/pages/recipe/edit.rs +++ b/web/src/pages/recipe/edit.rs @@ -25,6 +25,6 @@ pub fn RecipeEditPage(cx: Scope, props: RecipePageProps) -> View { RecipePage( selected=Some("Edit".to_owned()), recipe=recipe.clone(), - ) { Editor(recipe) } + ) { Editor(recipe_id=recipe, sh=sh) } } } diff --git a/web/src/pages/recipe/view.rs b/web/src/pages/recipe/view.rs index b98331c..2ff892b 100644 --- a/web/src/pages/recipe/view.rs +++ b/web/src/pages/recipe/view.rs @@ -26,6 +26,6 @@ pub fn RecipeViewPage(cx: Scope, props: RecipePageProps) -> View { RecipePage( selected=Some("View".to_owned()), recipe=recipe.clone(), - ) { Viewer(recipe) } + ) { Viewer(recipe_id=recipe, sh=sh) } } }