From 33cd6e69ff888e83e9617ba0d597719ec2f17158 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 3 Jan 2018 06:53:19 +0200 Subject: [PATCH] EpisodeWidget: Migrate to use a Channel Action instead of simple Action. --- hammond-gtk/resources/gtk/episode_widget.ui | 2 - hammond-gtk/src/app.rs | 6 +-- hammond-gtk/src/content.rs | 16 +++++-- hammond-gtk/src/views/episodes.rs | 10 +++-- hammond-gtk/src/widgets/episode.rs | 47 +++++++++------------ hammond-gtk/src/widgets/show.rs | 6 +-- 6 files changed, 43 insertions(+), 44 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 66fc8f6..ea1edcb 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -197,7 +197,6 @@ Download this episode end center - app.refresh_episodes True @@ -221,7 +220,6 @@ True Play this episode center - app.refresh_episodes True diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index d9c29b5..e0cb3a0 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -19,7 +19,7 @@ use std::time::Duration; pub enum Action { UpdateSources(Option), RefreshViews, - RefreshEpisodesView, + RefreshEpisodesViewBGR, } #[derive(Debug)] @@ -169,8 +169,8 @@ impl App { Ok(Action::RefreshViews) => { content.update(); } - Ok(Action::RefreshEpisodesView) => { - content.update_episode_view(); + Ok(Action::RefreshEpisodesViewBGR) => { + content.update_episode_view_if_baground(); } _ => (), } diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 2e0161d..01b5de4 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -26,7 +26,7 @@ pub struct Content { impl Content { pub fn new(header: Rc
, sender: Sender) -> Rc { let stack = gtk::Stack::new(); - let episodes = EpisodeStack::new(); + let episodes = EpisodeStack::new(sender.clone()); let shows = ShowStack::new(header, episodes.clone(), sender.clone()); stack.add_titled(&episodes.stack, "episodes", "Episodes"); @@ -49,6 +49,12 @@ impl Content { self.episodes.update(); } + pub fn update_episode_view_if_baground(&self) { + if self.stack.get_visible_child_name() != Some("episodes".into()) { + self.episodes.update(); + } + } + pub fn update_shows_view(&self) { self.shows.update(); } @@ -178,11 +184,12 @@ pub struct EpisodeStack { // populated: RecentEpisodes, // empty: EmptyView, stack: gtk::Stack, + sender: Sender, } impl EpisodeStack { - fn new() -> Rc { - let episodes = EpisodesView::new(); + fn new(sender: Sender) -> Rc { + let episodes = EpisodesView::new(sender.clone()); let empty = EmptyView::new(); let stack = gtk::Stack::new(); @@ -199,12 +206,13 @@ impl EpisodeStack { // empty, // populated: pop, stack, + sender, }) } pub fn update(&self) { let old = self.stack.get_child_by_name("episodes").unwrap(); - let eps = EpisodesView::new(); + let eps = EpisodesView::new(self.sender.clone()); self.stack.remove(&old); self.stack.add_named(&eps.container, "episodes"); diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 7a4d794..cddde81 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -7,8 +7,10 @@ use hammond_data::EpisodeWidgetQuery; use widgets::episode::EpisodeWidget; use utils::get_pixbuf_from_path; +use app::Action; use std::rc::Rc; +use std::sync::mpsc::Sender; #[derive(Debug, Clone)] enum ListSplit { @@ -69,13 +71,13 @@ impl Default for EpisodesView { } impl EpisodesView { - pub fn new() -> Rc { + pub fn new(sender: Sender) -> Rc { let view = EpisodesView::default(); let episodes = dbqueries::get_episodes_widgets_with_limit(100).unwrap(); let now_utc = Utc::now(); episodes.into_iter().for_each(|mut ep| { - let viewep = EpisodesViewWidget::new(&mut ep); + let viewep = EpisodesViewWidget::new(&mut ep, sender.clone()); let t = split(&now_utc, i64::from(ep.epoch())); match t { @@ -187,7 +189,7 @@ impl Default for EpisodesViewWidget { } impl EpisodesViewWidget { - fn new(episode: &mut EpisodeWidgetQuery) -> EpisodesViewWidget { + fn new(episode: &mut EpisodeWidgetQuery, sender: Sender) -> EpisodesViewWidget { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); @@ -200,7 +202,7 @@ impl EpisodesViewWidget { } } - let ep = EpisodeWidget::new(episode); + let ep = EpisodeWidget::new(episode, sender.clone()); container.pack_start(&ep.container, true, true, 6); EpisodesViewWidget { diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index c5048ff..f6bab76 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -13,9 +13,11 @@ use hammond_data::{EpisodeWidgetQuery, Podcast}; use hammond_data::errors::*; use hammond_downloader::downloader; +use app::Action; + use std::thread; use std::cell::RefCell; -use std::sync::mpsc::{channel, Receiver}; +use std::sync::mpsc::{channel, Receiver, Sender}; use std::path::Path; type Foo = RefCell< @@ -86,16 +88,16 @@ impl Default for EpisodeWidget { } impl EpisodeWidget { - pub fn new(episode: &mut EpisodeWidgetQuery) -> EpisodeWidget { + pub fn new(episode: &mut EpisodeWidgetQuery, sender: Sender) -> EpisodeWidget { let widget = EpisodeWidget::default(); - widget.init(episode); + widget.init(episode, sender); widget } // TODO: calculate lenght. // TODO: wire the progress_bar to the downloader. // TODO: wire the cancel button. - fn init(&self, episode: &mut EpisodeWidgetQuery) { + fn init(&self, episode: &mut EpisodeWidgetQuery, sender: Sender) { // Set the title label state. self.set_title(episode); @@ -113,29 +115,32 @@ impl EpisodeWidget { let title = &self.title; self.play - .connect_clicked(clone!(episode, title => move |_| { + .connect_clicked(clone!(episode, title, sender => move |_| { let mut episode = episode.clone(); on_play_bttn_clicked(episode.rowid()); if episode.set_played_now().is_ok() { title .get_style_context() .map(|c| c.add_class("dim-label")); + sender.clone().send(Action::RefreshEpisodesViewBGR).unwrap(); }; })); let play = &self.play; let cancel = &self.cancel; let progress = self.progress.clone(); - self.download - .connect_clicked(clone!(play, episode, cancel, progress => move |dl| { + self.download.connect_clicked( + clone!(play, episode, cancel, progress, sender => move |dl| { on_download_clicked( &mut episode.clone(), dl, &play, &cancel, - progress.clone() + progress.clone(), + sender.clone() ); - })); + }), + ); } /// Show or hide the play/delete/download buttons upon widget initialization. @@ -214,6 +219,7 @@ fn on_download_clicked( play_bttn: >k::Button, cancel_bttn: >k::Button, progress_bar: gtk::ProgressBar, + sender: Sender, ) { let progress = progress_bar.clone(); @@ -223,27 +229,13 @@ fn on_download_clicked( glib::Continue(true) }); - // Create a async channel. - let (sender, receiver) = channel(); - - // Pass the desired arguments into the Local Thread Storage. - GLOBAL.with( - clone!(download_bttn, play_bttn, cancel_bttn, progress => move |global| { - *global.borrow_mut() = Some(( - download_bttn, - play_bttn, - cancel_bttn, - progress, - receiver)); - }), - ); - let pd = dbqueries::get_podcast_from_id(ep.podcast_id()).unwrap(); let pd_title = pd.title().to_owned(); let mut ep = ep.clone(); cancel_bttn.show(); progress.show(); download_bttn.hide(); + sender.send(Action::RefreshEpisodesViewBGR); thread::spawn(move || { let download_fold = downloader::get_download_folder(&pd_title).unwrap(); let e = downloader::get_episode(&mut ep, download_fold.as_str()); @@ -251,8 +243,7 @@ fn on_download_clicked( error!("Error while trying to download: {:?}", ep.uri()); error!("Error: {}", err); }; - sender.send(true).expect("Couldn't send data to channel");; - glib::idle_add(receive); + sender.send(Action::RefreshViews); }); } @@ -309,13 +300,13 @@ fn receive() -> glib::Continue { glib::Continue(false) } -pub fn episodes_listbox(pd: &Podcast) -> Result { +pub fn episodes_listbox(pd: &Podcast, sender: Sender) -> Result { let episodes = dbqueries::get_pd_episodeswidgets(pd)?; let list = gtk::ListBox::new(); episodes.into_iter().for_each(|mut ep| { - let widget = EpisodeWidget::new(&mut ep); + let widget = EpisodeWidget::new(&mut ep, sender.clone()); list.add(&widget.container); }); diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index a7ce989..a248a02 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -82,7 +82,7 @@ impl ShowWidget { header.switch_to_normal(); })); - self.setup_listbox(pd); + self.setup_listbox(pd, sender.clone()); self.set_cover(pd); self.set_description(pd.description()); @@ -95,8 +95,8 @@ impl ShowWidget { } /// Populate the listbox with the shows episodes. - fn setup_listbox(&self, pd: &Podcast) { - let listbox = episodes_listbox(pd); + fn setup_listbox(&self, pd: &Podcast, sender: Sender) { + let listbox = episodes_listbox(pd, sender.clone()); if let Ok(l) = listbox { self.episodes.add(&l); }