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