use leptos::prelude::*;
use leptos::wasm_bindgen::closure::Closure;
use leptos::wasm_bindgen::JsCast;
use leptos::web_sys;
use std::sync::atomic::{AtomicU64, Ordering};
static CARD_ID_COUNTER: AtomicU64 = AtomicU64::new(1);
pub fn next_card_id() -> u64 {
CARD_ID_COUNTER.fetch_add(1, Ordering::Relaxed)
}
#[derive(Clone, Copy)]
pub struct GlobalMouseState {
pub position: RwSignal<(f64, f64)>,
pub active_card: RwSignal<Option<u64>>,
}
impl GlobalMouseState {
fn new() -> Self {
Self {
position: RwSignal::new((0.0, 0.0)),
active_card: RwSignal::new(None),
}
}
}
pub fn provide_global_mouse() {
let state = GlobalMouseState::new();
provide_context(state);
let position = state.position;
let active_card = state.active_card;
let window = web_sys::window().expect("window");
let on_move = Closure::wrap(Box::new(move |e: web_sys::MouseEvent| {
position.set((e.client_x() as f64, e.client_y() as f64));
}) as Box<dyn FnMut(web_sys::MouseEvent)>);
let on_up = Closure::wrap(Box::new(move |_: web_sys::MouseEvent| {
active_card.set(None);
}) as Box<dyn FnMut(web_sys::MouseEvent)>);
let _ = window.add_event_listener_with_callback("mousemove", on_move.as_ref().unchecked_ref());
let _ = window.add_event_listener_with_callback("mouseup", on_up.as_ref().unchecked_ref());
on_move.forget();
on_up.forget();
}
pub fn use_global_mouse() -> GlobalMouseState {
use_context::<GlobalMouseState>()
.expect("GlobalMouseState not found — call provide_global_mouse() in App")
}