2023-06-15 20:10:30 +01:00
|
|
|
use crate::utils::{CloneableFn, CloneableFnWithArg, Pausable};
|
|
|
|
use crate::{use_interval_fn, use_interval_fn_with_options, watch, UseIntervalFnOptions};
|
2023-06-15 18:02:13 +02:00
|
|
|
use default_struct_builder::DefaultBuilder;
|
|
|
|
use leptos::leptos_dom::helpers::IntervalHandle;
|
|
|
|
use leptos::*;
|
|
|
|
use std::cell::Cell;
|
|
|
|
use std::marker::PhantomData;
|
|
|
|
use std::rc::Rc;
|
|
|
|
use std::time::Duration;
|
|
|
|
|
|
|
|
/// Reactive counter increases on every interval.
|
|
|
|
///
|
|
|
|
/// ## Demo
|
|
|
|
///
|
|
|
|
/// [Link to Demo](https://github.com/Synphonyte/leptos-use/tree/main/examples/use_interval)
|
|
|
|
///
|
|
|
|
/// ## Usage
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use leptos::*;
|
|
|
|
/// # use leptos_use::{use_interval, UseIntervalReturn};
|
|
|
|
/// #
|
|
|
|
/// # #[component]
|
|
|
|
/// # fn Demo(cx: Scope) -> impl IntoView {
|
|
|
|
/// let UseIntervalReturn {
|
|
|
|
/// counter,
|
|
|
|
/// reset,
|
|
|
|
/// is_active,
|
|
|
|
/// pause,
|
|
|
|
/// resume
|
|
|
|
/// } = use_interval( cx, 200 );
|
|
|
|
/// # view! { cx, }
|
|
|
|
/// # }
|
|
|
|
/// ```
|
|
|
|
pub fn use_interval<N>(
|
|
|
|
cx: Scope,
|
|
|
|
interval: N,
|
|
|
|
) -> UseIntervalReturn<impl Fn() + Clone, impl Fn() + Clone, impl Fn() + Clone>
|
2023-06-15 20:10:30 +01:00
|
|
|
where
|
|
|
|
N: Into<MaybeSignal<u64>>,
|
2023-06-15 18:02:13 +02:00
|
|
|
{
|
2023-06-15 20:10:30 +01:00
|
|
|
use_interval_with_options(cx, interval, UseIntervalOptions::default())
|
2023-06-15 18:02:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Version of [`use_interval`] that takes `UseIntervalOptions`. See [`use_interval`] for how to use.
|
2023-06-15 20:10:30 +01:00
|
|
|
pub fn use_interval_with_options<N>(
|
2023-06-15 18:02:13 +02:00
|
|
|
cx: Scope,
|
|
|
|
interval: N,
|
2023-06-15 20:10:30 +01:00
|
|
|
options: UseIntervalOptions,
|
2023-06-15 18:02:13 +02:00
|
|
|
) -> UseIntervalReturn<impl Fn() + Clone, impl Fn() + Clone, impl Fn() + Clone>
|
2023-06-15 20:10:30 +01:00
|
|
|
where
|
|
|
|
N: Into<MaybeSignal<u64>>,
|
2023-06-15 18:02:13 +02:00
|
|
|
{
|
|
|
|
let UseIntervalOptions {
|
|
|
|
immediate,
|
|
|
|
callback,
|
|
|
|
} = options;
|
|
|
|
|
|
|
|
let (counter, set_counter) = create_signal(cx, 0u64);
|
|
|
|
|
|
|
|
let update = move || set_counter.update(|count| *count += 1);
|
|
|
|
let reset = move || set_counter(0);
|
|
|
|
|
2023-06-15 20:10:30 +01:00
|
|
|
let cb = move || {
|
|
|
|
update();
|
|
|
|
callback.clone()(counter());
|
|
|
|
};
|
2023-06-15 18:02:13 +02:00
|
|
|
|
2023-06-15 20:10:30 +01:00
|
|
|
let Pausable {
|
|
|
|
is_active,
|
|
|
|
pause,
|
|
|
|
resume,
|
|
|
|
} = use_interval_fn_with_options(
|
|
|
|
cx,
|
|
|
|
cb,
|
|
|
|
interval,
|
|
|
|
UseIntervalFnOptions {
|
|
|
|
immediate,
|
|
|
|
immediate_callback: false,
|
|
|
|
},
|
|
|
|
);
|
2023-06-15 18:02:13 +02:00
|
|
|
|
|
|
|
UseIntervalReturn {
|
|
|
|
counter: counter.into(),
|
|
|
|
reset,
|
|
|
|
is_active,
|
|
|
|
pause,
|
|
|
|
resume,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Options for [`use_interval_with_options`]
|
|
|
|
#[derive(DefaultBuilder)]
|
2023-06-15 20:10:30 +01:00
|
|
|
pub struct UseIntervalOptions {
|
2023-06-15 18:02:13 +02:00
|
|
|
/// Start the timer immediately. Defaults to `true`.
|
|
|
|
immediate: bool,
|
|
|
|
|
|
|
|
/// Callback on every interval.
|
2023-06-15 20:10:30 +01:00
|
|
|
#[builder(into)]
|
|
|
|
callback: Box<dyn CloneableFnWithArg<u64>>,
|
2023-06-15 18:02:13 +02:00
|
|
|
}
|
|
|
|
|
2023-06-15 20:10:30 +01:00
|
|
|
impl Default for UseIntervalOptions {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
immediate: false,
|
|
|
|
callback: Box::new(|_: u64| {}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-06-15 18:02:13 +02:00
|
|
|
|
|
|
|
/// Return type of [`use_interval`].
|
|
|
|
#[derive(DefaultBuilder)]
|
|
|
|
pub struct UseIntervalReturn<PauseFn, ResumeFn, ResetFn>
|
2023-06-15 20:10:30 +01:00
|
|
|
where
|
|
|
|
PauseFn: Fn() + Clone,
|
|
|
|
ResumeFn: Fn() + Clone,
|
|
|
|
ResetFn: Fn() + Clone,
|
2023-06-15 18:02:13 +02:00
|
|
|
{
|
|
|
|
/// Counter signal that increases by one every interval.
|
|
|
|
pub counter: Signal<u64>,
|
|
|
|
|
|
|
|
/// Reset the counter to zero
|
|
|
|
pub reset: ResetFn,
|
|
|
|
|
|
|
|
/// A Signal that indicates whether the counter is active. `false` when paused.
|
|
|
|
pub is_active: Signal<bool>,
|
|
|
|
|
|
|
|
/// Temporarily pause the counter
|
|
|
|
pub pause: PauseFn,
|
|
|
|
|
|
|
|
/// Resume the counter
|
|
|
|
pub resume: ResumeFn,
|
2023-06-15 20:10:30 +01:00
|
|
|
}
|