diff --git a/packages/router/examples/simple_routes.rs b/packages/router/examples/simple_routes.rs index 6c33c275b..9317f0f36 100644 --- a/packages/router/examples/simple_routes.rs +++ b/packages/router/examples/simple_routes.rs @@ -54,8 +54,7 @@ fn main() { #[cfg(feature = "liveview")] #[component] fn Root(cx: Scope) -> Element { - let history = LiveviewHistory::new(cx); - render! { Router:: { config: || RouterConfig::default().history(history) } } + render! { Router:: {} } } #[cfg(not(feature = "liveview"))] diff --git a/packages/router/src/history/liveview.rs b/packages/router/src/history/liveview.rs index 9ffb09c34..354d259b1 100644 --- a/packages/router/src/history/liveview.rs +++ b/packages/router/src/history/liveview.rs @@ -132,6 +132,15 @@ where } } +impl Default for LiveviewHistory +where + ::Err: std::fmt::Display, +{ + fn default() -> Self { + Self::new() + } +} + impl LiveviewHistory where ::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::>(); let action_rx = Arc::new(Mutex::new(action_rx)); let timeline = Arc::new(Mutex::new(Timeline::new(initial_path))); let updater_callback: Arc>> = Arc::new(RwLock::new(Arc::new(|| {}))); - let eval_provider = cx - .consume_context::>() - .expect("evaluator not provided"); + let eval_provider = + consume_context::>().expect("evaluator not provided"); let create_eval = Rc::new(move |script: &str| { eval_provider @@ -175,7 +182,7 @@ where }) as Rc Result>; // 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, Option>, 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)>(event).expect("serializable state"); + let (route, state) = serde_json::from_value::<(String, Option)>(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())(); diff --git a/packages/router/src/router_cfg.rs b/packages/router/src/router_cfg.rs index dd379e493..e0d2ce358 100644 --- a/packages/router/src/router_cfg.rs +++ b/packages/router/src/router_cfg.rs @@ -53,10 +53,15 @@ where { pub(crate) fn get_history(self) -> Box> { 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::>::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::>::default(); + #[cfg(feature = "liveview")] + let history = Box::>::default(); history }) } @@ -83,9 +88,17 @@ where { pub(crate) fn take_history(&mut self) -> Box { self.history.take().unwrap_or_else(|| { + // If we are on wasm32 and the web feature is enabled, use the web history. #[cfg(all(target_arch = "wasm32", feature = "web"))] let history = Box::>>::default(); - #[cfg(not(all(target_arch = "wasm32", feature = "web")))] + // If we are not on wasm32 and the liveview feature is enabled, use the liveview history. + #[cfg(all(feature = "liveview", not(target_arch = "wasm32")))] + let history = Box::>>::default(); + // If neither of the above are true, use the memory history. + #[cfg(all( + not(all(target_arch = "wasm32", feature = "web")), + not(all(feature = "liveview", not(target_arch = "wasm32"))), + ))] let history = Box::>>::default(); history })