diff --git a/web/src/components/tabs.rs b/web/src/components/tabs.rs index 336aaf9..ab4ec90 100644 --- a/web/src/components/tabs.rs +++ b/web/src/components/tabs.rs @@ -21,23 +21,26 @@ pub struct TabState { #[component(TabbedView)] pub fn tabbed_view(state: TabState) -> View { cloned!((state) => view! { - header(class="no-print") { - nav { - ul { - li { a(href="/ui/plan", class="no-print") { "Plan" } " > " + // NOTE(jwall): this needs to be a single node or the Router freaks out. + div { + header(class="no-print") { + nav { + ul { + li { a(href="/ui/plan", class="no-print") { "Plan" } " > " + } + li { a(href="/ui/inventory", class="no-print") { "Inventory" } " > " + } + li { a(href="/ui/cook", class="no-print") { "Cook" } + } } - li { a(href="/ui/inventory", class="no-print") { "Inventory" } " > " + ul { + li { a(href="https://github.com/zaphar/kitchen") { "Github" } } } - li { a(href="/ui/cook", class="no-print") { "Cook" } - } - } - ul { - li { a(href="https://github.com/zaphar/kitchen") { "Github" } } } } - } - main(class=".conatiner-fluid") { - (state.inner) + main(class=".conatiner-fluid") { + (state.inner) + } } }) } diff --git a/web/src/service.rs b/web/src/service.rs index 1054a3b..71e9a54 100644 --- a/web/src/service.rs +++ b/web/src/service.rs @@ -13,9 +13,15 @@ // limitations under the License. use std::collections::{BTreeMap, BTreeSet}; -use serde_json::{from_str, to_string}; +#[cfg(target_arch = "wasm32")] +use serde_json::from_str; +#[cfg(target_arch = "wasm32")] +use serde_json::to_string; use sycamore::{context::use_context, prelude::*}; -use tracing::{debug, error, info, instrument, warn}; +use tracing::{debug, instrument, warn}; +#[cfg(target_arch = "wasm32")] +use tracing::{error, info}; +#[cfg(target_arch = "wasm32")] use web_sys::{window, Storage}; use recipe_store::*; @@ -56,6 +62,7 @@ where } } + #[cfg(target_arch = "wasm32")] fn get_storage(&self) -> Result, String> { window() .unwrap() @@ -63,9 +70,19 @@ where .map_err(|e| format!("{:?}", e)) } + #[cfg(not(target_arch = "wasm32"))] #[instrument(skip(self))] - async fn synchronize(&self) -> Result<(), String> { + pub async fn init(&self, force: bool) -> Result<(), String> { + // TODO(jwall): Allow this to work for the ssr case. + todo!() + } + + #[cfg(target_arch = "wasm32")] + #[instrument(skip(self))] + pub async fn init(&self, force: bool) -> Result<(), String> { info!("Synchronizing Recipes"); + // TODO(jwall): Check to see if we already have them in storage + // only fetch via http if force is true. let storage = self.get_storage()?.unwrap(); let recipes = self .store @@ -96,10 +113,9 @@ where Ok(()) } + #[cfg(target_arch = "wasm32")] #[instrument(skip(self))] - pub fn fetch_categories_from_storage( - &self, - ) -> Result>, String> { + fn fetch_categories_from_storage(&self) -> Result>, String> { let storage = self.get_storage()?.unwrap(); match storage .get_item("categories") @@ -119,8 +135,9 @@ where } } + #[cfg(target_arch = "wasm32")] #[instrument(skip(self))] - pub fn fetch_recipes_from_storage( + fn fetch_recipes_from_storage( &self, ) -> Result<(Option, Option>), String> { let storage = self.get_storage()?.unwrap(); @@ -153,19 +170,32 @@ where } } + #[cfg(target_arch = "wasm32")] async fn fetch_recipes( &self, ) -> Result<(Option, Option>), String> { Ok(self.fetch_recipes_from_storage()?) } + #[cfg(not(target_arch = "wasm32"))] + async fn fetch_recipes( + &self, + ) -> Result<(Option, Option>), String> { + Ok((None, None)) + } + #[cfg(target_arch = "wasm32")] async fn fetch_categories(&self) -> Result>, String> { Ok(self.fetch_categories_from_storage()?) } + #[cfg(not(target_arch = "wasm32"))] + async fn fetch_categories(&self) -> Result>, String> { + Ok(None) + } + // FIXME(jwall): Stays public #[instrument(skip(self))] pub async fn refresh(&mut self) -> Result<(), String> { - self.synchronize().await?; + self.init(true).await?; debug!("refreshing recipes"); if let (staples, Some(r)) = self.fetch_recipes().await? { self.set_recipes(r); @@ -182,6 +212,7 @@ where self.recipes.get().get(idx).map(|r| r.clone()) } + // FIXME(jwall): Stays public #[instrument(skip(self))] pub fn get_shopping_list( &self, @@ -243,7 +274,7 @@ where .collect() } - pub fn set_recipes(&mut self, mut recipes: BTreeMap) { + pub fn set_recipes(&mut self, recipes: BTreeMap) { self.recipes.set( recipes .iter() diff --git a/web/src/web.rs b/web/src/web.rs index 88905b6..b2d1b8b 100644 --- a/web/src/web.rs +++ b/web/src/web.rs @@ -27,7 +27,7 @@ fn route_switch(route: ReadSignal) -> View { // NOTE(jwall): This needs to not be a dynamic node. The rules around // this are somewhat unclear and underdocumented for Sycamore. But basically // avoid conditionals in the `view!` macro calls here. - cloned!((route) => match route.get().as_ref() { + let node = cloned!((route) => match route.get().as_ref() { AppRoutes::Plan => view! { PlanPage() }, @@ -50,7 +50,9 @@ fn route_switch(route: ReadSignal) -> View { "Error: " (e) } } - }) + }); + debug!(node=?node, "routing to new page"); + node } #[cfg(not(target_arch = "wasm32"))] @@ -95,17 +97,11 @@ pub fn ui(route: Option) -> View { children: || { create_effect(move || { spawn_local_in_scope({ - let mut app_service = app_service.clone(); + let app_service = app_service.clone(); async move { debug!("fetching recipes"); - match app_service.fetch_recipes_from_storage() { - Ok((_, Some(recipes))) => { - app_service.set_recipes(recipes); - } - Ok((_, None)) => { - error!("No recipes to find"); - } - Err(msg) => error!("Failed to get recipes {}", msg), + if let Err(msg) = app_service.init(false).await { + error!("Failed to get recipes {}", msg) } } });