yggdrasil/hooks/
event_listener.rs1#[cfg(target_arch = "wasm32")]
33pub fn use_event_listener<T, A, F>(acquire: A, event: &'static str, handler: F)
34where
35 T: AsRef<web_sys::EventTarget> + Clone + 'static,
36 A: FnOnce() -> Option<T> + 'static,
37 F: FnMut() + 'static,
38{
39 use dioxus::prelude::*;
40 use std::cell::RefCell;
41 use std::rc::Rc;
42
43 type ListenerState<T> = Rc<RefCell<Option<(wasm_bindgen::prelude::Closure<dyn FnMut()>, T)>>>;
46 let state: ListenerState<T> = use_hook(|| Rc::new(RefCell::new(None)));
47 let state_for_drop = state.clone();
48
49 let mut acquire = Some(acquire);
52 let mut handler = Some(handler);
53
54 use_effect(move || {
55 let Some(acquire) = acquire.take() else {
56 return;
57 };
58 let Some(mut handler) = handler.take() else {
59 return;
60 };
61 let Some(target) = acquire() else { return };
62 let target_clone = target.clone();
63 let closure = wasm_bindgen::prelude::Closure::wrap(Box::new(move || {
64 handler();
65 }) as Box<dyn FnMut()>);
66 let _ = target_clone.as_ref().add_event_listener_with_callback(
67 event,
68 wasm_bindgen::JsCast::unchecked_ref(closure.as_ref()),
69 );
70 *state.borrow_mut() = Some((closure, target_clone));
71 });
72
73 use_drop(move || {
74 if let Some((closure, tgt)) = state_for_drop.borrow_mut().take() {
75 let _ = tgt.as_ref().remove_event_listener_with_callback(
76 event,
77 wasm_bindgen::JsCast::unchecked_ref(closure.as_ref()),
78 );
79 }
80 });
81}
82
83#[cfg(not(target_arch = "wasm32"))]
87#[allow(unused_variables, dead_code)]
88pub fn use_event_listener<T, A, F>(acquire: A, event: &'static str, handler: F)
89where
90 T: Clone + 'static,
91 A: FnOnce() -> Option<T> + 'static,
92 F: FnMut() + 'static,
93{
94 }