use crate::{
dom::{window, Application,util, Task, Program, dom_node::intern},
vdom::Attribute,
};
use wasm_bindgen::{prelude::*, JsCast};
use js_sys::Promise;
use wasm_bindgen_futures::JsFuture;
impl<APP, MSG> Program<APP, MSG>
where
MSG: 'static,
APP: Application<MSG> + 'static,
{
pub fn add_window_event_listeners(&self, event_listeners: Vec<Attribute<MSG>>) {
self.add_event_listeners(&window(), event_listeners).expect("must add to event listener");
}
pub fn on_resize<F>(&self, mut cb: F)
where
F: FnMut(i32, i32) -> MSG + Clone + 'static,
{
let program = self.clone();
let closure: Closure<dyn FnMut(web_sys::Event)> =
Closure::new(move|_| {
let (window_width, window_height) = util::get_window_size();
let msg = cb(window_width, window_height);
program.dispatch(msg);
});
window().add_event_listener_with_callback(intern("resize"), closure.as_ref().unchecked_ref()).expect("resize callback");
self.event_closures.borrow_mut().push(closure);
}
pub fn on_resize_task<F>(mut cb: F) -> Task<MSG>
where
F: FnMut(i32, i32) -> MSG + Clone + 'static,
{
Task::new(async move{
let promise = Promise::new(&mut |resolve, _reject|{
let resize_callback: Closure<dyn FnMut(web_sys::Event)> =
Closure::new(move|_| {
resolve.call0(&JsValue::NULL).expect("must resolve");
});
window().add_event_listener_with_callback(intern("resize"), resize_callback.as_ref().unchecked_ref()).expect("add event callback");
resize_callback.forget();
});
JsFuture::from(promise).await.expect("must await");
let (window_width, window_height) = util::get_window_size();
cb(window_width, window_height)
})
}
pub fn on_hashchange<F>(&self, mut cb: F)
where
F: FnMut(String) -> MSG + 'static,
{
let program = self.clone();
let closure: Closure<dyn FnMut(web_sys::Event)> =
Closure::new(move |_| {
let hash = util::get_location_hash();
let msg = cb(hash);
program.dispatch(msg);
});
window().set_onhashchange(Some(closure.as_ref().unchecked_ref()));
self.event_closures.borrow_mut().push(closure);
}
}