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>)]
|
#[component(Recipe<G>)]
|
||||||
pub fn recipe(idx: ReadSignal<usize>) -> View<G> {
|
pub fn recipe(idx: ReadSignal<usize>) -> View<G> {
|
||||||
let app_service = use_context::<AppService>();
|
let app_service = use_context::<AppService>();
|
||||||
let recipe = app_service.get_recipes().get()[*idx.get()].1.clone();
|
let view = Signal::new(View::empty());
|
||||||
let title = create_memo(cloned!((recipe) => move || recipe.get().title.clone()));
|
create_effect(cloned!((app_service, view) => move || {
|
||||||
let desc = create_memo(
|
if let Some((_, recipe)) = app_service.get_recipes().get().get(*idx.get()) {
|
||||||
cloned!((recipe) => move || recipe.clone().get().desc.clone().unwrap_or_else(|| String::new())),
|
let recipe = recipe.clone();
|
||||||
);
|
let title = create_memo(cloned!((recipe) => move || recipe.get().title.clone()));
|
||||||
let steps = create_memo(cloned!((recipe) => move || recipe.get().steps.clone()));
|
let desc = create_memo(
|
||||||
view! {
|
cloned!((recipe) => move || recipe.clone().get().desc.clone().unwrap_or_else(|| String::new())),
|
||||||
div(class="recipe") {
|
);
|
||||||
h1(class="recipe_title") { (title.get()) }
|
let steps = create_memo(cloned!((recipe) => move || recipe.get().steps.clone()));
|
||||||
div(class="recipe_description") {
|
view.set(view! {
|
||||||
(desc.get())
|
div(class="recipe") {
|
||||||
}
|
h1(class="recipe_title") { (title.get()) }
|
||||||
Steps(steps)
|
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)));
|
let count = Signal::new(format!("{}", app_service.get_recipe_count_by_index(i)));
|
||||||
view! {
|
view! {
|
||||||
div() {
|
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 |_| {
|
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();
|
let mut app_service = app_service.clone();
|
||||||
debug!(idx=%i, count=%(*count.get()), "setting recipe count");
|
debug!(idx=%i, count=%(*count.get()), "setting recipe count");
|
||||||
|
@ -14,11 +14,14 @@
|
|||||||
use crate::components::{recipe::Recipe, tabs::*};
|
use crate::components::{recipe::Recipe, tabs::*};
|
||||||
|
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
|
use tracing::instrument;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct RecipePageProps {
|
pub struct RecipePageProps {
|
||||||
pub recipe: Signal<usize>,
|
pub recipe: Signal<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument]
|
||||||
#[component(RecipePage<G>)]
|
#[component(RecipePage<G>)]
|
||||||
pub fn recipe_page(props: RecipePageProps) -> View<G> {
|
pub fn recipe_page(props: RecipePageProps) -> View<G> {
|
||||||
view! {
|
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))]
|
#[instrument(skip(self))]
|
||||||
pub fn click_handler(&self) -> Box<dyn Fn(web_sys::Event)> {
|
pub fn click_handler(&self) -> Box<dyn Fn(web_sys::Event)> {
|
||||||
let route_signal = self.0.clone();
|
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
|
// NOTE(jwall): This needs to be a dynamic node so Sycamore knows to rerender it
|
||||||
// based on the results of the effect above.
|
// based on the results of the effect above.
|
||||||
view! {
|
view! {
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use crate::pages::*;
|
use crate::pages::*;
|
||||||
use crate::{app_state::*, components::*, router_integration::*, service::AppService};
|
use crate::{app_state::*, components::*, router_integration::*, service::AppService};
|
||||||
use tracing::{error, info, instrument};
|
use tracing::{debug, error, info, instrument};
|
||||||
|
|
||||||
use sycamore::{
|
use sycamore::{
|
||||||
context::{ContextProvider, ContextProviderProps},
|
context::{ContextProvider, ContextProviderProps},
|
||||||
@ -21,6 +21,7 @@ use sycamore::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[instrument]
|
||||||
fn route_switch<G: Html>(route: ReadSignal<AppRoutes>) -> View<G> {
|
fn route_switch<G: Html>(route: ReadSignal<AppRoutes>) -> View<G> {
|
||||||
// NOTE(jwall): This needs to not be a dynamic node. The rules around
|
// NOTE(jwall): This needs to not be a dynamic node. The rules around
|
||||||
// this are somewhat unclear and underdocumented for Sycamore. But basically
|
// this are somewhat unclear and underdocumented for Sycamore. But basically
|
||||||
@ -66,6 +67,7 @@ pub fn ui() -> View<G> {
|
|||||||
spawn_local_in_scope({
|
spawn_local_in_scope({
|
||||||
let mut app_service = app_service.clone();
|
let mut app_service = app_service.clone();
|
||||||
async move {
|
async move {
|
||||||
|
debug!("fetching recipes");
|
||||||
match AppService::fetch_recipes_from_storage() {
|
match AppService::fetch_recipes_from_storage() {
|
||||||
Ok((_, Some(recipes))) => {
|
Ok((_, Some(recipes))) => {
|
||||||
app_service.set_recipes(recipes);
|
app_service.set_recipes(recipes);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user