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, } }