use std::cell::Cell;
use day_spec::{Event, NodeId};
use objc2::runtime::AnyObject;
use objc2_app_kit::{NSScrollView, NSViewBoundsDidChangeNotification};
use objc2_foundation::{NSNotification, NSNotificationCenter};
const PULL_THRESHOLD: f64 = 60.0;
pub(crate) fn attach(view: &objc2::rc::Retained<objc2_app_kit::NSView>, host: NodeId) {
let Some(sv) = view.downcast_ref::<NSScrollView>() else {
return; };
let clip = sv.contentView();
clip.setPostsBoundsChangedNotifications(true);
let armed = Cell::new(true);
let clip_for_block = clip.clone();
let block = block2::RcBlock::new(move |_: std::ptr::NonNull<NSNotification>| {
let y = clip_for_block.bounds().origin.y;
if y <= -PULL_THRESHOLD {
if armed.get() {
armed.set(false);
crate::emit(host, Event::custom("pullrefresh:begin", ""));
}
} else if y >= 0.0 {
armed.set(true);
}
});
let center = NSNotificationCenter::defaultCenter();
let clip_obj: &AnyObject = &clip;
let token = unsafe {
center.addObserverForName_object_queue_usingBlock(
Some(NSViewBoundsDidChangeNotification),
Some(clip_obj),
None,
&block,
)
};
day_reactive::Scope::current().on_cleanup(move || {
let center = NSNotificationCenter::defaultCenter();
let ptr = objc2::rc::Retained::as_ptr(&token) as *const AnyObject;
unsafe { center.removeObserver(&*ptr) };
});
}