mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-23 12:43:08 +00:00
throttle history updates to 100ms
This commit is contained in:
parent
fe626c67bd
commit
bc063c58b7
3 changed files with 116 additions and 4 deletions
|
@ -14,6 +14,18 @@ pub struct RouterConfigFactory<R: Routable> {
|
|||
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>
|
||||
where
|
||||
<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`].
|
||||
#[derive(Props)]
|
||||
pub struct GenericRouterProps<R: Routable>
|
||||
|
@ -41,6 +66,7 @@ where
|
|||
config: RouterConfigFactory<R>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "serde"))]
|
||||
impl<R: Routable> PartialEq for GenericRouterProps<R>
|
||||
where
|
||||
<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.
|
||||
pub fn GenericRouter<R: Routable + Clone>(cx: Scope<GenericRouterProps<R>>) -> Element
|
||||
where
|
||||
|
@ -79,3 +118,34 @@ where
|
|||
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(
|
||||
prefix,
|
||||
do_scroll_restoration,
|
||||
EventListener::new(&document, "scroll", move |_| {
|
||||
update_scroll::<R>(&w, &h);
|
||||
EventListener::new(&document, "scroll", {
|
||||
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(
|
||||
prefix,
|
||||
do_scroll_restoration,
|
||||
EventListener::new(&document, "scroll", move |_| {
|
||||
update_scroll::<R>(&w, &h);
|
||||
EventListener::new(&document, "scroll", {
|
||||
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>>,
|
||||
}
|
||||
|
||||
#[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>
|
||||
where
|
||||
<R as std::str::FromStr>::Err: std::fmt::Display,
|
||||
|
|
Loading…
Reference in a new issue