From 49e1e767c3052933e2bad190e29d134b29ebef6f Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Sat, 8 Mar 2025 22:35:18 -0600 Subject: [PATCH] updating songs now works --- Cargo.lock | 3 ++ Cargo.toml | 2 +- src/core/songs.rs | 68 ++++++++++++++++++++++++++++++++--- src/ui/library.rs | 92 ++++++++++++++++++++++------------------------- src/ui/mod.rs | 1 + 5 files changed, 110 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24f45a1..15c69b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5498,6 +5498,8 @@ dependencies = [ "sha2", "smallvec", "thiserror 2.0.11", + "tokio", + "tokio-stream", "tracing", "url", ] @@ -5537,6 +5539,7 @@ dependencies = [ "sqlx-sqlite", "syn 2.0.98", "tempfile", + "tokio", "url", ] diff --git a/Cargo.toml b/Cargo.toml index 2067ea6..c99c22e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ iced_video_player = { git = "https://github.com/jackpot51/iced_video_player", br strum = "0.26.3" strum_macros = "0.26.4" ron = "0.8.1" -sqlx = { version = "0.8.2", features = ["sqlite"] } +sqlx = { version = "0.8.2", features = ["sqlite", "runtime-tokio"] } dirs = "5.0.1" tokio = "1.41.1" crisp = { git = "https://git.tfcconnection.org/chris/crisp", version = "0.1.3" } diff --git a/src/core/songs.rs b/src/core/songs.rs index d960d62..c2eb87a 100644 --- a/src/core/songs.rs +++ b/src/core/songs.rs @@ -5,8 +5,8 @@ use crisp::types::{Keyword, Symbol, Value}; use miette::{miette, IntoDiagnostic, Result}; use serde::{Deserialize, Serialize}; use sqlx::{ - query, sqlite::SqliteRow, FromRow, Row, SqliteConnection, - SqlitePool, + pool::PoolConnection, query, sqlite::SqliteRow, FromRow, Row, + Sqlite, SqliteConnection, SqlitePool, }; use tracing::{debug, error}; @@ -375,13 +375,12 @@ pub async fn get_song_from_db( } impl Model { - pub async fn update_song( + pub async fn update_song_in_db( &mut self, item: Song, - index: i32, db: &mut SqliteConnection, ) -> Result<()> { - self.update_item(item.clone(), index)?; + // self.update_item(item.clone(), index)?; let verse_order = { if let Some(vo) = item.verse_order { @@ -469,6 +468,65 @@ impl Model { } } +pub async fn update_song_in_db<'a>( + item: Song, + db: PoolConnection, +) -> Result<()> { + // self.update_item(item.clone(), index)?; + + let verse_order = { + if let Some(vo) = item.verse_order { + vo.into_iter() + .map(|mut s| { + s.push_str(" "); + s + }) + .collect::() + } else { + String::from("") + } + }; + + let audio = item + .audio + .map(|a| a.to_str().unwrap_or_default().to_string()); + + let background = item + .background + .map(|b| b.path.to_str().unwrap_or_default().to_string()); + + // let text_alignment = item.text_alignment.map(|ta| match ta { + // TextAlignment::TopLeft => todo!(), + // TextAlignment::TopCenter => todo!(), + // TextAlignment::TopRight => todo!(), + // TextAlignment::MiddleLeft => todo!(), + // TextAlignment::MiddleCenter => todo!(), + // TextAlignment::MiddleRight => todo!(), + // TextAlignment::BottomLeft => todo!(), + // TextAlignment::BottomCenter => todo!(), + // TextAlignment::BottomRight => todo!(), + // }) + + query!( + r#"UPDATE songs SET title = $2, lyrics = $3, author = $4, ccli = $5, verse_order = $6, audio = $7, font = $8, font_size = $9, background = $10 WHERE id = $1"#, + item.id, + item.title, + item.lyrics, + item.author, + item.ccli, + verse_order, + audio, + item.font, + item.font_size, + background + ) + .execute(&mut db.detach()) + .await + .into_diagnostic()?; + + Ok(()) +} + impl Song { pub fn get_lyrics(&self) -> Result> { let mut lyric_list = Vec::new(); diff --git a/src/ui/library.rs b/src/ui/library.rs index b07e2d4..f690bcd 100644 --- a/src/ui/library.rs +++ b/src/ui/library.rs @@ -1,5 +1,8 @@ use cosmic::{ - iced::{alignment::Vertical, Background, Border, Length}, + iced::{ + alignment::Vertical, futures::FutureExt, Background, Border, + Length, + }, iced_widget::{column, row as rowm, text as textm}, widget::{ container, horizontal_space, icon, mouse_area, responsive, @@ -17,7 +20,7 @@ use crate::core::{ model::{LibraryKind, Model}, presentations::Presentation, service_items::ServiceItem, - songs::Song, + songs::{update_song_in_db, Song}, videos::Video, }; @@ -46,6 +49,8 @@ pub(crate) enum Message { HoverItem(Option<(LibraryKind, i32)>), SelectItem(Option<(LibraryKind, i32)>), UpdateSong(Song), + SongChanged, + Error(String), None, } @@ -101,15 +106,42 @@ impl<'a> Library { Task::none() } Message::UpdateSong(song) => { - let future = self.update_song(song); - Task::perform(future, |r| { - match r { - Ok(_) => (), - Err(e) => error!(?e), - }; - Message::None - }) + let Some((kind, index)) = self.editing_item else { + error!("Not editing an item"); + return Task::none(); + }; + + if kind != LibraryKind::Song { + error!("Not editing a song item"); + return Task::none(); + }; + + match self + .song_library + .update_item(song.clone(), index) + { + Ok(_) => Task::future(self.db.acquire()) + .and_then(move |conn| { + Task::perform( + update_song_in_db(song.clone(), conn) + .map(|r| match r { + Ok(_) => {} + Err(e) => { + error!(?e); + } + }), + |_| Message::SongChanged, + ) + }), + Err(_) => todo!(), + } } + Message::SongChanged => { + // self.song_library.update_item(song, index); + debug!("song changed"); + Task::none() + } + Message::Error(_) => todo!(), } } @@ -353,29 +385,6 @@ impl<'a> Library { }) .into() } - - pub async fn update_song<'b>( - &'b mut self, - song: Song, - ) -> Result<()> { - let Some((kind, index)) = self.editing_item else { - return Err(miette!("Not editing an item")); - }; - - if kind != LibraryKind::Song { - return Err(miette!("Not editing a song item")); - } - let mut db = self.db.acquire().await.expect("foo"); - - if let Some(_) = self.song_library.items.get(index as usize) { - self.song_library - .update_song(song, index, &mut db) - .await?; - Ok(()) - } else { - Err(miette!("Song not found")) - } - } } async fn add_db() -> Result { @@ -387,23 +396,6 @@ async fn add_db() -> Result { SqlitePool::connect(&db_url).await.into_diagnostic() } -pub(crate) async fn update_song( - song: Song, - index: usize, - db: &mut SqlitePool, - song_library: &mut Model, -) -> Result<()> { - if let Some(_) = song_library.items.get(index) { - let mut db = db.acquire().await.expect("foo"); - song_library - .update_song(song, index as i32, &mut db) - .await?; - Ok(()) - } else { - Err(miette!("Song not found")) - } -} - fn elide_text(text: String, width: f32) -> String { const CHAR_SIZE: f32 = 8.0; let text_length = text.len() as f32 * CHAR_SIZE; diff --git a/src/ui/mod.rs b/src/ui/mod.rs index aa081cd..e6e0c84 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,3 +1,4 @@ +pub mod double_ended_slider; pub mod library; pub mod presenter; pub mod song_editor;