1use std::future::Future;
2
3use lingxia_surface::LayoutPresentationPlan;
4
5use crate::error::PlatformError;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum ToastIcon {
9 Success,
10 Error,
11 Loading,
12 None,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum ToastPosition {
17 Top,
18 Center,
19 Bottom,
20}
21
22#[derive(Debug, Clone)]
23pub struct ToastOptions {
24 pub title: String,
25 pub icon: ToastIcon,
26 pub image: Option<String>,
27 pub duration: f64,
28 pub mask: bool,
29 pub position: ToastPosition,
30}
31
32#[derive(Debug, Clone)]
33pub struct ModalOptions {
34 pub title: String,
35 pub content: String,
36 pub show_cancel: bool,
37 pub cancel_text: String,
38 pub cancel_color: Option<String>,
39 pub confirm_text: String,
40 pub confirm_color: Option<String>,
41}
42
43#[repr(i32)]
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45pub enum SurfaceKind {
46 Window = 0,
47 Overlay = 1,
48}
49
50#[repr(i32)]
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
56pub enum SurfaceRole {
57 #[default]
58 Main = 0,
59 Aside = 1,
60 Float = 2,
61}
62
63impl SurfaceRole {
64 pub const fn as_str(self) -> &'static str {
65 match self {
66 Self::Main => "main",
67 Self::Aside => "aside",
68 Self::Float => "float",
69 }
70 }
71}
72
73impl From<lingxia_surface::Role> for SurfaceRole {
74 fn from(role: lingxia_surface::Role) -> Self {
75 match role {
76 lingxia_surface::Role::Main => Self::Main,
77 lingxia_surface::Role::Aside => Self::Aside,
78 lingxia_surface::Role::Float => Self::Float,
79 }
80 }
81}
82
83impl From<SurfaceRole> for lingxia_surface::Role {
84 fn from(role: SurfaceRole) -> Self {
85 match role {
86 SurfaceRole::Main => Self::Main,
87 SurfaceRole::Aside => Self::Aside,
88 SurfaceRole::Float => Self::Float,
89 }
90 }
91}
92
93#[repr(i32)]
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
95pub enum SurfaceContent {
96 #[default]
97 Page = 0,
98 Url = 1,
99}
100
101#[repr(i32)]
102#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
103pub enum SurfacePosition {
104 #[default]
105 Center = 0,
106 Bottom = 1,
107 Left = 2,
108 Right = 3,
109 Top = 4,
110}
111
112#[repr(i32)]
120#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
121pub enum WindowChrome {
122 #[default]
123 System = 0,
124 Full = 1,
125}
126
127impl WindowChrome {
128 pub const FULL_DRAG_STRIP_HEIGHT: f64 = 28.0;
134}
135
136#[derive(Debug, Clone)]
137pub struct SurfaceRequest {
138 pub id: String,
139 pub app_id: String,
140 pub path: String,
141 pub session_id: u64,
142 pub page_instance_id: String,
143 pub content: SurfaceContent,
144 pub kind: SurfaceKind,
145 pub width: f64,
146 pub height: f64,
147 pub width_ratio: f64,
148 pub height_ratio: f64,
149 pub position: SurfacePosition,
150 pub role: SurfaceRole,
152 pub interaction: lingxia_surface::SurfaceInteraction,
154 pub chrome: WindowChrome,
156 pub ephemeral_web_data: bool,
160 pub url_callback: bool,
164}
165
166pub type ManagedSurfaceCompletion = Box<dyn FnOnce(Result<(), PlatformError>) + Send + 'static>;
169
170pub type ManagedSurfaceFuture = crate::traits::PlatformFuture;
171
172#[derive(Debug, Clone, PartialEq, Eq)]
173pub enum ManagedSurfaceProvider {
174 Declared,
175 Native {
176 capability: String,
177 instance_key: Option<String>,
178 },
179}
180
181#[derive(Debug, Clone, PartialEq, Eq)]
182pub struct ManagedSurfaceProviderRequest {
183 pub surface_id: String,
184 pub provider: ManagedSurfaceProvider,
185 pub role: Option<SurfaceRole>,
186 pub edge: Option<String>,
187}
188
189#[derive(Debug, Clone, PartialEq, Eq)]
190pub struct ManagedSurfaceProviderDestroyRequest {
191 pub surface_id: String,
192 pub provider: ManagedSurfaceProvider,
193 pub role: Option<SurfaceRole>,
194}
195
196pub trait SurfacePresenter: Send + Sync + 'static {
197 fn present_layout(
201 &self,
202 _window_id: &str,
203 _plan: &LayoutPresentationPlan,
204 ) -> Result<(), PlatformError> {
205 Err(PlatformError::NotSupported(
206 "present_layout is not supported on this platform".to_string(),
207 ))
208 }
209
210 fn present_surface(&self, _request: SurfaceRequest) -> Result<(), PlatformError> {
211 Err(PlatformError::NotSupported(
212 "surface is not supported on this platform".to_string(),
213 ))
214 }
215
216 fn close_surface(&self, _app_id: &str, _id: &str, _reason: &str) -> Result<(), PlatformError> {
217 Err(PlatformError::NotSupported(
218 "surface close is not supported on this platform".to_string(),
219 ))
220 }
221
222 fn show_surface(&self, _app_id: &str, _id: &str) -> Result<(), PlatformError> {
223 Err(PlatformError::NotSupported(
224 "surface show is not supported on this platform".to_string(),
225 ))
226 }
227
228 fn hide_surface(&self, _app_id: &str, _id: &str) -> Result<(), PlatformError> {
229 Err(PlatformError::NotSupported(
230 "surface hide is not supported on this platform".to_string(),
231 ))
232 }
233
234 fn ensure_managed_surface_provider(
238 &self,
239 _request: ManagedSurfaceProviderRequest,
240 ) -> ManagedSurfaceFuture {
241 Box::pin(async {
242 Err(PlatformError::NotSupported(
243 "managed surface providers are not supported on this platform".to_string(),
244 ))
245 })
246 }
247
248 fn destroy_managed_surface_provider(
250 &self,
251 _request: ManagedSurfaceProviderDestroyRequest,
252 ) -> ManagedSurfaceFuture {
253 Box::pin(async {
254 Err(PlatformError::NotSupported(
255 "managed surface providers are not supported on this platform".to_string(),
256 ))
257 })
258 }
259}
260
261pub trait UIUpdate: Send + Sync + 'static {
262 fn update_navbar_ui(&self, appid: String) -> Result<(), PlatformError>;
263 fn update_tabbar_ui(&self, appid: String) -> Result<(), PlatformError>;
264
265 fn update_tabbar_ui_async(
266 &self,
267 appid: String,
268 ) -> impl Future<Output = Result<(), PlatformError>> + Send {
269 async move { self.update_tabbar_ui(appid) }
270 }
271
272 fn update_orientation_ui(&self, _appid: String) -> Result<(), PlatformError> {
273 Err(PlatformError::NotSupported(
274 "update_orientation_ui not implemented for this platform".to_string(),
275 ))
276 }
277
278 fn host_appearance_dark(&self) -> bool {
280 false
281 }
282
283 fn apply_lxapp_appearance(&self, _appid: &str, _dark: bool) -> Result<(), PlatformError> {
286 Ok(())
287 }
288
289 fn clear_lxapp_appearance(&self, _appid: &str) {}
291
292 fn notify_home_first_ready(&self) {}
295
296 fn measure_page_chrome_capsule(
300 &self,
301 _appid: String,
302 ) -> impl Future<Output = Result<Option<String>, PlatformError>> + Send {
303 async { Ok(None) }
304 }
305
306 fn apply_page_chrome_revision(
310 &self,
311 appid: String,
312 _revision: u64,
313 ) -> impl Future<Output = Result<(), PlatformError>> + Send {
314 async move {
315 self.update_navbar_ui(appid.clone())?;
316 self.update_tabbar_ui_async(appid).await
317 }
318 }
319}
320
321pub trait UserFeedback: Send + Sync + 'static {
322 fn show_toast(&self, options: ToastOptions) -> Result<(), PlatformError>;
323 fn hide_toast(&self) -> Result<(), PlatformError>;
324
325 fn show_modal(
326 &self,
327 options: ModalOptions,
328 ) -> impl Future<Output = Result<String, PlatformError>> + Send;
329
330 fn show_action_sheet(
331 &self,
332 options: Vec<String>,
333 cancel_text: String,
334 item_color: String,
335 ) -> impl Future<Output = Result<String, PlatformError>> + Send;
336}