mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -04:00
Navigate to recipe view from plan page
This commit is contained in:
parent
35f48298dd
commit
71a4e093b9
@ -49,19 +49,27 @@ fn steps(steps: ReadSignal<Vec<recipes::Step>>) -> View<G> {
|
||||
#[component(Recipe<G>)]
|
||||
pub fn recipe(idx: ReadSignal<usize>) -> View<G> {
|
||||
let app_service = use_context::<AppService>();
|
||||
let recipe = app_service.get_recipes().get()[*idx.get()].1.clone();
|
||||
let title = create_memo(cloned!((recipe) => move || recipe.get().title.clone()));
|
||||
let desc = create_memo(
|
||||
cloned!((recipe) => move || recipe.clone().get().desc.clone().unwrap_or_else(|| String::new())),
|
||||
);
|
||||
let steps = create_memo(cloned!((recipe) => move || recipe.get().steps.clone()));
|
||||
view! {
|
||||
div(class="recipe") {
|
||||
h1(class="recipe_title") { (title.get()) }
|
||||
div(class="recipe_description") {
|
||||
(desc.get())
|
||||
}
|
||||
Steps(steps)
|
||||
let view = Signal::new(View::empty());
|
||||
create_effect(cloned!((app_service, view) => move || {
|
||||
if let Some((_, recipe)) = app_service.get_recipes().get().get(*idx.get()) {
|
||||
let recipe = recipe.clone();
|
||||
let title = create_memo(cloned!((recipe) => move || recipe.get().title.clone()));
|
||||
let desc = create_memo(
|
||||
cloned!((recipe) => move || recipe.clone().get().desc.clone().unwrap_or_else(|| String::new())),
|
||||
);
|
||||
let steps = create_memo(cloned!((recipe) => move || recipe.get().steps.clone()));
|
||||
view.set(view! {
|
||||
div(class="recipe") {
|
||||
h1(class="recipe_title") { (title.get()) }
|
||||
div(class="recipe_description") {
|
||||
(desc.get())
|
||||
}
|
||||
Steps(steps)
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
||||
view! {
|
||||
(view.get().as_ref())
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ pub fn recipe_selection(props: RecipeCheckBoxProps) -> View<G> {
|
||||
let count = Signal::new(format!("{}", app_service.get_recipe_count_by_index(i)));
|
||||
view! {
|
||||
div() {
|
||||
label(for=id_cloned_2) { (props.title.get()) }
|
||||
label(for=id_cloned_2) { a(href=format!("#recipe/{}", i)) { (props.title.get()) } }
|
||||
input(type="number", class="item-count-sel", min="0", bind:value=count.clone(), name=format!("recipe_id:{}", i), value=id_as_str.clone(), on:change=move |_| {
|
||||
let mut app_service = app_service.clone();
|
||||
debug!(idx=%i, count=%(*count.get()), "setting recipe count");
|
||||
|
@ -14,11 +14,14 @@
|
||||
use crate::components::{recipe::Recipe, tabs::*};
|
||||
|
||||
use sycamore::prelude::*;
|
||||
use tracing::instrument;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RecipePageProps {
|
||||
pub recipe: Signal<usize>,
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[component(RecipePage<G>)]
|
||||
pub fn recipe_page(props: RecipePageProps) -> View<G> {
|
||||
view! {
|
||||
|
@ -37,6 +37,16 @@ impl BrowserIntegration {
|
||||
)))
|
||||
}
|
||||
|
||||
#[instrument(skip(self, f))]
|
||||
pub fn register_post_state_handler(&self, f: Box<dyn FnMut()>) {
|
||||
let closure = Closure::wrap(f);
|
||||
web_sys::window()
|
||||
.unwrap_throw()
|
||||
.add_event_listener_with_callback("popstate", closure.as_ref().unchecked_ref())
|
||||
.unwrap_throw();
|
||||
closure.forget();
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub fn click_handler(&self) -> Box<dyn Fn(web_sys::Event)> {
|
||||
let route_signal = self.0.clone();
|
||||
@ -130,6 +140,12 @@ where
|
||||
}),
|
||||
);
|
||||
|
||||
let path_signal = integration.0.clone();
|
||||
integration.register_post_state_handler(Box::new(cloned!((path_signal) => move || {
|
||||
let location = web_sys::window().unwrap_throw().location();
|
||||
path_signal.set((location.origin().unwrap_throw(), location.pathname().unwrap_throw(), location.hash().unwrap_throw()));
|
||||
})));
|
||||
|
||||
// NOTE(jwall): This needs to be a dynamic node so Sycamore knows to rerender it
|
||||
// based on the results of the effect above.
|
||||
view! {
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
use crate::pages::*;
|
||||
use crate::{app_state::*, components::*, router_integration::*, service::AppService};
|
||||
use tracing::{error, info, instrument};
|
||||
use tracing::{debug, error, info, instrument};
|
||||
|
||||
use sycamore::{
|
||||
context::{ContextProvider, ContextProviderProps},
|
||||
@ -21,6 +21,7 @@ use sycamore::{
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
#[instrument]
|
||||
fn route_switch<G: Html>(route: ReadSignal<AppRoutes>) -> View<G> {
|
||||
// NOTE(jwall): This needs to not be a dynamic node. The rules around
|
||||
// this are somewhat unclear and underdocumented for Sycamore. But basically
|
||||
@ -66,6 +67,7 @@ pub fn ui() -> View<G> {
|
||||
spawn_local_in_scope({
|
||||
let mut app_service = app_service.clone();
|
||||
async move {
|
||||
debug!("fetching recipes");
|
||||
match AppService::fetch_recipes_from_storage() {
|
||||
Ok((_, Some(recipes))) => {
|
||||
app_service.set_recipes(recipes);
|
||||
|
Loading…
x
Reference in New Issue
Block a user