telegram_webapp_sdk/yew/
theme.rs1use std::{cell::RefCell, rc::Rc};
5
6use yew::prelude::{hook, use_effect_with, use_state};
7
8use crate::{
9 api::theme::get_theme_params,
10 core::types::theme_params::TelegramThemeParams,
11 webapp::{EventHandle, TelegramWebApp}
12};
13
14type HandleSlot = Rc<RefCell<Option<EventHandle<dyn FnMut()>>>>;
15
16#[derive(Clone, Debug, PartialEq, Default)]
18pub struct ThemeState {
19 pub color_scheme: Option<String>,
21 pub params: TelegramThemeParams
23}
24
25impl ThemeState {
26 fn snapshot(app: Option<&TelegramWebApp>) -> Self {
27 let color_scheme = app.and_then(|a| a.color_scheme());
28 let params = get_theme_params().unwrap_or_default();
29 Self {
30 color_scheme,
31 params
32 }
33 }
34}
35
36#[hook]
52pub fn use_theme() -> ThemeState {
53 let state = use_state(|| ThemeState::snapshot(TelegramWebApp::instance().as_ref()));
54
55 {
56 let state = state.clone();
57 use_effect_with((), move |_| {
58 let stash: HandleSlot = Rc::new(RefCell::new(None));
59 if let Some(app) = TelegramWebApp::instance() {
60 let app_for_handler = app.clone();
61 let state_for_handler = state.clone();
62 if let Ok(handle) = app.on_theme_changed(move || {
63 state_for_handler.set(ThemeState::snapshot(Some(&app_for_handler)));
64 }) {
65 *stash.borrow_mut() = Some(handle);
66 }
67 }
68 move || {
69 stash.borrow_mut().take();
70 }
71 });
72 }
73
74 (*state).clone()
75}