use crate::{
Pausable, TimestampInterval, UseIntervalFnOptions, UseRafFnOptions, UseTimestampOptions,
UseTimestampReturn, now, use_interval_fn_with_options, use_raf_fn_with_options,
};
use leptos::prelude::*;
use leptos::reactive::wrappers::read::Signal;
use std::rc::Rc;
use std::sync::Arc;
pub fn use_timestamp() -> Signal<f64> {
use_timestamp_with_controls().timestamp
}
pub fn use_timestamp_with_options(options: UseTimestampOptions) -> Signal<f64> {
use_timestamp_with_controls_and_options(options).timestamp
}
pub fn use_timestamp_with_controls() -> UseTimestampReturn {
use_timestamp_with_controls_and_options(UseTimestampOptions::default())
}
pub fn use_timestamp_with_controls_and_options(options: UseTimestampOptions) -> UseTimestampReturn {
let UseTimestampOptions {
offset,
immediate,
interval,
callback,
} = options;
let (ts, set_ts) = signal(now() + offset);
let update = move || {
set_ts.set(now() + offset);
};
let cb = {
let callback = Rc::clone(&callback);
move || {
update();
#[cfg(debug_assertions)]
let _z = leptos::reactive::diagnostics::SpecialNonReactiveZone::enter();
callback(ts.get_untracked());
}
};
match interval {
TimestampInterval::RequestAnimationFrame => {
let Pausable {
pause,
resume,
is_active,
} = use_raf_fn_with_options(
move |_| cb(),
UseRafFnOptions::default().immediate(immediate),
);
UseTimestampReturn {
timestamp: ts.into(),
is_active,
pause: Arc::new(pause),
resume: Arc::new(resume),
}
}
TimestampInterval::Interval(interval) => {
let Pausable {
pause,
resume,
is_active,
} = use_interval_fn_with_options(
cb,
interval,
UseIntervalFnOptions::default().immediate(immediate),
);
UseTimestampReturn {
timestamp: ts.into(),
is_active,
pause: Arc::new(pause),
resume: Arc::new(resume),
}
}
}
}