diff --git a/Cargo.lock b/Cargo.lock index 86b647d..1587f4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -862,6 +862,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "mio" version = "0.7.14" @@ -902,6 +908,17 @@ dependencies = [ "twoway", ] +[[package]] +name = "nom" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +dependencies = [ + "memchr", + "minimal-lexical", + "version_check", +] + [[package]] name = "ntapi" version = "0.3.6" @@ -1355,6 +1372,31 @@ dependencies = [ "web-sys", ] +[[package]] +name = "sycamore-router" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cace57b69d923ef7ac5a1291bee73fa62e7d75b1f3a713db70d30ab0ee032185" +dependencies = [ + "sycamore", + "sycamore-router-macro", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "sycamore-router-macro" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a1f83a4862484dba897a6dc64c4a72b5c808c9af05573f7a55133b4f110ac66" +dependencies = [ + "nom", + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + [[package]] name = "syn" version = "1.0.85" @@ -1765,6 +1807,7 @@ dependencies = [ "recipes", "reqwasm", "sycamore", + "sycamore-router", "wasm-bindgen", ] diff --git a/web/Cargo.toml b/web/Cargo.toml index b93ba54..b9ea2a2 100644 --- a/web/Cargo.toml +++ b/web/Cargo.toml @@ -10,6 +10,7 @@ recipes = {path = "../recipes" } reqwasm = "0.4.0" # This makes debugging panics more tractable. console_error_panic_hook = "0.1.7" +sycamore-router = "0.7.1" [dependencies.wasm-bindgen] version = "0.2.79" diff --git a/web/src/web.rs b/web/src/web.rs index 206a5d2..c80aeac 100644 --- a/web/src/web.rs +++ b/web/src/web.rs @@ -16,6 +16,7 @@ use reqwasm::http; use sycamore::context::{use_context, ContextProvider, ContextProviderProps}; use sycamore::futures::spawn_local_in_scope; use sycamore::prelude::*; +use sycamore_router::{HistoryIntegration, Route, Router, RouterProps}; use recipes::{parse, Recipe}; @@ -92,26 +93,66 @@ fn recipe_list() -> View { } } +#[derive(Route, Debug)] +enum AppRoutes { + #[to("/ui")] + Root, + #[to("/ui/recipe/")] + Recipe { index: usize }, + #[to("/ui/menu")] + Menu, + #[not_found] + NotFound, +} + #[component(UI)] pub fn ui() -> View { let app_service = AppService::new(); console_log!("Starting UI"); - spawn_local_in_scope({ - let mut app_service = app_service.clone(); - async move { - match AppService::fetch_recipes().await { - Ok(recipes) => { - app_service.set_recipes(recipes); + create_effect(cloned!((app_service) => move || { + spawn_local_in_scope({ + let mut app_service = app_service.clone(); + async move { + match AppService::fetch_recipes().await { + Ok(recipes) => { + app_service.set_recipes(recipes); + } + Err(msg) => console_error!("Failed to get recipes {}", msg), } - Err(msg) => console_error!("Failed to get recipes {}", msg), } - } - }); + }); + })); view! { - div { "hello chefs!" } - ContextProvider(ContextProviderProps { - value: app_service, - children: || view! { RecipeList() } - }) + Router(RouterProps::new(HistoryIntegration::new(), move |routes: ReadSignal| { + let t = create_memo(cloned!((app_service) => move || { + console_debug!("Determining route."); + let route = routes.get(); + console_debug!("Route {:?}", route); + match route.as_ref() { + AppRoutes::Root => view! { + div { "hello chefs!" } + ContextProvider(ContextProviderProps { + value: app_service.clone(), + children: || view! { RecipeList() } + }) + }, + AppRoutes::Recipe{index:_idx} => view! { + "TODO!!" + }, + AppRoutes::Menu => view! { + "TODO!!" + }, + AppRoutes::NotFound => view! { + "NotFound" + } + } + })); + console_debug!("Created our route view memo."); + view! { + div(class="app") { + (t.get().as_ref().clone()) + } + } + })) } }