Skip to main content

fission_shell_desktop/
lib.rs

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