fix web history

This commit is contained in:
Evan Almloff 2023-05-23 11:58:12 -05:00
parent b91fb39142
commit dd48c5a163
5 changed files with 45 additions and 15 deletions

View file

@ -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,
{

View file

@ -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.

View file

@ -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

View file

@ -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()
})
}

View file

@ -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;
}