ソースを参照

fix web history

Evan Almloff 2 年 前
コミット
dd48c5a163

+ 1 - 4
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<R: Routable> PartialEq for RouterProps<R> {
 }
 
 /// A component that renders the current route.
-pub fn Router<R: Routable + Clone, H: HistoryProvider<R> + Default + 'static>(
-    cx: Scope<RouterProps<R>>,
-) -> Element
+pub fn Router<R: Routable + Clone>(cx: Scope<RouterProps<R>>) -> Element
 where
     <R as FromStr>::Err: std::fmt::Display,
 {

+ 23 - 5
packages/router/src/contexts/router.rs

@@ -76,7 +76,10 @@ impl<R> RouterContext<R>
 where
     R: Routable,
 {
-    pub(crate) fn new(cfg: RouterConfiguration<R>, mark_dirty: Arc<dyn Fn(ScopeId)>) -> Self
+    pub(crate) fn new(
+        cfg: RouterConfiguration<R>,
+        mark_dirty: Arc<dyn Fn(ScopeId) + Sync + Send>,
+    ) -> 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.

+ 8 - 2
packages/router/src/history/web.rs

@@ -45,6 +45,12 @@ pub struct WebHistory<R: Serialize + DeserializeOwned> {
     phantom: std::marker::PhantomData<R>,
 }
 
+impl<R: Serialize + DeserializeOwned> Default for WebHistory<R> {
+    fn default() -> Self {
+        Self::new(None, true)
+    }
+}
+
 impl<R: Serialize + DeserializeOwned> WebHistory<R> {
     /// Create a new [`WebHistory`].
     ///
@@ -97,9 +103,9 @@ where
     <R as std::str::FromStr>::Err: std::fmt::Display,
 {
     fn current_route(&self) -> R {
-        match get_current(&self.history) {
+        match get_current::<WebHistoryState<_>>(&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

+ 12 - 4
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<V: Serialize>(
 }
 
 pub(crate) fn get_current<V: DeserializeOwned>(history: &History) -> Option<V> {
-    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()
+    })
 }

+ 1 - 0
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;
 }