1- use dioxus:: prelude:: { use_hook, Callback , Writable } ;
1+ use dioxus:: {
2+ dioxus_core:: SpawnIfAsync ,
3+ prelude:: { spawn, use_hook, Callback , Task , Writable } ,
4+ signals:: Signal ,
5+ } ;
26use std:: time:: Duration ;
37
48/// The interface to a debounce.
59///
6- /// This handle allows you to cancel an interval.
10+ /// You can cancel an interval with [`UseInterval::cancel`].
11+ /// See [`use_interval`] for more information.
712#[ derive( Clone , PartialEq , Copy ) ]
813pub struct UseInterval {
9- inner : dioxus :: prelude :: Signal < InnerUseInterval > ,
14+ inner : Signal < InnerUseInterval > ,
1015}
1116
1217struct InnerUseInterval {
13- pub ( crate ) interval : Option < dioxus :: prelude :: Task > ,
18+ pub ( crate ) interval : Option < Task > ,
1419}
1520
1621impl Drop for InnerUseInterval {
@@ -35,6 +40,50 @@ impl UseInterval {
3540/// Intervals are cancelable with the [`UseInterval::cancel`] method.
3641///
3742/// # Examples
43+ ///
44+ /// Example of using an interval:
45+ /// ```rust
46+ /// use dioxus::prelude::*;
47+ /// use dioxus_time::use_interval;
48+ /// use std::time::Duration;
49+ ///
50+ /// #[component]
51+ /// fn App() -> Element {
52+ /// let mut time_elapsed = use_signal(|| 0);
53+ /// // Create an interval that increases the time elapsed signal by one every second.
54+ /// use_interval(Duration::from_secs(1), move |()| time_elapsed += 1);
55+ ///
56+ /// rsx! {
57+ /// "It has been {time_elapsed} since the app started."
58+ /// }
59+ /// }
60+ /// ```
61+ ///
62+ /// #### Cancelling Intervals
63+ /// Example of cancelling an interval:
64+ /// ```rust
65+ /// use dioxus::prelude::*;
66+ /// use dioxus_time::use_interval;
67+ /// use std::time::Duration;
68+ ///
69+ /// #[component]
70+ /// fn App() -> Element {
71+ /// let mut time_elapsed = use_signal(|| 0);
72+ /// let mut interval = use_interval(Duration::from_secs(1), move |()| time_elapsed += 1);
73+ ///
74+ /// rsx! {
75+ /// "It has been {time_elapsed} since the app started."
76+ /// button {
77+ /// // Cancel the interval when the button is clicked.
78+ /// onclick: move |_| interval.cancel(),
79+ /// "Cancel Interval"
80+ /// }
81+ /// }
82+ /// }
83+ /// ```
84+ ///
85+ /// #### Async Intervals
86+ /// Intervals can accept an async callback:
3887/// ```rust
3988/// use dioxus::prelude::*;
4089/// use dioxus_time::use_interval;
@@ -43,34 +92,45 @@ impl UseInterval {
4392/// #[component]
4493/// fn App() -> Element {
4594/// let mut time_elapsed = use_signal(|| 0);
46- /// use_interval(Duration::from_secs(1), move || *time_elapsed.write() += 1);
95+ /// // Create an interval that increases the time elapsed signal by one every second.
96+ /// use_interval(Duration::from_secs(1), move |()| async move {
97+ /// time_elapsed += 1;
98+ /// // Pretend we're doing some async work.
99+ /// tokio::time::sleep(Duration::from_secs(1)).await;
100+ /// println!("Done!");
101+ /// });
47102///
48103/// rsx! {
49104/// "It has been {time_elapsed} since the app started."
50105/// }
51106/// }
52107/// ```
53- pub fn use_interval ( period : Duration , mut action : impl FnMut ( ) + ' static ) -> UseInterval {
108+ pub fn use_interval < MaybeAsync : SpawnIfAsync < Marker > , Marker > (
109+ period : Duration ,
110+ callback : impl FnMut ( ( ) ) -> MaybeAsync + ' static ,
111+ ) -> UseInterval {
54112 let inner = use_hook ( || {
55- let callback = Callback :: new ( move |( ) | {
56- action ( ) ;
57- } ) ;
113+ let callback = Callback :: new ( callback) ;
58114
59- dioxus:: prelude:: Signal :: new ( InnerUseInterval {
60- interval : Some ( dioxus:: prelude:: spawn ( async move {
61- #[ cfg( not( target_family = "wasm" ) ) ]
62- let mut interval = tokio:: time:: interval ( period) ;
115+ let task = spawn ( async move {
116+ #[ cfg( not( target_family = "wasm" ) ) ]
117+ let mut interval = tokio:: time:: interval ( period) ;
63118
64- loop {
65- #[ cfg( not( target_family = "wasm" ) ) ]
66- interval. tick ( ) . await ;
119+ loop {
120+ #[ cfg( not( target_family = "wasm" ) ) ]
121+ interval. tick ( ) . await ;
67122
68- #[ cfg( target_family = "wasm" ) ]
123+ #[ cfg( target_family = "wasm" ) ]
124+ {
69125 gloo_timers:: future:: sleep ( period) . await ;
70-
71- callback. call ( ( ) ) ;
72126 }
73- } ) ) ,
127+
128+ callback. call ( ( ) ) ;
129+ }
130+ } ) ;
131+
132+ Signal :: new ( InnerUseInterval {
133+ interval : Some ( task) ,
74134 } )
75135 } ) ;
76136
0 commit comments