Skip to content

Commit

Permalink
Feat: use_debounce (#37)
Browse files Browse the repository at this point in the history
* feat: debounce

* fix: fmt

* revision: debounce

* fix: clippy

* revision: docs, compile errors

* revision: debounce

* fix: fmt

* revision: use clone

* revision: remove clone

* revision: formatting

* revision: manually partialeq
  • Loading branch information
DogeDark authored May 3, 2024
1 parent d860937 commit 57ab3fa
Show file tree
Hide file tree
Showing 17 changed files with 176 additions and 46 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
- [x] use_channel
- [x] use_window_size
- [x] use_interval
- [x] use_debounce
- [ ] use_timeout
- [ ] use_debouncer
- [ ] Camera
- [ ] WiFi
- [ ] Bluetooth
Expand Down
21 changes: 0 additions & 21 deletions examples/interval/src/main.rs

This file was deleted.

6 changes: 3 additions & 3 deletions examples/interval/Cargo.toml → examples/timing/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[package]
name = "interval"
name = "timing"
version = "0.1.0"
edition = "2021"

[dependencies]
dioxus-sdk = { workspace = true, features = ["interval"] }
dioxus = { workspace = true, features = ["web"] }
dioxus-sdk = { workspace = true, features = ["timing"] }
dioxus = { workspace = true, features = ["desktop"] }

log = "0.4.6"

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
35 changes: 35 additions & 0 deletions examples/timing/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use dioxus::prelude::*;
use dioxus_sdk::utils::timing::{use_debounce, use_interval};
use std::time::Duration;

fn main() {
// init debug tool for WebAssembly
wasm_logger::init(wasm_logger::Config::default());
console_error_panic_hook::set_once();

launch(app);
}

fn app() -> Element {
let mut count = use_signal(|| 0);

use_interval(Duration::from_millis(100), move || {
count += 1;
});

let mut debounce = use_debounce(Duration::from_millis(2000), move |text| {
println!("{text}");
count.set(0);
});

rsx! {
p { "{count}" },
button {
onclick: move |_| {
// Reset the counter after 2 seconds pass since the last click.
debounce.action("button was clicked");
},
"Reset the counter! (2 second debounce)"
}
}
}
21 changes: 13 additions & 8 deletions sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use_window_size = [

# Desktop
"dep:dioxus-desktop",

# Wasm
"web-sys/Window",
"dep:wasm-bindgen",
Expand Down Expand Up @@ -80,21 +80,25 @@ storage = [
# Not WASM
"dep:directories",
]
interval = [
timing = [
# Shared
"dep:futures",

# Desktop
"dep:tokio",
"dep:tokio",
"tokio/time",

# Wasm
"dep:gloo-timers"
"dep:gloo-timers",
]

# CI testing
wasm-testing = [
"geolocation",
"color_scheme",
"geolocation",
"channel",
"use_window_size",
"timing",
"i18n",
]
desktop-testing = [
Expand All @@ -104,6 +108,7 @@ desktop-testing = [
"channel",
"use_window_size",
"i18n",
"timing",
]


Expand Down Expand Up @@ -146,10 +151,10 @@ dioxus-signals = { version = "0.5.0-alpha.2", features = [
yazi = { version = "0.1.4", optional = true }
tracing = "0.1.40"

# Used by: interval
# Used by: timing
gloo-timers = { version = "0.3.0", optional = true }

# Used by: interval & storage
# Used by: timing & storage
tokio = { version = "1.33.0", optional = true }

# # # # # # # # #
Expand Down
11 changes: 8 additions & 3 deletions sdk/src/clipboard/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
mod use_clipboard;

pub use use_clipboard::*;
cfg_if::cfg_if! {
if #[cfg(not(target_family = "wasm"))] {
mod use_clipboard;
pub use use_clipboard::*;
} else {
compile_error!("the `clipboard` feature is only available on desktop targets");
}
}
11 changes: 8 additions & 3 deletions sdk/src/color_scheme/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
mod use_preferred_color_scheme;

pub use use_preferred_color_scheme::*;
cfg_if::cfg_if! {
if #[cfg(target_family = "wasm")] {
mod use_preferred_color_scheme;
pub use use_preferred_color_scheme::*;
} else {
compile_error!("the `color_scheme` feature is only available on wasm targets");
}
}
2 changes: 1 addition & 1 deletion sdk/src/geolocation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ cfg_if::cfg_if! {
pub use self::use_geolocation::*;
}
else {
compile_error!("The geolocation module is not supported on this platform.");
compile_error!("the `geolocation` feature is only available on wasm and windows targets");
}
}
2 changes: 1 addition & 1 deletion sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ cfg_if::cfg_if! {
}

cfg_if::cfg_if! {
if #[cfg(any(feature = "channel", feature = "use_window_size", feature = "interval"))] {
if #[cfg(any(feature = "channel", feature = "use_window_size", feature = "timing"))] {
pub mod utils;
}
}
Expand Down
8 changes: 7 additions & 1 deletion sdk/src/notification/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
pub mod notification;
cfg_if::cfg_if! {
if #[cfg(not(target_family = "wasm"))] {
pub mod notification;
} else {
compile_error!("the `notification` feature is only available on desktop targets");
}
}
4 changes: 2 additions & 2 deletions sdk/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ cfg_if::cfg_if! {
}

cfg_if::cfg_if! {
if #[cfg(feature = "interval")] {
pub mod interval;
if #[cfg(feature = "timing")] {
pub mod timing;
}
}
89 changes: 89 additions & 0 deletions sdk/src/utils/timing/debounce.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use dioxus::prelude::*;
use futures::{
channel::mpsc::{self, UnboundedSender as Sender},
StreamExt,
};
use std::time::Duration;

/// The interface for calling a debounce.
///
/// See [`use_debounce`] for more information.
pub struct UseDebounce<T: 'static> {
sender: Signal<Sender<T>>,
}

impl<T> UseDebounce<T> {
/// Will start the debounce countdown, resetting it if already started.
pub fn action(&mut self, data: T) {
self.sender.write().unbounded_send(data).ok();
}
}

// Manually implement Clone, Copy, and PartialEq as #[derive] thinks that T needs to implement these (it doesn't).

impl<T> Clone for UseDebounce<T> {
fn clone(&self) -> Self {
*self
}
}

impl<T> Copy for UseDebounce<T> {}

impl<T> PartialEq for UseDebounce<T> {
fn eq(&self, other: &Self) -> bool {
self.sender == other.sender
}
}

/// A hook for allowing a function to be called only after a provided [`Duration`] has passed.
///
/// Once the [`UseDebounce::action`] method is called, a timer will start counting down until
/// the callback is ran. If the [`UseDebounce::action`] method is called again, the timer will restart.
///
/// # Example
///
/// ```rust
/// use dioxus::prelude::*;
/// use dioxus_sdk::utils::timing::use_debounce;
/// use std::time::Duration;
///
/// fn App() -> Element {
/// let mut debounce = use_debounce(Duration::from_millis(2000), |_| println!("ran"));
///
/// rsx! {
/// button {
/// onclick: move |_| {
/// debounce.action(());
/// },
/// "Click!"
/// }
/// }
/// }
/// ```
pub fn use_debounce<T>(time: Duration, cb: impl FnOnce(T) + Copy + 'static) -> UseDebounce<T> {
use_hook(|| {
let (sender, mut receiver) = mpsc::unbounded();
let debouncer = UseDebounce {
sender: Signal::new(sender),
};

spawn(async move {
let mut current_task: Option<Task> = None;

loop {
if let Some(data) = receiver.next().await {
if let Some(task) = current_task.take() {
task.cancel();
}

current_task = Some(spawn(async move {
tokio::time::sleep(time).await;
cb(data);
}));
}
}
});

debouncer
})
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::time::Duration;

use dioxus::prelude::{use_hook, Writable};
use std::time::Duration;

#[derive(Clone, PartialEq, Copy)]
pub struct UseInterval {
Expand Down
7 changes: 7 additions & 0 deletions sdk/src/utils/timing/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//! Timing utilities.

mod interval;
pub use interval::*;

mod debounce;
pub use debounce::*;

0 comments on commit 57ab3fa

Please sign in to comment.