diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 7d06799..fbccf01 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -257,6 +257,7 @@ False True + 0 False diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 8aaadea..262293b 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -17,8 +17,10 @@ use std::sync::mpsc::{channel, Receiver, Sender}; #[derive(Clone, Debug)] pub enum Action { UpdateSources(Option), - RefreshViews, + RefreshAllViews, + RefreshEpisodesView, RefreshEpisodesViewBGR, + RefreshWidget, HeaderBarShowTile(String), HeaderBarNormal, HeaderBarHideUpdateIndicator, @@ -134,12 +136,14 @@ impl App { utils::refresh_feed(headerbar.clone(), Some(vec![s]), sender.clone()) } } - Ok(Action::RefreshViews) => content.update(), + Ok(Action::RefreshAllViews) => content.update(), + Ok(Action::RefreshWidget) => content.update_widget(), + Ok(Action::RefreshEpisodesView) => content.update_episode_view(), Ok(Action::RefreshEpisodesViewBGR) => content.update_episode_view_if_baground(), Ok(Action::HeaderBarShowTile(title)) => headerbar.switch_to_back(&title), Ok(Action::HeaderBarNormal) => headerbar.switch_to_normal(), Ok(Action::HeaderBarHideUpdateIndicator) => headerbar.hide_update_notification(), - _ => (), + Err(_) => (), } Continue(true) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 0480512..57a8018 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -41,8 +41,9 @@ impl Content { } pub fn update(&self) { - self.update_shows_view(); self.update_episode_view(); + self.update_shows_view(); + self.update_widget() } pub fn update_episode_view(&self) { @@ -56,7 +57,11 @@ impl Content { } pub fn update_shows_view(&self) { - self.shows.update(); + self.shows.update_podcasts(); + } + + pub fn update_widget(&self) { + self.shows.update_widget(); } pub fn get_stack(&self) -> gtk::Stack { @@ -100,15 +105,11 @@ impl ShowStack { show } - // fn is_empty(&self) -> bool { - // self.podcasts.is_empty() + // pub fn update(&self) { + // self.update_widget(); + // self.update_podcasts(); // } - pub fn update(&self) { - self.update_podcasts(); - self.update_widget(); - } - pub fn update_podcasts(&self) { let vis = self.stack.get_visible_child_name().unwrap(); diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index 2be4804..9a21819 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -4,7 +4,7 @@ use hammond_downloader::downloader::get_episode; use app::Action; -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use std::sync::{Arc, Mutex, RwLock}; use std::sync::mpsc::Sender; // use std::sync::atomic::AtomicUsize; @@ -24,26 +24,27 @@ impl Progress { downloaded_bytes: 0, } } + + pub fn get_fraction(&self) -> f64 { + self.downloaded_bytes as f64 / self.total_bytes as f64 + } } lazy_static! { - pub static ref ACTIVE_DOWNLOADS: Arc>> = { - Arc::new(RwLock::new(HashSet::new())) - }; - - pub static ref ACTIVE_PROGRESS: Arc>>> = { + pub static ref ACTIVE_DOWNLOADS: Arc>>>> = { Arc::new(RwLock::new(HashMap::new())) }; } -pub fn add(id: i32, directory: &str, sender: Sender) { +pub fn add(id: i32, directory: &str, sender: Sender, prog: Arc>) { { let mut m = ACTIVE_DOWNLOADS.write().unwrap(); - m.insert(id); + m.insert(id, prog.clone()); } let dir = directory.to_owned(); thread::spawn(move || { + info!("{:?}", prog); // just checking that it compiles let episode = dbqueries::get_episode_from_rowid(id).unwrap(); let e = get_episode(&mut episode.into(), dir.as_str()); if let Err(err) = e { @@ -54,7 +55,9 @@ pub fn add(id: i32, directory: &str, sender: Sender) { let mut m = ACTIVE_DOWNLOADS.write().unwrap(); m.remove(&id); } - sender.send(Action::RefreshViews).unwrap(); + + sender.send(Action::RefreshEpisodesView).unwrap(); + sender.send(Action::RefreshWidget).unwrap(); }); } @@ -102,9 +105,10 @@ mod tests { }; let (sender, _rx) = channel(); + let prog = Arc::new(Mutex::new(Progress::new(42))); let download_fold = downloader::get_download_folder(&pd.title()).unwrap(); - add(episode.rowid(), download_fold.as_str(), sender); + add(episode.rowid(), download_fold.as_str(), sender, prog); // Give it soem time to download the file thread::sleep(time::Duration::from_secs(40)); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 4928abc..2f354ea 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -30,7 +30,7 @@ pub fn refresh_feed(headerbar: Arc
, source: Option>, sender: }; sender.send(Action::HeaderBarHideUpdateIndicator).unwrap(); - sender.send(Action::RefreshViews).unwrap(); + sender.send(Action::RefreshAllViews).unwrap(); }); } diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index e7040af..fae1ed7 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -17,6 +17,7 @@ use app::Action; use manager; use std::sync::mpsc::Sender; +use std::sync::{Arc, Mutex}; use std::path::Path; #[derive(Debug, Clone)] @@ -83,6 +84,8 @@ impl EpisodeWidget { // TODO: wire the progress_bar to the downloader. // TODO: wire the cancel button. fn init(&self, episode: &mut EpisodeWidgetQuery, sender: Sender) { + WidgetExt::set_name(&self.container, &episode.rowid().to_string()); + // Set the title label state. self.set_title(episode); @@ -98,12 +101,8 @@ impl EpisodeWidget { // Show or hide the play/delete/download buttons upon widget initialization. self.show_buttons(episode.local_uri()); - { - let m = manager::ACTIVE_DOWNLOADS.read().unwrap(); - if m.contains(&episode.rowid()) { - self.show_progess_bar() - }; - } + // Determine what the state of the progress bar should be. + self.determine_progess_bar(); let title = &self.title; self.play @@ -118,17 +117,10 @@ impl EpisodeWidget { }; })); - let cancel = &self.cancel; - let progress = self.progress.clone(); self.download - .connect_clicked(clone!(episode, cancel, progress, sender => move |dl| { - on_download_clicked( - &mut episode.clone(), - dl, - &cancel, - progress.clone(), - sender.clone() - ); + .connect_clicked(clone!(episode, sender => move |dl| { + dl.set_sensitive(false); + on_download_clicked(&mut episode.clone(), sender.clone()); })); } @@ -202,43 +194,56 @@ impl EpisodeWidget { }; } - fn show_progess_bar(&self) { - let progress_bar = self.progress.clone(); - timeout_add(200, move || { - progress_bar.pulse(); - glib::Continue(true) - }); + fn determine_progess_bar(&self) { + let id = WidgetExt::get_name(&self.container) + .unwrap() + .parse::() + .unwrap(); - self.progress.show(); - self.download.hide(); - self.cancel.show(); + let m = manager::ACTIVE_DOWNLOADS.read().unwrap(); + if !m.contains_key(&id) { + return; + }; + + let progress_bar = self.progress.clone(); + if let Some(prog) = m.get(&id) { + self.progress.show(); + self.download.hide(); + self.cancel.show(); + + timeout_add( + 400, + clone!(prog => move || { + let fraction = { + let m = prog.lock().unwrap(); + m.get_fraction() + }; + progress_bar.set_fraction(fraction); + // info!("Fraction: {}", progress_bar.get_fraction()); + + if fraction != 1.0{ + glib::Continue(true) + } else { + glib::Continue(false) + } + }), + ); + } } } -fn on_download_clicked( - ep: &EpisodeWidgetQuery, - download_bttn: >k::Button, - cancel_bttn: >k::Button, - progress_bar: gtk::ProgressBar, - sender: Sender, -) { - let progress = progress_bar.clone(); - - // Start the proggress_bar pulse. - timeout_add(200, move || { - progress_bar.pulse(); - glib::Continue(true) - }); - +fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: Sender) { let pd = dbqueries::get_podcast_from_id(ep.podcast_id()).unwrap(); - let pd_title = pd.title().to_owned(); - cancel_bttn.show(); - progress.show(); - download_bttn.hide(); - let download_fold = downloader::get_download_folder(&pd_title).unwrap(); + let download_fold = downloader::get_download_folder(&pd.title().to_owned()).unwrap(); - manager::add(ep.rowid(), &download_fold, sender.clone()); - sender.send(Action::RefreshEpisodesViewBGR).unwrap(); + // Create a new `Progress` struct to keep track of dl progress. + let prog = Arc::new(Mutex::new(manager::Progress::new(42))); + // Start a new download. + manager::add(ep.rowid(), &download_fold, sender.clone(), prog.clone()); + + // Update Views + sender.send(Action::RefreshEpisodesView).unwrap(); + sender.send(Action::RefreshWidget).unwrap(); } fn on_play_bttn_clicked(episode_id: i32) { diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 37a571e..6470596 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -142,7 +142,7 @@ fn on_unsub_button_clicked( })); shows.switch_podcasts_animated(); // Queue a refresh after the switch to avoid blocking the db. - sender.send(Action::RefreshViews).unwrap(); + sender.send(Action::RefreshAllViews).unwrap(); } #[allow(dead_code)]