telegram_webapp_sdk/webapp/
events.rs1use js_sys::{Function, Reflect};
5use wasm_bindgen::{JsCast, JsValue, prelude::Closure};
6
7use crate::webapp::{
8 TelegramWebApp,
9 types::{BackgroundEvent, EventHandle}
10};
11
12impl TelegramWebApp {
13 pub fn on_event<F>(
21 &self,
22 event: &str,
23 callback: F
24 ) -> Result<EventHandle<dyn FnMut(JsValue)>, JsValue>
25 where
26 F: 'static + Fn(JsValue)
27 {
28 let cb = Closure::<dyn FnMut(JsValue)>::new(callback);
29 let f = Reflect::get(&self.inner, &"onEvent".into())?;
30 let func = f
31 .dyn_ref::<Function>()
32 .ok_or_else(|| JsValue::from_str("onEvent is not a function"))?;
33 func.call2(&self.inner, &event.into(), cb.as_ref().unchecked_ref())?;
34 Ok(EventHandle::new(
35 self.inner.clone(),
36 "offEvent",
37 Some(event.to_owned()),
38 cb
39 ))
40 }
41
42 pub fn on_background_event<F>(
50 &self,
51 event: BackgroundEvent,
52 callback: F
53 ) -> Result<EventHandle<dyn FnMut(JsValue)>, JsValue>
54 where
55 F: 'static + Fn(JsValue)
56 {
57 let cb = Closure::<dyn FnMut(JsValue)>::new(callback);
58 let f = Reflect::get(&self.inner, &"onEvent".into())?;
59 let func = f
60 .dyn_ref::<Function>()
61 .ok_or_else(|| JsValue::from_str("onEvent is not a function"))?;
62 func.call2(
63 &self.inner,
64 &event.as_str().into(),
65 cb.as_ref().unchecked_ref()
66 )?;
67 Ok(EventHandle::new(
68 self.inner.clone(),
69 "offEvent",
70 Some(event.as_str().to_string()),
71 cb
72 ))
73 }
74
75 pub fn off_event<T: ?Sized>(&self, handle: EventHandle<T>) -> Result<(), JsValue> {
80 handle.unregister()
81 }
82
83 pub fn on_theme_changed<F>(&self, callback: F) -> Result<EventHandle<dyn FnMut()>, JsValue>
91 where
92 F: 'static + Fn()
93 {
94 let cb = Closure::<dyn FnMut()>::new(callback);
95 let f = Reflect::get(&self.inner, &"onEvent".into())?;
96 let func = f
97 .dyn_ref::<Function>()
98 .ok_or_else(|| JsValue::from_str("onEvent is not a function"))?;
99 func.call2(
100 &self.inner,
101 &"themeChanged".into(),
102 cb.as_ref().unchecked_ref()
103 )?;
104 Ok(EventHandle::new(
105 self.inner.clone(),
106 "offEvent",
107 Some("themeChanged".to_string()),
108 cb
109 ))
110 }
111
112 pub fn on_safe_area_changed<F>(&self, callback: F) -> Result<EventHandle<dyn FnMut()>, JsValue>
120 where
121 F: 'static + Fn()
122 {
123 let cb = Closure::<dyn FnMut()>::new(callback);
124 let f = Reflect::get(&self.inner, &"onEvent".into())?;
125 let func = f
126 .dyn_ref::<Function>()
127 .ok_or_else(|| JsValue::from_str("onEvent is not a function"))?;
128 func.call2(
129 &self.inner,
130 &"safeAreaChanged".into(),
131 cb.as_ref().unchecked_ref()
132 )?;
133 Ok(EventHandle::new(
134 self.inner.clone(),
135 "offEvent",
136 Some("safeAreaChanged".to_string()),
137 cb
138 ))
139 }
140
141 pub fn on_content_safe_area_changed<F>(
149 &self,
150 callback: F
151 ) -> Result<EventHandle<dyn FnMut()>, JsValue>
152 where
153 F: 'static + Fn()
154 {
155 let cb = Closure::<dyn FnMut()>::new(callback);
156 let f = Reflect::get(&self.inner, &"onEvent".into())?;
157 let func = f
158 .dyn_ref::<Function>()
159 .ok_or_else(|| JsValue::from_str("onEvent is not a function"))?;
160 func.call2(
161 &self.inner,
162 &"contentSafeAreaChanged".into(),
163 cb.as_ref().unchecked_ref()
164 )?;
165 Ok(EventHandle::new(
166 self.inner.clone(),
167 "offEvent",
168 Some("contentSafeAreaChanged".to_string()),
169 cb
170 ))
171 }
172
173 pub fn on_viewport_changed<F>(&self, callback: F) -> Result<EventHandle<dyn FnMut()>, JsValue>
181 where
182 F: 'static + Fn()
183 {
184 let cb = Closure::<dyn FnMut()>::new(callback);
185 let f = Reflect::get(&self.inner, &"onEvent".into())?;
186 let func = f
187 .dyn_ref::<Function>()
188 .ok_or_else(|| JsValue::from_str("onEvent is not a function"))?;
189 func.call2(
190 &self.inner,
191 &"viewportChanged".into(),
192 cb.as_ref().unchecked_ref()
193 )?;
194 Ok(EventHandle::new(
195 self.inner.clone(),
196 "offEvent",
197 Some("viewportChanged".to_string()),
198 cb
199 ))
200 }
201
202 pub fn on_clipboard_text_received<F>(
210 &self,
211 callback: F
212 ) -> Result<EventHandle<dyn FnMut(JsValue)>, JsValue>
213 where
214 F: 'static + Fn(String)
215 {
216 let cb = Closure::<dyn FnMut(JsValue)>::new(move |text: JsValue| {
217 callback(text.as_string().unwrap_or_default());
218 });
219 let f = Reflect::get(&self.inner, &"onEvent".into())?;
220 let func = f
221 .dyn_ref::<Function>()
222 .ok_or_else(|| JsValue::from_str("onEvent is not a function"))?;
223 func.call2(
224 &self.inner,
225 &"clipboardTextReceived".into(),
226 cb.as_ref().unchecked_ref()
227 )?;
228 Ok(EventHandle::new(
229 self.inner.clone(),
230 "offEvent",
231 Some("clipboardTextReceived".to_string()),
232 cb
233 ))
234 }
235
236 pub fn on_invoice_closed<F>(
256 &self,
257 callback: F
258 ) -> Result<EventHandle<dyn FnMut(String)>, JsValue>
259 where
260 F: 'static + Fn(String)
261 {
262 let cb = Closure::<dyn FnMut(String)>::new(callback);
263 let f = Reflect::get(&self.inner, &"onEvent".into())?;
264 let func = f
265 .dyn_ref::<Function>()
266 .ok_or_else(|| JsValue::from_str("onEvent is not a function"))?;
267 func.call2(
268 &self.inner,
269 &"invoiceClosed".into(),
270 cb.as_ref().unchecked_ref()
271 )?;
272 Ok(EventHandle::new(
273 self.inner.clone(),
274 "offEvent",
275 Some("invoiceClosed".to_string()),
276 cb
277 ))
278 }
279}