static SEEN: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
pub fn on_first_user_gesture(f: impl Fn() + 'static) {
#[cfg(target_arch = "wasm32")]
install(f);
#[cfg(not(target_arch = "wasm32"))]
let _ = f;
}
#[cfg(target_arch = "wasm32")]
fn install(f: impl Fn() + 'static) {
use std::sync::atomic::Ordering;
use wasm_bindgen::closure::Closure;
use wasm_bindgen::JsCast;
let global = js_sys::global();
let Ok(add) = js_sys::Reflect::get(&global, &wasm_bindgen::JsValue::from_str(
"addEventListener",
)) else {
return;
};
let Some(add) = add.dyn_ref::<js_sys::Function>() else {
return;
};
let handler = Closure::wrap(Box::new(move || {
if !SEEN.swap(true, Ordering::SeqCst) {
f();
}
}) as Box<dyn FnMut()>)
.into_js_value();
for event in ["pointerdown", "touchstart", "keydown"] {
let _ = add.call2(
&global,
&wasm_bindgen::JsValue::from_str(event),
&handler,
);
}
}
pub fn user_gesture_seen() -> bool {
SEEN.load(std::sync::atomic::Ordering::SeqCst)
}