diff --git a/src/ui/hooks/mod.rs b/src/ui/hooks/mod.rs new file mode 100644 index 0000000..4a7932f --- /dev/null +++ b/src/ui/hooks/mod.rs @@ -0,0 +1,3 @@ +pub use use_long_press::use_long_press; + +mod use_long_press; diff --git a/src/ui/hooks/use_long_press.rs b/src/ui/hooks/use_long_press.rs new file mode 100644 index 0000000..2044bdd --- /dev/null +++ b/src/ui/hooks/use_long_press.rs @@ -0,0 +1,60 @@ +use std::{cell::RefCell, time::Duration}; + +use async_std::task; +use dioxus::prelude::*; + +pub struct UseLongPress { + _timer: UseFuture, + pub handlers: Vec, +} + +pub fn use_long_press( + duration: Duration, + on_press: impl FnMut() + 'static, + on_long_press: impl FnMut() + 'static, +) -> UseLongPress { + let on_press = std::rc::Rc::new(RefCell::new(on_press)); + let on_press_cb = use_callback(move || { + let mut on_press = on_press.as_ref().borrow_mut(); + on_press(); + }); + + let on_long_press = std::rc::Rc::new(RefCell::new(on_long_press)); + let on_long_press_cb = use_callback(move || { + let mut on_long_press = on_long_press.as_ref().borrow_mut(); + on_long_press(); + }); + + let mut timer = use_future(move || async move { + task::sleep(duration).await; + on_long_press_cb.call(); + }); + + timer.cancel(); + + let selection_begin_cb = move |_: Event| { + timer.restart(); + }; + + let selection_end_cb = move |_: Event| { + if !timer.finished() { + timer.cancel(); + on_press_cb.call(); + } + }; + + let mut handlers = Vec::new(); + for event_name in ["onmousedown", "ontouchstart"] { + let value = dioxus_core::AttributeValue::listener(selection_begin_cb); + handlers.push(Attribute::new(event_name, value, None, false)); + } + for event_name in ["onmouseup", "ontouchend"] { + let value = dioxus_core::AttributeValue::listener(selection_end_cb); + handlers.push(Attribute::new(event_name, value, None, false)); + } + + UseLongPress { + _timer: timer, + handlers, + } +} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index d3dc2dd..134b666 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,4 +1,5 @@ pub(crate) mod components; +pub(crate) mod hooks; pub(crate) mod layouts; pub(crate) mod store;