throttle history updates to 100ms
This commit is contained in:
1 parent
fe626c67bd
commit
bc063c58b7
3 files changed
+116
-4
No files matched your search
@@ -14,6 +14,18 @@ pub struct RouterConfigFactory<R: Routable> {
|
|||||||
config: RefCell<Option<Box<dyn FnOnce() -> RouterConfig<R>>>>,
|
config: RefCell<Option<Box<dyn FnOnce() -> RouterConfig<R>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
impl<R: Routable> Default for RouterConfigFactory<R>
|
||||||
|
where
|
||||||
|
<R as FromStr>::Err: std::fmt::Display,
|
||||||
|
R: serde::Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::from(RouterConfig::default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "serde"))]
|
||||||
impl<R: Routable> Default for RouterConfigFactory<R>
|
impl<R: Routable> Default for RouterConfigFactory<R>
|
||||||
where
|
where
|
||||||
<R as FromStr>::Err: std::fmt::Display,
|
<R as FromStr>::Err: std::fmt::Display,
|
||||||
@@ -31,6 +43,19 @@ impl<R: Routable, F: FnOnce() -> RouterConfig<R> + 'static> From<F> for RouterCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
/// The props for [`GenericRouter`].
|
||||||
|
#[derive(Props)]
|
||||||
|
pub struct GenericRouterProps<R: Routable>
|
||||||
|
where
|
||||||
|
<R as FromStr>::Err: std::fmt::Display,
|
||||||
|
R: serde::Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
#[props(default, into)]
|
||||||
|
config: RouterConfigFactory<R>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "serde"))]
|
||||||
/// The props for [`GenericRouter`].
|
/// The props for [`GenericRouter`].
|
||||||
#[derive(Props)]
|
#[derive(Props)]
|
||||||
pub struct GenericRouterProps<R: Routable>
|
pub struct GenericRouterProps<R: Routable>
|
||||||
@@ -41,6 +66,7 @@ where
|
|||||||
config: RouterConfigFactory<R>,
|
config: RouterConfigFactory<R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "serde"))]
|
||||||
impl<R: Routable> PartialEq for GenericRouterProps<R>
|
impl<R: Routable> PartialEq for GenericRouterProps<R>
|
||||||
where
|
where
|
||||||
<R as FromStr>::Err: std::fmt::Display,
|
<R as FromStr>::Err: std::fmt::Display,
|
||||||
@@ -51,6 +77,19 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
impl<R: Routable> PartialEq for GenericRouterProps<R>
|
||||||
|
where
|
||||||
|
<R as FromStr>::Err: std::fmt::Display,
|
||||||
|
R: serde::Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn eq(&self, _: &Self) -> bool {
|
||||||
|
// prevent the router from re-rendering when the initial url or config changes
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "serde"))]
|
||||||
/// A component that renders the current route.
|
/// A component that renders the current route.
|
||||||
pub fn GenericRouter<R: Routable + Clone>(cx: Scope<GenericRouterProps<R>>) -> Element
|
pub fn GenericRouter<R: Routable + Clone>(cx: Scope<GenericRouterProps<R>>) -> Element
|
||||||
where
|
where
|
||||||
@@ -79,3 +118,34 @@ where
|
|||||||
GenericOutlet::<R> {}
|
GenericOutlet::<R> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
/// A component that renders the current route.
|
||||||
|
pub fn GenericRouter<R: Routable + Clone>(cx: Scope<GenericRouterProps<R>>) -> Element
|
||||||
|
where
|
||||||
|
<R as FromStr>::Err: std::fmt::Display,
|
||||||
|
R: serde::Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
use_context_provider(cx, || {
|
||||||
|
#[allow(unreachable_code, unused_variables)]
|
||||||
|
if let Some(outer) = cx.consume_context::<GenericRouterContext<R>>() {
|
||||||
|
let msg = "Router components should not be nested within each other";
|
||||||
|
error!("{msg}, inner will be inactive and transparent");
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
panic!("{}", msg);
|
||||||
|
}
|
||||||
|
let router = GenericRouterContext::new(
|
||||||
|
(cx.props
|
||||||
|
.config
|
||||||
|
.config
|
||||||
|
.take()
|
||||||
|
.expect("use_context_provider ran twice"))(),
|
||||||
|
cx.schedule_update_any(),
|
||||||
|
);
|
||||||
|
router
|
||||||
|
});
|
||||||
|
|
||||||
|
render! {
|
||||||
|
GenericOutlet::<R> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -104,8 +104,18 @@ impl<R: Routable> WebHistory<R> {
|
|||||||
let myself = Self::new_inner(
|
let myself = Self::new_inner(
|
||||||
prefix,
|
prefix,
|
||||||
do_scroll_restoration,
|
do_scroll_restoration,
|
||||||
EventListener::new(&document, "scroll", move |_| {
|
EventListener::new(&document, "scroll", {
|
||||||
update_scroll::<R>(&w, &h);
|
let mut last_updated = 0.0;
|
||||||
|
move |evt| {
|
||||||
|
// the time stamp in milliseconds
|
||||||
|
let time_stamp = evt.time_stamp();
|
||||||
|
// throttle the scroll event to 100ms
|
||||||
|
if (time_stamp - last_updated) < 100.0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
update_scroll::<R>(&w, &h);
|
||||||
|
last_updated = time_stamp;
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -134,8 +144,18 @@ impl<R: Routable> WebHistory<R> {
|
|||||||
let myself = Self::new_inner(
|
let myself = Self::new_inner(
|
||||||
prefix,
|
prefix,
|
||||||
do_scroll_restoration,
|
do_scroll_restoration,
|
||||||
EventListener::new(&document, "scroll", move |_| {
|
EventListener::new(&document, "scroll", {
|
||||||
update_scroll::<R>(&w, &h);
|
let mut last_updated = 0.0;
|
||||||
|
move |evt| {
|
||||||
|
// the time stamp in milliseconds
|
||||||
|
let time_stamp = evt.time_stamp();
|
||||||
|
// throttle the scroll event to 100ms
|
||||||
|
if (time_stamp - last_updated) < 100.0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
update_scroll::<R>(&w, &h);
|
||||||
|
last_updated = time_stamp;
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,28 @@ pub struct RouterConfig<R: Routable> {
|
|||||||
pub(crate) on_update: Option<RoutingCallback<R>>,
|
pub(crate) on_update: Option<RoutingCallback<R>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
impl<R: Routable + Clone> Default for RouterConfig<R>
|
||||||
|
where
|
||||||
|
<R as std::str::FromStr>::Err: std::fmt::Display,
|
||||||
|
R: serde::Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
failure_external_navigation: FailureExternalNavigation::<R>,
|
||||||
|
history: {
|
||||||
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
|
let history = Box::<WebHistory<R>>::default();
|
||||||
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
|
let history = Box::<MemoryHistory<R>>::default();
|
||||||
|
history
|
||||||
|
},
|
||||||
|
on_update: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "serde"))]
|
||||||
impl<R: Routable + Clone> Default for RouterConfig<R>
|
impl<R: Routable + Clone> Default for RouterConfig<R>
|
||||||
where
|
where
|
||||||
<R as std::str::FromStr>::Err: std::fmt::Display,
|
<R as std::str::FromStr>::Err: std::fmt::Display,
|
||||||
|
|||||||
Reference in new issue
Block a user