Use state handler in the recipe pages

This commit is contained in:
Jeremy Wall 2022-12-26 22:22:05 -05:00
parent 90346d55eb
commit 9881d2972b
4 changed files with 29 additions and 15 deletions

View File

@ -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<G: Html>(cx: Scope, recipe_id: String) -> View<G> {
pub fn Editor<'ctx, G: Html>(cx: Scope<'ctx>, props: RecipeComponentProps<'ctx>) -> View<G> {
let RecipeComponentProps { recipe_id, sh } = props;
let store = crate::api::HttpStore::get_from_context(cx);
let recipe: &Signal<RecipeEntry> =
create_signal(cx, RecipeEntry::new(&recipe_id, String::new()));
@ -73,7 +80,6 @@ pub fn Editor<G: Html>(cx: Scope, recipe_id: String) -> View<G> {
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<G: Html>(cx: Scope, recipe_id: String) -> View<G> {
// 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<G: Html>(cx: Scope, steps: Vec<recipes::Step>) -> View<G> {
}
#[component]
pub fn Viewer<G: Html>(cx: Scope, recipe_id: String) -> View<G> {
pub fn Viewer<'ctx, G: Html>(cx: Scope<'ctx>, props: RecipeComponentProps<'ctx>) -> View<G> {
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") {

View File

@ -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) }
}
}

View File

@ -25,6 +25,6 @@ pub fn RecipeEditPage<G: Html>(cx: Scope, props: RecipePageProps) -> View<G> {
RecipePage(
selected=Some("Edit".to_owned()),
recipe=recipe.clone(),
) { Editor(recipe) }
) { Editor(recipe_id=recipe, sh=sh) }
}
}

View File

@ -26,6 +26,6 @@ pub fn RecipeViewPage<G: Html>(cx: Scope, props: RecipePageProps) -> View<G> {
RecipePage(
selected=Some("View".to_owned()),
recipe=recipe.clone(),
) { Viewer(recipe) }
) { Viewer(recipe_id=recipe, sh=sh) }
}
}