Skip to main content

fission_shell_desktop/
lib.rs

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