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