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