Skip to main content

lingxia_platform/traits/
media_interaction.rs

1use std::future::Future;
2
3use crate::error::PlatformError;
4
5#[derive(Debug, Clone)]
6pub struct PreviewMediaItem {
7    pub path: String,
8    pub media_type: MediaKind,
9    pub rotate: Option<u16>,
10    pub object_fit: Option<MediaObjectFit>,
11    pub duration_ms: Option<u64>,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
15pub enum PreviewMediaAdvance {
16    #[default]
17    Manual,
18    Next,
19    Loop,
20}
21
22impl PreviewMediaAdvance {
23    pub fn as_str(self) -> &'static str {
24        match self {
25            Self::Manual => "manual",
26            Self::Next => "next",
27            Self::Loop => "loop",
28        }
29    }
30}
31
32#[derive(Debug, Clone)]
33pub struct PreviewMediaRequest {
34    pub items: Vec<PreviewMediaItem>,
35    pub start_index: i32,
36    pub advance: PreviewMediaAdvance,
37    pub show_index_indicator: bool,
38    /// Callback_id for the final preview result. Fires once when the session
39    /// ends (manual/auto/interrupted/error). Payload: serialized
40    /// `PreviewMediaResultObj` ({reason, lastIndex}).
41    pub callback_id: u64,
42    /// Callback_id for the "first frame composited" signal. Fires once when
43    /// the first pixel of the underlying media has been painted to screen.
44    /// Native MAY skip on degenerate paths (abort before any item rendered,
45    /// process tear-down, etc.) — the JS-side `presented` Promise is also
46    /// woken by a fallback when `completed` settles, and by a total timeout
47    /// after that, so it never hangs. The callback payload, when fired, is
48    /// an empty JSON object `{}`.
49    pub presented_callback_id: u64,
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
53pub enum MediaKind {
54    Image,
55    Video,
56    Unknown,
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub enum MediaObjectFit {
61    Cover,
62    Contain,
63    Fill,
64    Fit,
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub enum ChooseMediaMode {
69    Images,
70    Videos,
71    Mix,
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq)]
75pub enum MediaSource {
76    Album,
77    Camera,
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81pub enum CameraFacing {
82    Front,
83    Back,
84}
85
86#[derive(Debug, Clone, Copy, PartialEq, Eq)]
87pub enum MediaQuality {
88    Original,
89    Compressed,
90}
91
92#[derive(Debug, Clone)]
93pub struct ChooseMediaRequest {
94    pub max_count: u32,
95    pub mode: ChooseMediaMode,
96    pub source_types: Vec<MediaSource>,
97    pub max_duration_seconds: Option<u32>,
98    pub camera_facing: Option<CameraFacing>,
99}
100
101impl Default for ChooseMediaRequest {
102    fn default() -> Self {
103        Self {
104            max_count: 9,
105            mode: ChooseMediaMode::Images,
106            source_types: vec![MediaSource::Album, MediaSource::Camera],
107            max_duration_seconds: None,
108            camera_facing: None,
109        }
110    }
111}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq)]
114pub enum ScanType {
115    BarCode,
116    QrCode,
117    DataMatrix,
118    Pdf417,
119}
120
121#[derive(Debug, Clone)]
122pub struct ScanCodeRequest {
123    pub scan_types: Vec<ScanType>,
124    pub only_from_camera: bool,
125}
126
127impl Default for ScanCodeRequest {
128    fn default() -> Self {
129        Self {
130            scan_types: Vec::new(),
131            only_from_camera: true,
132        }
133    }
134}
135
136#[derive(Debug, Clone)]
137pub struct SaveMediaRequest {
138    pub file_uri: String,
139}
140
141pub trait MediaInteraction: Send + Sync + 'static {
142    /// Preview media. Keeps callback_id pattern for AbortSignal support.
143    fn preview_media(&self, request: PreviewMediaRequest) -> Result<(), PlatformError>;
144    fn cancel_preview(&self, callback_id: u64) -> Result<(), PlatformError>;
145
146    fn choose_media(
147        &self,
148        request: ChooseMediaRequest,
149    ) -> impl Future<Output = Result<String, PlatformError>> + Send;
150
151    fn scan_code(
152        &self,
153        request: ScanCodeRequest,
154    ) -> impl Future<Output = Result<String, PlatformError>> + Send;
155
156    fn save_image_to_photos_album(
157        &self,
158        request: SaveMediaRequest,
159    ) -> impl Future<Output = Result<(), PlatformError>> + Send;
160
161    fn save_video_to_photos_album(
162        &self,
163        request: SaveMediaRequest,
164    ) -> impl Future<Output = Result<(), PlatformError>> + Send;
165}