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}