diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index ca9b44c..0e7170d 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -103,6 +103,20 @@ pub fn get_episode_from_rowid(ep_id: i32) -> Result { .map_err(From::from) } +pub fn get_episode_widget_from_rowid(ep_id: i32) -> Result { + use schema::episode::dsl::*; + let db = connection(); + let con = db.get()?; + + episode + .select(( + rowid, title, uri, local_uri, epoch, length, duration, played, podcast_id, + )) + .filter(rowid.eq(ep_id)) + .get_result::(&con) + .map_err(From::from) +} + pub fn get_episode_local_uri_from_id(ep_id: i32) -> Result, DataError> { use schema::episode::dsl::*; let db = connection(); diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index a4120e6..c497348 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -5,10 +5,7 @@ use rayon; use hammond_data::dbqueries; use hammond_downloader::downloader::{get_episode, DownloadProgress}; -use app::Action; - use std::collections::HashMap; -use std::sync::mpsc::Sender; use std::sync::{Arc, Mutex, RwLock}; // use std::sync::atomic::AtomicUsize; // use std::path::PathBuf; @@ -78,7 +75,7 @@ lazy_static! { static ref DLPOOL: rayon::ThreadPool = rayon::ThreadPoolBuilder::new().build().unwrap(); } -pub fn add(id: i32, directory: String, sender: Sender) -> Result<(), Error> { +pub fn add(id: i32, directory: String) -> Result<(), Error> { // Create a new `Progress` struct to keep track of dl progress. let prog = Arc::new(Mutex::new(Progress::default())); @@ -88,11 +85,10 @@ pub fn add(id: i32, directory: String, sender: Sender) -> Result<(), Err }; DLPOOL.spawn(move || { - if let Ok(episode) = dbqueries::get_episode_from_rowid(id) { + if let Ok(mut episode) = dbqueries::get_episode_widget_from_rowid(id) { let id = episode.rowid(); - let pid = episode.podcast_id(); - get_episode(&mut episode.into(), directory.as_str(), Some(prog)) + get_episode(&mut episode, directory.as_str(), Some(prog)) .map_err(|err| error!("Download Failed: {}", err)) .ok(); @@ -104,15 +100,6 @@ pub fn add(id: i32, directory: String, sender: Sender) -> Result<(), Err // if let Ok(m) = ACTIVE_DOWNLOADS.read() { // debug!("ACTIVE DOWNLOADS: {:#?}", m); // } - - sender - .send(Action::RefreshWidgetIfSame(pid)) - .map_err(|err| error!("Action Sender: {}", err)) - .ok(); - sender - .send(Action::RefreshEpisodesView) - .map_err(|err| error!("Action Sender: {}", err)) - .ok(); } }); diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 0d563db..ffba865 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -128,10 +128,10 @@ impl EpisodeWidget { .and_then(|_| { info!("Donwload started succesfully."); determine_media_state(media_machine.clone(), &ep) - }) - .map_err(|err| error!("Error: {}", err)) - .map_err(|_| error!("Could not determine Media State")) - .ok(); + }) + .map_err(|err| error!("Error: {}", err)) + .map_err(|_| error!("Could not determine Media State")) + .ok(); } // Restore sensitivity after operations above complete @@ -190,20 +190,42 @@ fn determine_media_state( // Show or hide the play/delete/download buttons upon widget initialization. if let Some(prog) = active_dl { - let episode = episode.clone(); + + // set a callback that will update the state when the download finishes + let id = episode.rowid(); + let callback = clone!(media_machine => move || { + if let Ok(guard) = manager::ACTIVE_DOWNLOADS.read() { + if !guard.contains_key(&id) { + if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) { + determine_media_state(media_machine.clone(), &ep) + .map_err(|err| error!("Error: {}", err)) + .map_err(|_| error!("Could not determine Media State")) + .ok(); + + return glib::Continue(false) + } + } + } + + glib::Continue(true) + }); + gtk::timeout_add(250, callback); + lock.cancel_connect_clicked(clone!(prog, media_machine => move |_| { if let Ok(mut m) = prog.lock() { m.cancel(); } if let Ok(mut lock) = media_machine.try_borrow_mut() { - take_mut::take(lock.deref_mut(), |media| { - media.determine_state( - episode.length(), - false, - episode.local_uri().is_some(), - ) - }); + if let Ok(episode) = dbqueries::get_episode_widget_from_rowid(id) { + take_mut::take(lock.deref_mut(), |media| { + media.determine_state( + episode.length(), + false, + episode.local_uri().is_some(), + ) + }); + } } })); drop(lock); @@ -221,12 +243,15 @@ fn determine_media_state( } #[inline] -fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: Sender) -> Result<(), Error> { +fn on_download_clicked( + ep: &EpisodeWidgetQuery, + sender: Sender, +) -> Result<(), Error> { let pd = dbqueries::get_podcast_from_id(ep.podcast_id())?; let download_fold = get_download_folder(&pd.title())?; // Start a new download. - manager::add(ep.rowid(), download_fold, sender.clone())?; + manager::add(ep.rowid(), download_fold)?; // Update Views sender.send(Action::RefreshEpisodesViewBGR)?;