use wasm_bindgen::JsCast;
use wasm_bindgen::prelude::*;
use web_sys::*;
use crate::config::ViewerConfigUpdate;
use crate::js::*;
use crate::presentation::Presentation;
use crate::renderer::*;
use crate::session::Session;
use crate::tasks::*;
use crate::utils::*;
use crate::*;
pub struct IntersectionObserverHandle {
elem: HtmlElement,
observer: IntersectionObserver,
_callback: Closure<dyn FnMut(js_sys::Array)>,
}
impl IntersectionObserverHandle {
pub fn new(
elem: &HtmlElement,
presentation: &Presentation,
session: &Session,
renderer: &Renderer,
) -> Self {
clone!(session, renderer, presentation);
let _callback = Closure::new(move |xs: js_sys::Array| {
let intersect = xs
.pop()
.unchecked_into::<IntersectionObserverEntry>()
.is_intersecting();
clone!(session, renderer, presentation);
let state = IntersectionObserverState {
presentation,
session,
renderer,
};
ApiFuture::spawn(state.set_pause(intersect));
});
let func = _callback.as_ref().unchecked_ref::<js_sys::Function>();
let observer = IntersectionObserver::new(func);
observer.observe(elem);
Self {
elem: elem.clone(),
_callback,
observer,
}
}
}
impl Drop for IntersectionObserverHandle {
fn drop(&mut self) {
self.observer.unobserve(&self.elem);
}
}
struct IntersectionObserverState {
session: Session,
renderer: Renderer,
presentation: Presentation,
}
impl HasPresentation for IntersectionObserverState {
fn presentation(&self) -> &Presentation {
&self.presentation
}
}
impl HasRenderer for IntersectionObserverState {
fn renderer(&self) -> &Renderer {
&self.renderer
}
}
impl HasSession for IntersectionObserverState {
fn session(&self) -> &Session {
&self.session
}
}
impl IntersectionObserverState {
async fn set_pause(self, intersect: bool) -> ApiResult<()> {
if intersect {
if self.session.set_pause(false) {
self.restore_and_render(ViewerConfigUpdate::default(), async move { Ok(()) })
.await?;
}
} else {
self.session.set_pause(true);
};
Ok(())
}
}