use std::{cell::RefCell, rc::Rc};
use yew::prelude::{hook, use_effect_with, use_state};
use crate::{
api::theme::get_theme_params,
core::types::theme_params::TelegramThemeParams,
webapp::{EventHandle, TelegramWebApp}
};
type HandleSlot = Rc<RefCell<Option<EventHandle<dyn FnMut()>>>>;
#[derive(Clone, Debug, PartialEq, Default)]
pub struct ThemeState {
pub color_scheme: Option<String>,
pub params: TelegramThemeParams
}
impl ThemeState {
fn snapshot(app: Option<&TelegramWebApp>) -> Self {
let color_scheme = app.and_then(|a| a.color_scheme());
let params = get_theme_params().unwrap_or_default();
Self {
color_scheme,
params
}
}
}
#[hook]
pub fn use_theme() -> ThemeState {
let state = use_state(|| ThemeState::snapshot(TelegramWebApp::instance().as_ref()));
{
let state = state.clone();
use_effect_with((), move |_| {
let stash: HandleSlot = Rc::new(RefCell::new(None));
if let Some(app) = TelegramWebApp::instance() {
let app_for_handler = app.clone();
let state_for_handler = state.clone();
if let Ok(handle) = app.on_theme_changed(move || {
state_for_handler.set(ThemeState::snapshot(Some(&app_for_handler)));
}) {
*stash.borrow_mut() = Some(handle);
}
}
move || {
stash.borrow_mut().take();
}
});
}
(*state).clone()
}