Skip to main content

#
jellytau_lib/commands/storage/
series_prefs.rs

    1//! Per-series preferred audio track commands.
    2//!
    3//! TRACES: UR-021 | DR-024
    4
    5use serde::{Deserialize, Serialize};
    6use std::sync::Arc;
    7use tauri::State;
    8
    9use super::DatabaseWrapper;
    10use crate::storage::db_service::{DatabaseService, Query, QueryParam};
    11
    12/// Audio track preference for a series
    13#[derive(specta::Type, Debug, Clone, Serialize, Deserialize)]
    14#[serde(rename_all = "camelCase")]
    15pub struct SeriesAudioPreference {
    16    pub series_id: String,
    17    pub audio_track_display_title: Option<String>,
    18    pub audio_track_language: Option<String>,
    19    pub audio_track_index: Option<i32>,
    20}
    21
    22/// Save user's preferred audio track for a series
    23#[tauri::command]
    24#[specta::specta]
    25pub async fn storage_save_series_audio_preference(
    26    db: State<'_, DatabaseWrapper>,
    27    user_id: String,
    28    series_id: String,
    29    server_id: String,
    30    audio_track_display_title: Option<String>,
    31    audio_track_language: Option<String>,
    32    audio_track_index: Option<i32>,
    33) -> Result<(), String> {
    34    let db_service = {
    35        let database = db.0.lock().map_err(|e| e.to_string())?;
    36        Arc::new(database.service())
    37    };
    38
    39    let query = Query::with_params(
    40        "INSERT INTO series_audio_preferences
    41            (user_id, series_id, server_id, audio_track_display_title, audio_track_language, audio_track_index, updated_at)
    42         VALUES (?, ?, ?, ?, ?, ?, datetime('now'))
    43         ON CONFLICT (user_id, series_id, server_id) DO UPDATE SET
    44            audio_track_display_title = excluded.audio_track_display_title,
    45            audio_track_language = excluded.audio_track_language,
    46            audio_track_index = excluded.audio_track_index,
    47            updated_at = datetime('now')",
    48        vec![
    49            QueryParam::String(user_id),
    50            QueryParam::String(series_id),
    51            QueryParam::String(server_id),
    52            audio_track_display_title.map(QueryParam::String).unwrap_or(QueryParam::Null),
    53            audio_track_language.map(QueryParam::String).unwrap_or(QueryParam::Null),
    54            audio_track_index.map(|i| QueryParam::Int64(i as i64)).unwrap_or(QueryParam::Null),
    55        ],
    56    );
    57
    58    db_service.execute(query).await.map_err(|e| e.to_string())?;
    59    Ok(())
    60}
    61
    62/// Get user's preferred audio track for a series
    63#[tauri::command]
    64#[specta::specta]
    65pub async fn storage_get_series_audio_preference(
    66    db: State<'_, DatabaseWrapper>,
    67    user_id: String,
    68    series_id: String,
    69) -> Result<Option<SeriesAudioPreference>, String> {
    70    let db_service = {
    71        let database = db.0.lock().map_err(|e| e.to_string())?;
    72        Arc::new(database.service())
    73    };
    74
    75    let query = Query::with_params(
    76        "SELECT series_id, audio_track_display_title, audio_track_language, audio_track_index
    77         FROM series_audio_preferences
    78         WHERE user_id = ? AND series_id = ?",
    79        vec![QueryParam::String(user_id), QueryParam::String(series_id)],
    80    );
    81
    82    let preference = db_service
    83        .query_optional(query, |row| {
    84            Ok(SeriesAudioPreference {
    85                series_id: row.get(0)?,
    86                audio_track_display_title: row.get(1)?,
    87                audio_track_language: row.get(2)?,
    88                audio_track_index: row.get(3)?,
    89            })
    90        })
    91        .await
    92        .map_err(|e| e.to_string())?;
    93
    94    Ok(preference)
    95}