1use anyhow::Result;
2use fission_core::{Action, ActionRegistry, Env, GlobalState, Widget};
3use fission_shell::async_host::AsyncRegistry;
4use fission_shell_winit::WinitApp;
5
6pub use fission_shell_winit::{
7 BarcodeScannerHost, BiometricHost, BluetoothHost, CameraHost, ClipboardHost, GeolocationHost,
8 HapticHost, MemoryBarcodeScannerHost, MemoryBiometricHost, MemoryBluetoothHost,
9 MemoryCameraHost, MemoryClipboardHost, MemoryGeolocationHost, MemoryHapticHost,
10 MemoryMicrophoneHost, MemoryNfcHost, MemoryNotificationHost, MemoryPasskeyHost,
11 MemoryVolumeHost, MemoryWifiHost, MicrophoneHost, NfcHost, NotificationHost, PasskeyHost,
12 UnsupportedBarcodeScannerHost, UnsupportedBiometricHost, UnsupportedBluetoothHost,
13 UnsupportedCameraHost, UnsupportedGeolocationHost, UnsupportedHapticHost,
14 UnsupportedMicrophoneHost, UnsupportedNfcHost, UnsupportedNotificationHost,
15 UnsupportedPasskeyHost, UnsupportedVolumeHost, UnsupportedWifiHost, VolumeHost, WifiHost,
16};
17
18#[cfg(target_os = "android")]
19pub use winit::platform::android::activity::AndroidApp;
20
21pub struct MobileApp<S: GlobalState, W>
22where
23 W: Clone + Into<Widget>,
24{
25 inner: WinitApp<S, W>,
26}
27
28impl<S, W> MobileApp<S, W>
29where
30 S: GlobalState + Default,
31 W: Clone + Into<Widget> + 'static,
32{
33 pub fn new(root_widget: W) -> Self {
34 Self {
35 inner: WinitApp::new(root_widget),
36 }
37 }
38
39 pub fn new_with_global_state(root_widget: W, global_state: S) -> Self {
40 Self {
41 inner: WinitApp::new_with_global_state(root_widget, global_state),
42 }
43 }
44
45 pub fn with_global_state(mut self, global_state: S) -> Self {
46 self.inner = self.inner.with_global_state(global_state);
47 self
48 }
49
50 pub fn with_key_handler<F>(mut self, handler: F) -> Self
51 where
52 F: Fn(&mut S, &fission_core::KeyCode, u8) -> bool + Send + Sync + 'static,
53 {
54 self.inner = self.inner.with_key_handler(handler);
55 self
56 }
57
58 pub fn with_title(mut self, title: impl Into<String>) -> Self {
59 self.inner = self.inner.with_title(title);
60 self
61 }
62
63 pub fn with_test_control_port(mut self, port: u16) -> Self {
64 self.inner = self.inner.with_test_control_port(port);
65 self
66 }
67
68 pub fn with_state_init<F>(mut self, init: F) -> Self
69 where
70 F: FnOnce(&mut S),
71 {
72 self.inner = self.inner.with_state_init(init);
73 self
74 }
75
76 pub fn with_startup_action<A: Action>(mut self, action: A) -> Self {
77 self.inner = self.inner.with_startup_action(action);
78 self
79 }
80
81 pub fn with_design_system<D: fission_theme::DesignSystem>(
82 mut self,
83 mode: fission_theme::DesignMode,
84 ) -> Self {
85 self.inner = self.inner.with_design_system::<D>(mode);
86 self
87 }
88
89 pub fn with_sync_env<F>(mut self, sync: F) -> Self
90 where
91 F: Fn(&S, &mut Env) + Send + Sync + 'static,
92 {
93 self.inner = self.inner.with_sync_env(sync);
94 self
95 }
96
97 pub fn with_frame_hook<F>(mut self, hook: F) -> Self
98 where
99 F: Fn(&mut S) -> bool + Send + Sync + 'static,
100 {
101 self.inner = self.inner.with_frame_hook(hook);
102 self
103 }
104
105 pub fn with_async<F>(mut self, configure: F) -> Self
106 where
107 F: FnOnce(&mut AsyncRegistry),
108 {
109 self.inner = self.inner.with_async(configure);
110 self
111 }
112
113 pub fn with_notification_host<H>(mut self, host: H) -> Self
114 where
115 H: NotificationHost,
116 {
117 self.inner = self.inner.with_notification_host(host);
118 self
119 }
120
121 pub fn with_nfc_host<H>(mut self, host: H) -> Self
122 where
123 H: NfcHost,
124 {
125 self.inner = self.inner.with_nfc_host(host);
126 self
127 }
128
129 pub fn with_biometric_host<H>(mut self, host: H) -> Self
130 where
131 H: BiometricHost,
132 {
133 self.inner = self.inner.with_biometric_host(host);
134 self
135 }
136
137 pub fn with_passkey_host<H>(mut self, host: H) -> Self
138 where
139 H: PasskeyHost,
140 {
141 self.inner = self.inner.with_passkey_host(host);
142 self
143 }
144
145 pub fn with_bluetooth_host<H>(mut self, host: H) -> Self
146 where
147 H: BluetoothHost,
148 {
149 self.inner = self.inner.with_bluetooth_host(host);
150 self
151 }
152
153 pub fn with_barcode_scanner_host<H>(mut self, host: H) -> Self
154 where
155 H: BarcodeScannerHost,
156 {
157 self.inner = self.inner.with_barcode_scanner_host(host);
158 self
159 }
160
161 pub fn with_camera_host<H>(mut self, host: H) -> Self
162 where
163 H: CameraHost,
164 {
165 self.inner = self.inner.with_camera_host(host);
166 self
167 }
168
169 pub fn with_clipboard_host<H>(mut self, host: H) -> Self
170 where
171 H: ClipboardHost,
172 {
173 self.inner = self.inner.with_clipboard_host(host);
174 self
175 }
176
177 pub fn with_geolocation_host<H>(mut self, host: H) -> Self
178 where
179 H: GeolocationHost,
180 {
181 self.inner = self.inner.with_geolocation_host(host);
182 self
183 }
184
185 pub fn with_haptic_host<H>(mut self, host: H) -> Self
186 where
187 H: HapticHost,
188 {
189 self.inner = self.inner.with_haptic_host(host);
190 self
191 }
192
193 pub fn with_microphone_host<H>(mut self, host: H) -> Self
194 where
195 H: MicrophoneHost,
196 {
197 self.inner = self.inner.with_microphone_host(host);
198 self
199 }
200
201 pub fn with_wifi_host<H>(mut self, host: H) -> Self
202 where
203 H: WifiHost,
204 {
205 self.inner = self.inner.with_wifi_host(host);
206 self
207 }
208
209 pub fn with_volume_host<H>(mut self, host: H) -> Self
210 where
211 H: VolumeHost,
212 {
213 self.inner = self.inner.with_volume_host(host);
214 self
215 }
216
217 pub fn with_deep_link_config(mut self, config: fission_core::DeepLinkConfig) -> Self {
218 self.inner = self.inner.with_deep_link_config(config);
219 self
220 }
221
222 pub fn with_deep_link_scheme(mut self, scheme: impl Into<String>) -> Self {
223 self.inner = self.inner.with_deep_link_scheme(scheme);
224 self
225 }
226
227 pub fn with_deep_link_domain(mut self, domain: impl Into<String>) -> Self {
228 self.inner = self.inner.with_deep_link_domain(domain);
229 self
230 }
231
232 pub fn with_startup_deep_link(mut self, link: fission_core::DeepLink) -> Self {
233 self.inner = self.inner.with_startup_deep_link(link);
234 self
235 }
236
237 pub fn with_startup_notification_response(
238 mut self,
239 response: fission_core::NotificationResponse,
240 ) -> Self {
241 self.inner = self.inner.with_startup_notification_response(response);
242 self
243 }
244
245 pub fn on_deep_link<H>(mut self, handler: H) -> Self
246 where
247 H: fission_core::registry::IntoHandler<S, fission_core::DeepLinkReceived>
248 + Send
249 + Sync
250 + 'static,
251 {
252 self.inner = self.inner.on_deep_link(handler);
253 self
254 }
255
256 pub fn on_notification_response<H>(mut self, handler: H) -> Self
257 where
258 H: fission_core::registry::IntoHandler<S, fission_core::NotificationResponseReceived>
259 + Send
260 + Sync
261 + 'static,
262 {
263 self.inner = self.inner.on_notification_response(handler);
264 self
265 }
266
267 pub fn absorb_registry(&mut self, registry: ActionRegistry<S>) {
268 self.inner.absorb_registry(registry);
269 }
270
271 pub fn run(self) -> Result<()> {
272 self.inner.run()
273 }
274
275 #[cfg(target_os = "android")]
276 pub fn run_with_android_app(self, app: AndroidApp) -> Result<()> {
277 self.inner.run_with_android_app(app)
278 }
279}