From dd48c5a163386a2f49d81eeb8a8121ccd932296c Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 23 May 2023 11:58:12 -0500 Subject: [PATCH] fix web history --- packages/router/src/components/router.rs | 5 +--- packages/router/src/contexts/router.rs | 28 ++++++++++++++++++---- packages/router/src/history/web.rs | 10 ++++++-- packages/router/src/history/web_history.rs | 16 +++++++++---- packages/router/src/lib.rs | 1 + 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/packages/router/src/components/router.rs b/packages/router/src/components/router.rs index 4e735984c..a8d70c7e3 100644 --- a/packages/router/src/components/router.rs +++ b/packages/router/src/components/router.rs @@ -3,7 +3,6 @@ use log::error; use std::{cell::RefCell, str::FromStr}; use crate::{ - history::HistoryProvider, prelude::{outlet::OutletContext, RouterContext}, routable::Routable, router_cfg::RouterConfiguration, @@ -26,9 +25,7 @@ impl PartialEq for RouterProps { } /// A component that renders the current route. -pub fn Router + Default + 'static>( - cx: Scope>, -) -> Element +pub fn Router(cx: Scope>) -> Element where ::Err: std::fmt::Display, { diff --git a/packages/router/src/contexts/router.rs b/packages/router/src/contexts/router.rs index 5690fc78e..f40f88418 100644 --- a/packages/router/src/contexts/router.rs +++ b/packages/router/src/contexts/router.rs @@ -76,7 +76,10 @@ impl RouterContext where R: Routable, { - pub(crate) fn new(cfg: RouterConfiguration, mark_dirty: Arc) -> Self + pub(crate) fn new( + cfg: RouterConfiguration, + mark_dirty: Arc, + ) -> Self where R: Clone, { @@ -87,17 +90,32 @@ where history: cfg.history, })); - Self { + let subscriber_update = mark_dirty.clone(); + let subscribers = Arc::new(RwLock::new(HashSet::new())); + + let myself = Self { state, - subscribers: Arc::new(RwLock::new(HashSet::new())), - subscriber_update: mark_dirty, + subscribers: subscribers.clone(), + subscriber_update, routing_callback: cfg.on_update, failure_external_navigation: cfg.failure_external_navigation, failure_named_navigation: cfg.failure_named_navigation, failure_redirection_limit: cfg.failure_redirection_limit, + }; + + // set the updater + { + let mut state = myself.state.write().unwrap(); + state.history.updater(Arc::new(move || { + for &id in subscribers.read().unwrap().iter() { + (mark_dirty)(id); + } + })); } + + myself } /// Check whether there is a previous page to navigate back to. @@ -161,7 +179,7 @@ where where R: Clone, { - self.state.read().unwrap().history.current_route().clone() + self.state.read().unwrap().history.current_route() } /// The prefix that is currently active. diff --git a/packages/router/src/history/web.rs b/packages/router/src/history/web.rs index f56d0c2d2..7e1980cf7 100644 --- a/packages/router/src/history/web.rs +++ b/packages/router/src/history/web.rs @@ -45,6 +45,12 @@ pub struct WebHistory { phantom: std::marker::PhantomData, } +impl Default for WebHistory { + fn default() -> Self { + Self::new(None, true) + } +} + impl WebHistory { /// Create a new [`WebHistory`]. /// @@ -97,9 +103,9 @@ where ::Err: std::fmt::Display, { fn current_route(&self) -> R { - match get_current(&self.history) { + match get_current::>(&self.history) { // Try to get the route from the history state - Some(route) => route, + Some(route) => route.state, // If that fails, get the route from the current URL None => R::from_str( &self diff --git a/packages/router/src/history/web_history.rs b/packages/router/src/history/web_history.rs index 7106f9f91..711c1b251 100644 --- a/packages/router/src/history/web_history.rs +++ b/packages/router/src/history/web_history.rs @@ -1,3 +1,4 @@ +use gloo::console::error; use gloo_utils::format::JsValueSerdeExt; use serde::{de::DeserializeOwned, Serialize}; use wasm_bindgen::JsValue; @@ -24,8 +25,15 @@ pub(crate) fn push_state_and_url( } pub(crate) fn get_current(history: &History) -> Option { - history - .state() - .ok() - .and_then(|state| state.into_serde().ok()) + let state = history.state(); + if let Err(err) = &state { + error!(err); + } + state.ok().and_then(|state| { + let deserialized = state.into_serde(); + if let Err(err) = &deserialized { + error!(format!("{}", err)); + } + deserialized.ok() + }) } diff --git a/packages/router/src/lib.rs b/packages/router/src/lib.rs index eaf81e9e5..9426fd3a3 100644 --- a/packages/router/src/lib.rs +++ b/packages/router/src/lib.rs @@ -47,6 +47,7 @@ pub mod prelude { pub use crate::components::*; pub use crate::contexts::*; pub use crate::hooks::*; + pub use crate::router_cfg::RouterConfiguration; pub use dioxus_router_macro::routable; }