Workstream E (backend): wire tauri-specta — annotate commands, derive Type, generate-ready Builder
- Add #[specta::specta] to all 201 #[tauri::command] functions. - Derive specta::Type on all IPC DTOs (repository/types, settings, player/storage/ download command DTOs, player enums, jellyfin SessionInfo/NowPlayingItem/PlayState, ThumbnailCacheStats, DownloadInfo, CacheConfig, etc.). - Replace tauri::generate_handler! with a tauri_specta::Builder + collect_commands! in lib.rs (exports bindings.ts in debug builds). Two contract changes required by specta constraints (frontend migration follows): - specta caps command arity at 10 args: download_item_and_start / download_item / download_video now take a single request struct (params bundled, body unchanged via destructuring). - specta can't parse split serde rename_all: SessionInfo/NowPlayingItem/PlayState switched to rename_all = "PascalCase" (Jellyfin deserialization preserved; these now serialize PascalCase to the frontend). cargo check --lib is clean (0 errors). Frontend migration to bindings.ts is the next step.
This commit is contained in:
@@ -56,7 +56,7 @@ pub struct MediaSessionManagerWrapper(pub Mutex<MediaSessionManager>);
|
||||
pub struct VideoSettingsWrapper(pub Mutex<VideoSettings>);
|
||||
|
||||
/// Response for player state queries
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(specta::Type, Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PlayerStatus {
|
||||
pub state: PlayerState,
|
||||
@@ -82,7 +82,7 @@ pub struct PlayerStatus {
|
||||
|
||||
/// Lightweight media item for merged playback state
|
||||
/// Converts from both local MediaItem and remote NowPlayingItem
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
#[derive(specta::Type, Debug, Serialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MergedMediaItem {
|
||||
pub id: String,
|
||||
@@ -134,7 +134,7 @@ impl From<&crate::jellyfin::client::NowPlayingItem> for MergedMediaItem {
|
||||
}
|
||||
|
||||
/// Response for queue queries
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(specta::Type, Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct QueueStatus {
|
||||
pub items: Vec<MediaItem>,
|
||||
@@ -146,7 +146,7 @@ pub struct QueueStatus {
|
||||
}
|
||||
|
||||
/// Backend type for video playback
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(specta::Type, Debug, Serialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum VideoBackend {
|
||||
/// Native backend (ExoPlayer on Android, libmpv on Linux)
|
||||
@@ -159,7 +159,7 @@ pub enum VideoBackend {
|
||||
///
|
||||
/// Simplified to video playback only. Audio playback uses player_play_tracks
|
||||
/// to avoid Tauri Android serialization issues with complex objects.
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(specta::Type, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PlayItemRequest {
|
||||
pub id: String,
|
||||
@@ -172,7 +172,7 @@ pub struct PlayItemRequest {
|
||||
}
|
||||
|
||||
/// Queue context for remote transfer - what type of queue is this?
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(specta::Type, Debug, Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "lowercase")]
|
||||
pub enum PlayQueueContext {
|
||||
/// Playing from a specific album
|
||||
@@ -194,7 +194,7 @@ pub enum PlayQueueContext {
|
||||
}
|
||||
|
||||
/// Request to play a queue of items
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(specta::Type, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PlayQueueRequest {
|
||||
pub items: Vec<PlayItemRequest>,
|
||||
@@ -207,7 +207,7 @@ pub struct PlayQueueRequest {
|
||||
}
|
||||
|
||||
/// Request to play a track from an album (backend fetches all tracks)
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(specta::Type, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PlayAlbumTrackRequest {
|
||||
pub album_id: String,
|
||||
@@ -217,7 +217,7 @@ pub struct PlayAlbumTrackRequest {
|
||||
}
|
||||
|
||||
/// Request to play tracks by ID (backend fetches metadata)
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(specta::Type, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PlayTracksRequest {
|
||||
pub track_ids: Vec<String>,
|
||||
@@ -227,7 +227,7 @@ pub struct PlayTracksRequest {
|
||||
}
|
||||
|
||||
/// Context information for track playback
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(specta::Type, Debug, Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "lowercase")]
|
||||
pub enum PlayTracksContext {
|
||||
Playlist {
|
||||
@@ -249,7 +249,7 @@ pub enum PlayTracksContext {
|
||||
}
|
||||
|
||||
/// Response for video seek operations
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(specta::Type, Debug, Serialize)]
|
||||
#[serde(tag = "strategy", rename_all = "camelCase")]
|
||||
pub enum VideoSeekResponse {
|
||||
/// Use native seeking (HLS or direct stream)
|
||||
@@ -267,7 +267,7 @@ pub enum VideoSeekResponse {
|
||||
}
|
||||
|
||||
/// Response for audio track switching operations
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(specta::Type, Debug, Serialize)]
|
||||
#[serde(tag = "strategy", rename_all = "camelCase")]
|
||||
pub enum AudioTrackSwitchResponse {
|
||||
/// Native backend handled it (Android ExoPlayer)
|
||||
@@ -384,6 +384,7 @@ pub(super) async fn check_for_local_download(
|
||||
/// @req: UR-005 - Control media playback (play operation)
|
||||
/// @req: DR-009 - Audio player UI
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_play_item(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session: State<'_, MediaSessionManagerWrapper>,
|
||||
@@ -435,6 +436,7 @@ pub async fn player_play_item(
|
||||
/// @req: UR-015 - View and manage current audio queue
|
||||
/// @req: DR-005 - Queue manager with shuffle, repeat, history
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_play_queue(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session: State<'_, MediaSessionManagerWrapper>,
|
||||
@@ -511,6 +513,7 @@ pub async fn player_play_queue(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_play(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
playback_mode: State<'_, super::playback_mode::PlaybackModeManagerWrapper>,
|
||||
@@ -538,6 +541,7 @@ pub async fn player_play(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_pause(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
playback_mode: State<'_, super::playback_mode::PlaybackModeManagerWrapper>,
|
||||
@@ -565,6 +569,7 @@ pub async fn player_pause(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_toggle(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
playback_mode: State<'_, super::playback_mode::PlaybackModeManagerWrapper>,
|
||||
@@ -592,6 +597,7 @@ pub async fn player_toggle(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_stop(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session: State<'_, MediaSessionManagerWrapper>,
|
||||
@@ -651,6 +657,7 @@ pub async fn player_stop(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_next(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session: State<'_, MediaSessionManagerWrapper>,
|
||||
@@ -703,6 +710,7 @@ pub async fn player_next(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_previous(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session: State<'_, MediaSessionManagerWrapper>,
|
||||
@@ -753,6 +761,7 @@ pub async fn player_previous(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_seek(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
playback_mode: State<'_, super::playback_mode::PlaybackModeManagerWrapper>,
|
||||
@@ -792,6 +801,7 @@ pub async fn player_seek(
|
||||
/// For native (non-HTML5) backends, this command handles the entire stream reload
|
||||
/// internally. For HTML5 backends, it returns the new URL for the frontend to handle.
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_seek_video(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
repository_manager: State<'_, super::repository::RepositoryManagerWrapper>,
|
||||
@@ -929,6 +939,7 @@ pub async fn player_seek_video(
|
||||
/// Switch audio track - handles both HTML5 (stream reload) and native (direct switch)
|
||||
/// Note: Frontend should handle saving series preferences after this command succeeds
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_switch_audio_track(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
repository_manager: State<'_, super::repository::RepositoryManagerWrapper>,
|
||||
@@ -984,6 +995,7 @@ pub async fn player_switch_audio_track(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_set_audio_track(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
stream_index: i32,
|
||||
@@ -994,6 +1006,7 @@ pub async fn player_set_audio_track(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_set_subtitle_track(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
stream_index: Option<i32>,
|
||||
@@ -1004,6 +1017,7 @@ pub async fn player_set_subtitle_track(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_set_volume(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
playback_mode: State<'_, super::playback_mode::PlaybackModeManagerWrapper>,
|
||||
@@ -1034,6 +1048,7 @@ pub async fn player_set_volume(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_toggle_mute(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
playback_mode: State<'_, super::playback_mode::PlaybackModeManagerWrapper>,
|
||||
@@ -1062,6 +1077,7 @@ pub async fn player_toggle_mute(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_toggle_shuffle(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
) -> Result<QueueStatus, String> {
|
||||
@@ -1072,6 +1088,7 @@ pub async fn player_toggle_shuffle(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_cycle_repeat(player: State<'_, PlayerStateWrapper>) -> Result<QueueStatus, String> {
|
||||
let controller = player.0.lock().await;
|
||||
controller.cycle_repeat();
|
||||
@@ -1080,6 +1097,7 @@ pub async fn player_cycle_repeat(player: State<'_, PlayerStateWrapper>) -> Resul
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_get_status(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
playback_mode: State<'_, super::playback_mode::PlaybackModeManagerWrapper>,
|
||||
@@ -1165,6 +1183,7 @@ pub async fn player_get_status(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_get_queue(player: State<'_, PlayerStateWrapper>) -> Result<QueueStatus, String> {
|
||||
let controller = player.0.lock().await;
|
||||
Ok(get_queue_status(&controller))
|
||||
@@ -1216,6 +1235,7 @@ pub(super) fn get_queue_status(controller: &PlayerController) -> QueueStatus {
|
||||
|
||||
/// Play a track from an album - backend fetches all album tracks and builds queue
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_play_album_track(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session: State<'_, MediaSessionManagerWrapper>,
|
||||
@@ -1383,6 +1403,7 @@ pub async fn player_play_album_track(
|
||||
|
||||
/// Play tracks by ID - backend fetches all metadata
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_play_tracks(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session: State<'_, MediaSessionManagerWrapper>,
|
||||
@@ -1521,7 +1542,7 @@ pub async fn player_play_tracks(
|
||||
}
|
||||
|
||||
/// Response for preload operation
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(specta::Type, Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PreloadResult {
|
||||
/// Number of tracks queued for preload
|
||||
@@ -1535,6 +1556,7 @@ pub struct PreloadResult {
|
||||
/// Preload upcoming tracks from the queue
|
||||
/// This queues background downloads for the next N tracks that aren't already downloaded
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_preload_upcoming(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
db: State<'_, DatabaseWrapper>,
|
||||
@@ -1671,6 +1693,7 @@ fn sanitize_filename(name: &str) -> String {
|
||||
|
||||
/// Update SmartCache configuration
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_set_cache_config(
|
||||
smart_cache: State<'_, SmartCacheWrapper>,
|
||||
config: CacheConfig,
|
||||
@@ -1682,6 +1705,7 @@ pub async fn player_set_cache_config(
|
||||
|
||||
/// Get current SmartCache configuration
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_get_cache_config(
|
||||
smart_cache: State<'_, SmartCacheWrapper>,
|
||||
) -> Result<CacheConfig, String> {
|
||||
@@ -1691,6 +1715,7 @@ pub async fn player_get_cache_config(
|
||||
|
||||
/// Configure Jellyfin API client for automatic playback reporting
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_configure_jellyfin(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
server_url: String,
|
||||
@@ -1717,6 +1742,7 @@ pub async fn player_configure_jellyfin(
|
||||
|
||||
/// Disable Jellyfin automatic playback reporting
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_disable_jellyfin(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
) -> Result<(), String> {
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::repository::types::{ImageOptions, ImageType};
|
||||
use crate::repository::MediaRepository;
|
||||
|
||||
/// Request to add items to queue
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(specta::Type, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AddToQueueRequest {
|
||||
pub items: Vec<PlayItemRequest>,
|
||||
@@ -24,7 +24,7 @@ pub struct AddToQueueRequest {
|
||||
}
|
||||
|
||||
/// Request to add a track by ID - backend fetches metadata
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(specta::Type, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AddTrackByIdRequest {
|
||||
pub track_id: String,
|
||||
@@ -32,7 +32,7 @@ pub struct AddTrackByIdRequest {
|
||||
}
|
||||
|
||||
/// Request to add multiple tracks by IDs - backend fetches metadata
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(specta::Type, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AddTracksByIdsRequest {
|
||||
pub track_ids: Vec<String>,
|
||||
@@ -40,6 +40,7 @@ pub struct AddTracksByIdsRequest {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_add_to_queue(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
db: State<'_, DatabaseWrapper>,
|
||||
@@ -81,6 +82,7 @@ pub async fn player_add_to_queue(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_remove_from_queue(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
index: usize,
|
||||
@@ -107,6 +109,7 @@ pub async fn player_remove_from_queue(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_move_in_queue(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
from_index: usize,
|
||||
@@ -137,6 +140,7 @@ pub async fn player_move_in_queue(
|
||||
|
||||
/// Add a track to queue by ID - backend fetches metadata and constructs URLs
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_add_track_by_id(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
db: State<'_, DatabaseWrapper>,
|
||||
@@ -236,6 +240,7 @@ pub async fn player_add_track_by_id(
|
||||
|
||||
/// Add multiple tracks to queue by IDs - backend fetches metadata and constructs URLs
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_add_tracks_by_ids(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
db: State<'_, DatabaseWrapper>,
|
||||
@@ -339,6 +344,7 @@ pub async fn player_add_tracks_by_ids(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_skip_to(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
index: usize,
|
||||
|
||||
@@ -9,6 +9,7 @@ use super::PlayerStateWrapper;
|
||||
|
||||
/// Play items on a remote Jellyfin session (casting)
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn remote_play_on_session(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session_id: String,
|
||||
@@ -36,6 +37,7 @@ pub async fn remote_play_on_session(
|
||||
|
||||
/// Send a playback command to a remote session
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn remote_send_command(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session_id: String,
|
||||
@@ -59,6 +61,7 @@ pub async fn remote_send_command(
|
||||
|
||||
/// Seek on a remote session
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn remote_session_seek(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session_id: String,
|
||||
@@ -82,6 +85,7 @@ pub async fn remote_session_seek(
|
||||
|
||||
/// Set volume on a remote session
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn remote_session_set_volume(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session_id: String,
|
||||
@@ -105,6 +109,7 @@ pub async fn remote_session_set_volume(
|
||||
|
||||
/// Toggle mute on a remote session
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn remote_session_toggle_mute(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
session_id: String,
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::player::PlayerStatusEvent;
|
||||
|
||||
/// Get the current media session state
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_get_session(
|
||||
session: State<'_, MediaSessionManagerWrapper>,
|
||||
) -> Result<crate::player::session::MediaSessionType, String> {
|
||||
@@ -19,6 +20,7 @@ pub async fn player_get_session(
|
||||
|
||||
/// Dismiss the current media session (returns to Idle)
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_dismiss_session(
|
||||
session: State<'_, MediaSessionManagerWrapper>,
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::player::AutoplaySettings;
|
||||
use crate::settings::{AudioSettings, VideoSettings};
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_set_audio_settings(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
settings: AudioSettings,
|
||||
@@ -19,6 +20,7 @@ pub async fn player_set_audio_settings(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_get_audio_settings(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
) -> Result<AudioSettings, String> {
|
||||
@@ -27,6 +29,7 @@ pub async fn player_get_audio_settings(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_set_video_settings(
|
||||
video_settings: State<'_, VideoSettingsWrapper>,
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
@@ -50,6 +53,7 @@ pub async fn player_set_video_settings(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_get_video_settings(
|
||||
video_settings: State<'_, VideoSettingsWrapper>,
|
||||
) -> Result<VideoSettings, String> {
|
||||
|
||||
@@ -17,6 +17,7 @@ use crate::storage::db_service::{DatabaseService, Query, QueryParam};
|
||||
|
||||
/// Set sleep timer mode
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_set_sleep_timer(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
mode: SleepTimerMode,
|
||||
@@ -28,6 +29,7 @@ pub async fn player_set_sleep_timer(
|
||||
|
||||
/// Cancel sleep timer
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_cancel_sleep_timer(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
) -> Result<SleepTimerState, String> {
|
||||
@@ -38,6 +40,7 @@ pub async fn player_cancel_sleep_timer(
|
||||
|
||||
/// Get current sleep timer state
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_get_sleep_timer(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
) -> Result<SleepTimerState, String> {
|
||||
@@ -49,6 +52,7 @@ pub async fn player_get_sleep_timer(
|
||||
|
||||
/// Get autoplay settings
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_get_autoplay_settings(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
) -> Result<AutoplaySettings, String> {
|
||||
@@ -58,6 +62,7 @@ pub async fn player_get_autoplay_settings(
|
||||
|
||||
/// Set autoplay settings and persist to database
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_set_autoplay_settings(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
db: State<'_, DatabaseWrapper>,
|
||||
@@ -101,6 +106,7 @@ pub async fn player_set_autoplay_settings(
|
||||
|
||||
/// Cancel active autoplay countdown
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_cancel_autoplay_countdown(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
) -> Result<(), String> {
|
||||
@@ -111,6 +117,7 @@ pub async fn player_cancel_autoplay_countdown(
|
||||
|
||||
/// Play next episode (user confirmed from popup)
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_play_next_episode(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
db: State<'_, DatabaseWrapper>,
|
||||
@@ -131,6 +138,7 @@ pub async fn player_play_next_episode(
|
||||
/// - Frontend when audio track ends via backend event - no itemId/repositoryHandle needed
|
||||
/// - Android JNI callback also triggers this logic directly
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn player_on_playback_ended(
|
||||
player: State<'_, PlayerStateWrapper>,
|
||||
repository_manager: State<'_, crate::commands::repository::RepositoryManagerWrapper>,
|
||||
|
||||
Reference in New Issue
Block a user