Skip to main content

fission_shell_mobile/
lib.rs

1use anyhow::Result;
2use fission_core::{Action, ActionRegistry, 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 absorb_registry(&mut self, registry: ActionRegistry<S>) {
250        self.inner.absorb_registry(registry);
251    }
252
253    pub fn run(self) -> Result<()> {
254        self.inner.run()
255    }
256
257    #[cfg(target_os = "android")]
258    pub fn run_with_android_app(self, app: AndroidApp) -> Result<()> {
259        self.inner.run_with_android_app(app)
260    }
261}