Explorar o código

enabled the liveview history by default if the liveview feature is enabled in the router

Evan Almloff hai 1 ano
pai
achega
3feee729bc

+ 24 - 17
packages/router/examples/simple_routes.rs

@@ -54,10 +54,7 @@ fn main() {
 #[cfg(feature = "liveview")]
 #[component]
 fn Root(cx: Scope) -> Element {
-    let history = LiveviewHistory::new(cx);
-    render! { Router::<Route> {
-        config: || RouterConfig::default().history(history),
-    } }
+    render! { Router::<Route> {} }
 }
 
 #[cfg(not(feature = "liveview"))]
@@ -84,12 +81,19 @@ fn Route1(cx: Scope, user_id: usize, dynamic: usize, query: String, extra: Strin
             "Route1{{\n\tuser_id:{user_id},\n\tdynamic:{dynamic},\n\tquery:{query},\n\textra:{extra}\n}}"
         }
         Link {
-            to: Route::Route1 { user_id: *user_id, dynamic: *dynamic, query: String::new(), extra: extra.clone() + "." },
+            to: Route::Route1 {
+                user_id: *user_id,
+                dynamic: *dynamic,
+                query: String::new(),
+                extra: extra.clone() + ".",
+            },
             "Route1 with extra+\".\""
         }
         p { "Footer" }
         Link {
-            to: Route::Route3 { dynamic: String::new() },
+            to: Route::Route3 {
+                dynamic: String::new(),
+            },
             "Home"
         }
     }
@@ -98,13 +102,13 @@ fn Route1(cx: Scope, user_id: usize, dynamic: usize, query: String, extra: Strin
 #[component]
 fn Route2(cx: Scope, user_id: usize) -> Element {
     render! {
-        pre {
-            "Route2{{\n\tuser_id:{user_id}\n}}"
-        }
+        pre { "Route2{{\n\tuser_id:{user_id}\n}}" }
         (0..*user_id).map(|i| rsx!{ p { "{i}" } }),
         p { "Footer" }
         Link {
-            to: Route::Route3 { dynamic: String::new() },
+            to: Route::Route3 {
+                dynamic: String::new(),
+            },
             "Home"
         }
     }
@@ -130,22 +134,25 @@ fn Route3(cx: Scope, dynamic: String) -> Element {
             value: "{current_route_str.read()}"
         }
         "dynamic: {dynamic}"
-        Link {
-            to: Route::Route2 { user_id: 8888 },
-            "hello world link"
-        }
+        Link { to: Route::Route2 { user_id: 8888 }, "hello world link" }
         button {
             disabled: !navigator.can_go_back(),
-            onclick: move |_| { navigator.go_back(); },
+            onclick: move |_| {
+                navigator.go_back();
+            },
             "go back"
         }
         button {
             disabled: !navigator.can_go_forward(),
-            onclick: move |_| { navigator.go_forward(); },
+            onclick: move |_| {
+                navigator.go_forward();
+            },
             "go forward"
         }
         button {
-            onclick: move |_| { navigator.push("https://www.google.com"); },
+            onclick: move |_| {
+                navigator.push("https://www.google.com");
+            },
             "google link"
         }
         p { "Site Map" }

+ 27 - 17
packages/router/src/history/liveview.rs

@@ -132,6 +132,15 @@ where
     }
 }
 
+impl<R: Routable> Default for LiveviewHistory<R>
+where
+    <R as FromStr>::Err: std::fmt::Display,
+{
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl<R: Routable> LiveviewHistory<R>
 where
     <R as FromStr>::Err: std::fmt::Display,
@@ -141,10 +150,9 @@ where
     ///
     /// # Panics
     ///
-    /// Panics if not in a Liveview context.
-    pub fn new(cx: &ScopeState) -> Self {
+    /// Panics if the function is not called in a dioxus runtime with a Liveview context.
+    pub fn new() -> Self {
         Self::new_with_initial_path(
-            cx,
             "/".parse().unwrap_or_else(|err| {
                 panic!("index route does not exist:\n{}\n use LiveviewHistory::new_with_initial_path to set a custom path", err)
             }),
@@ -156,17 +164,16 @@ where
     ///
     /// # Panics
     ///
-    /// Panics if not in a Liveview context.
-    pub fn new_with_initial_path(cx: &ScopeState, initial_path: R) -> Self {
+    /// Panics if the function is not called in a dioxus runtime with a Liveview context.
+    pub fn new_with_initial_path(initial_path: R) -> Self {
         let (action_tx, action_rx) = tokio::sync::mpsc::unbounded_channel::<Action<R>>();
         let action_rx = Arc::new(Mutex::new(action_rx));
         let timeline = Arc::new(Mutex::new(Timeline::new(initial_path)));
         let updater_callback: Arc<RwLock<Arc<dyn Fn() + Send + Sync>>> =
             Arc::new(RwLock::new(Arc::new(|| {})));
 
-        let eval_provider = cx
-            .consume_context::<Rc<dyn EvalProvider>>()
-            .expect("evaluator not provided");
+        let eval_provider =
+            consume_context::<Rc<dyn EvalProvider>>().expect("evaluator not provided");
 
         let create_eval = Rc::new(move |script: &str| {
             eval_provider
@@ -175,7 +182,7 @@ where
         }) as Rc<dyn Fn(&str) -> Result<UseEval, EvalError>>;
 
         // Listen to server actions
-        cx.push_future({
+        push_future({
             let timeline = timeline.clone();
             let action_rx = action_rx.clone();
             let create_eval = create_eval.clone();
@@ -235,7 +242,7 @@ where
         });
 
         // Listen to browser actions
-        cx.push_future({
+        push_future({
             let updater = updater_callback.clone();
             let timeline = timeline.clone();
             let create_eval = create_eval.clone();
@@ -256,15 +263,16 @@ where
                         Option<State>,
                         Option<Session<R>>,
                         usize,
-                    )>(init_eval).expect("serializable state");
+                    )>(init_eval)
+                    .expect("serializable state");
                     let Ok(route) = R::from_str(&route.to_string()) else {
                         return;
                     };
                     let mut timeline = timeline.lock().expect("unpoisoned mutex");
                     let state = timeline.init(route.clone(), state, session, depth);
                     let state = serde_json::to_string(&state).expect("serializable state");
-                    let session = serde_json::to_string(&timeline.session())
-                        .expect("serializable session");
+                    let session =
+                        serde_json::to_string(&timeline.session()).expect("serializable session");
 
                     // Call the updater callback
                     (updater.read().unwrap())();
@@ -288,22 +296,24 @@ where
                         Ok(event) => event,
                         Err(_) => continue,
                     };
-                    let (route, state) = serde_json::from_value::<(String, Option<State>)>(event).expect("serializable state");
+                    let (route, state) = serde_json::from_value::<(String, Option<State>)>(event)
+                        .expect("serializable state");
                     let Ok(route) = R::from_str(&route.to_string()) else {
                         return;
                     };
                     let mut timeline = timeline.lock().expect("unpoisoned mutex");
                     let state = timeline.update(route.clone(), state);
                     let state = serde_json::to_string(&state).expect("serializable state");
-                    let session = serde_json::to_string(&timeline.session())
-                        .expect("serializable session");
+                    let session =
+                        serde_json::to_string(&timeline.session()).expect("serializable session");
 
                     let _ = create_eval(&format!(
                         r#"
                         // this does not trigger a PopState event
                         history.replaceState({state}, "", "{route}");
                         sessionStorage.setItem("liveview", '{session}');
-                    "#));
+                    "#
+                    ));
 
                     // Call the updater callback
                     (updater.read().unwrap())();

+ 14 - 4
packages/router/src/router_cfg.rs

@@ -53,10 +53,15 @@ where
 {
     pub(crate) fn get_history(self) -> Box<dyn HistoryProvider<R>> {
         self.history.unwrap_or_else(|| {
-            #[cfg(all(target_arch = "wasm32", feature = "web"))]
+            #[cfg(all(not(feature = "liveview"), target_arch = "wasm32", feature = "web"))]
             let history = Box::<WebHistory<R>>::default();
-            #[cfg(not(all(target_arch = "wasm32", feature = "web")))]
+            #[cfg(all(
+                not(feature = "liveview"),
+                any(not(target_arch = "wasm32"), not(feature = "web"))
+            ))]
             let history = Box::<MemoryHistory<R>>::default();
+            #[cfg(feature = "liveview")]
+            let history = Box::<LiveviewHistory<R>>::default();
             history
         })
     }
@@ -83,10 +88,15 @@ where
 {
     pub(crate) fn take_history(&mut self) -> Box<dyn AnyHistoryProvider> {
         self.history.take().unwrap_or_else(|| {
-            #[cfg(all(target_arch = "wasm32", feature = "web"))]
+            #[cfg(all(not(feature = "liveview"), target_arch = "wasm32", feature = "web"))]
             let history = Box::<AnyHistoryProviderImplWrapper<R, WebHistory<R>>>::default();
-            #[cfg(not(all(target_arch = "wasm32", feature = "web")))]
+            #[cfg(all(
+                not(feature = "liveview"),
+                any(not(target_arch = "wasm32"), not(feature = "web"))
+            ))]
             let history = Box::<AnyHistoryProviderImplWrapper<R, MemoryHistory<R>>>::default();
+            #[cfg(feature = "liveview")]
+            let history = Box::<AnyHistoryProviderImplWrapper<R, LiveviewHistory<R>>>::default();
             history
         })
     }