Workstream C: convert commands/player to a folder module, extract remote-session commands
- Move commands/player.rs to commands/player/mod.rs (folder module). - Extract the 5 self-contained remote-session control commands (remote_play_on_session/send_command/session_seek/set_volume/toggle_mute) into commands/player/remote.rs, re-exported via `pub use remote::*` so the command names remain at commands::player::* and the invoke_handler is unchanged. No behavior change; establishes the submodule split pattern for the oversized command file.
This commit is contained in:
parent
46b9d328ab
commit
8ddad497bf
@ -1,5 +1,10 @@
|
|||||||
//! TRACES: UR-003, UR-004, UR-005, UR-010, UR-020, UR-021 | JA-022, JA-023, JA-024, JA-025, JA-026 | DR-001
|
//! TRACES: UR-003, UR-004, UR-005, UR-010, UR-020, UR-021 | JA-022, JA-023, JA-024, JA-025, JA-026 | DR-001
|
||||||
|
|
||||||
|
// Remote Jellyfin session control commands (casting) live in their own submodule
|
||||||
|
// and are re-exported so the command names remain at `commands::player::*`.
|
||||||
|
mod remote;
|
||||||
|
pub use remote::*;
|
||||||
|
|
||||||
use crate::utils::lock::MutexSafe;
|
use crate::utils::lock::MutexSafe;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -2111,124 +2116,6 @@ pub async fn player_disable_jellyfin(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Play items on a remote Jellyfin session (casting)
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn remote_play_on_session(
|
|
||||||
player: State<'_, PlayerStateWrapper>,
|
|
||||||
session_id: String,
|
|
||||||
item_ids: Vec<String>,
|
|
||||||
start_index: usize,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
log::info!("[RemoteSession] Playing {} items on session {} (start index: {})", item_ids.len(), session_id, start_index);
|
|
||||||
log::info!("[RemoteSession] Item IDs: {:?}", item_ids);
|
|
||||||
|
|
||||||
let client_opt = {
|
|
||||||
let controller = player.0.lock().await;
|
|
||||||
controller.jellyfin_client().lock().map_err(|e| e.to_string())?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(client) = client_opt {
|
|
||||||
log::info!("[RemoteSession] Jellyfin client IS configured, calling play_on_session");
|
|
||||||
client.play_on_session(session_id, item_ids, start_index, None).await?;
|
|
||||||
log::info!("[RemoteSession] Successfully started playback on remote session");
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
log::error!("[RemoteSession] Jellyfin client is NOT configured! User needs to log out/in or restart app");
|
|
||||||
Err("Jellyfin client not configured - please restart the app or log out and log back in".to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Send a playback command to a remote session
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn remote_send_command(
|
|
||||||
player: State<'_, PlayerStateWrapper>,
|
|
||||||
session_id: String,
|
|
||||||
command: String,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
log::info!("[RemoteSession] Sending command '{}' to session {}", command, session_id);
|
|
||||||
|
|
||||||
let client_opt = {
|
|
||||||
let controller = player.0.lock().await;
|
|
||||||
controller.jellyfin_client().lock().map_err(|e| e.to_string())?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(client) = client_opt {
|
|
||||||
client.send_session_command(session_id, &command).await?;
|
|
||||||
log::info!("[RemoteSession] Command sent successfully");
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err("Jellyfin client not configured".to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Seek on a remote session
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn remote_session_seek(
|
|
||||||
player: State<'_, PlayerStateWrapper>,
|
|
||||||
session_id: String,
|
|
||||||
position_ticks: i64,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
log::info!("[RemoteSession] Seeking to {} ticks on session {}", position_ticks, session_id);
|
|
||||||
|
|
||||||
let client_opt = {
|
|
||||||
let controller = player.0.lock().await;
|
|
||||||
controller.jellyfin_client().lock().map_err(|e| e.to_string())?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(client) = client_opt {
|
|
||||||
client.session_seek(session_id, position_ticks).await?;
|
|
||||||
log::info!("[RemoteSession] Seek successful");
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err("Jellyfin client not configured".to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set volume on a remote session
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn remote_session_set_volume(
|
|
||||||
player: State<'_, PlayerStateWrapper>,
|
|
||||||
session_id: String,
|
|
||||||
volume: i32,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
log::info!("[RemoteSession] Setting volume to {} on session {}", volume, session_id);
|
|
||||||
|
|
||||||
let client_opt = {
|
|
||||||
let controller = player.0.lock().await;
|
|
||||||
controller.jellyfin_client().lock().map_err(|e| e.to_string())?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(client) = client_opt {
|
|
||||||
client.session_set_volume(session_id, volume).await?;
|
|
||||||
log::info!("[RemoteSession] Volume set successfully");
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err("Jellyfin client not configured".to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Toggle mute on a remote session
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn remote_session_toggle_mute(
|
|
||||||
player: State<'_, PlayerStateWrapper>,
|
|
||||||
session_id: String,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
log::info!("[RemoteSession] Toggling mute on session {}", session_id);
|
|
||||||
|
|
||||||
let client_opt = {
|
|
||||||
let controller = player.0.lock().await;
|
|
||||||
controller.jellyfin_client().lock().map_err(|e| e.to_string())?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(client) = client_opt {
|
|
||||||
client.session_toggle_mute(session_id).await?;
|
|
||||||
log::info!("[RemoteSession] Mute toggled successfully");
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err("Jellyfin client not configured".to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== Sleep Timer Commands =====
|
// ===== Sleep Timer Commands =====
|
||||||
|
|
||||||
/// Set sleep timer mode
|
/// Set sleep timer mode
|
||||||
126
src-tauri/src/commands/player/remote.rs
Normal file
126
src-tauri/src/commands/player/remote.rs
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
//! Remote Jellyfin session control commands (casting to another device).
|
||||||
|
//!
|
||||||
|
//! These thin command adapters forward control actions to the active Jellyfin
|
||||||
|
//! session via the player's configured `JellyfinClient`.
|
||||||
|
|
||||||
|
use tauri::State;
|
||||||
|
|
||||||
|
use super::PlayerStateWrapper;
|
||||||
|
|
||||||
|
/// Play items on a remote Jellyfin session (casting)
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn remote_play_on_session(
|
||||||
|
player: State<'_, PlayerStateWrapper>,
|
||||||
|
session_id: String,
|
||||||
|
item_ids: Vec<String>,
|
||||||
|
start_index: usize,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
log::info!("[RemoteSession] Playing {} items on session {} (start index: {})", item_ids.len(), session_id, start_index);
|
||||||
|
log::info!("[RemoteSession] Item IDs: {:?}", item_ids);
|
||||||
|
|
||||||
|
let client_opt = {
|
||||||
|
let controller = player.0.lock().await;
|
||||||
|
controller.jellyfin_client().lock().map_err(|e| e.to_string())?.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(client) = client_opt {
|
||||||
|
log::info!("[RemoteSession] Jellyfin client IS configured, calling play_on_session");
|
||||||
|
client.play_on_session(session_id, item_ids, start_index, None).await?;
|
||||||
|
log::info!("[RemoteSession] Successfully started playback on remote session");
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
log::error!("[RemoteSession] Jellyfin client is NOT configured! User needs to log out/in or restart app");
|
||||||
|
Err("Jellyfin client not configured - please restart the app or log out and log back in".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a playback command to a remote session
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn remote_send_command(
|
||||||
|
player: State<'_, PlayerStateWrapper>,
|
||||||
|
session_id: String,
|
||||||
|
command: String,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
log::info!("[RemoteSession] Sending command '{}' to session {}", command, session_id);
|
||||||
|
|
||||||
|
let client_opt = {
|
||||||
|
let controller = player.0.lock().await;
|
||||||
|
controller.jellyfin_client().lock().map_err(|e| e.to_string())?.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(client) = client_opt {
|
||||||
|
client.send_session_command(session_id, &command).await?;
|
||||||
|
log::info!("[RemoteSession] Command sent successfully");
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err("Jellyfin client not configured".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Seek on a remote session
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn remote_session_seek(
|
||||||
|
player: State<'_, PlayerStateWrapper>,
|
||||||
|
session_id: String,
|
||||||
|
position_ticks: i64,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
log::info!("[RemoteSession] Seeking to {} ticks on session {}", position_ticks, session_id);
|
||||||
|
|
||||||
|
let client_opt = {
|
||||||
|
let controller = player.0.lock().await;
|
||||||
|
controller.jellyfin_client().lock().map_err(|e| e.to_string())?.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(client) = client_opt {
|
||||||
|
client.session_seek(session_id, position_ticks).await?;
|
||||||
|
log::info!("[RemoteSession] Seek successful");
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err("Jellyfin client not configured".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set volume on a remote session
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn remote_session_set_volume(
|
||||||
|
player: State<'_, PlayerStateWrapper>,
|
||||||
|
session_id: String,
|
||||||
|
volume: i32,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
log::info!("[RemoteSession] Setting volume to {} on session {}", volume, session_id);
|
||||||
|
|
||||||
|
let client_opt = {
|
||||||
|
let controller = player.0.lock().await;
|
||||||
|
controller.jellyfin_client().lock().map_err(|e| e.to_string())?.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(client) = client_opt {
|
||||||
|
client.session_set_volume(session_id, volume).await?;
|
||||||
|
log::info!("[RemoteSession] Volume set successfully");
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err("Jellyfin client not configured".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Toggle mute on a remote session
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn remote_session_toggle_mute(
|
||||||
|
player: State<'_, PlayerStateWrapper>,
|
||||||
|
session_id: String,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
log::info!("[RemoteSession] Toggling mute on session {}", session_id);
|
||||||
|
|
||||||
|
let client_opt = {
|
||||||
|
let controller = player.0.lock().await;
|
||||||
|
controller.jellyfin_client().lock().map_err(|e| e.to_string())?.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(client) = client_opt {
|
||||||
|
client.session_toggle_mute(session_id).await?;
|
||||||
|
log::info!("[RemoteSession] Mute toggled successfully");
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err("Jellyfin client not configured".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user