From 0cd678cc1d685bbf28bec58e4bda7ba2389fa916 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 16 Feb 2018 17:18:02 +0200 Subject: [PATCH] MediaMachine: Expose an interface to update total_size label. --- hammond-gtk/src/widgets/episode.rs | 29 +++++----- hammond-gtk/src/widgets/episode_states.rs | 66 ++++++++++++++++------- 2 files changed, 63 insertions(+), 32 deletions(-) diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 4794a28..e745b01 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -49,7 +49,6 @@ pub struct EpisodeWidget { title: Arc>, duration: Arc>, progress: gtk::ProgressBar, - total_size: gtk::Label, local_size: gtk::Label, media: Arc>, } @@ -83,7 +82,7 @@ impl Default for EpisodeWidget { download, progress.clone(), cancel, - total_size.clone(), + total_size, local_size.clone(), separator2, prog_separator, @@ -93,7 +92,6 @@ impl Default for EpisodeWidget { EpisodeWidget { container, progress, - total_size, local_size, title: title_machine, duration: duration_machine, @@ -216,9 +214,9 @@ impl EpisodeWidget { }); // Show or hide the play/delete/download buttons upon widget initialization. + // FIXME: There might be a deadlock introduced here, but I am too tired to test it. if let Some(prog) = active_dl { let progress_bar = self.progress.clone(); - let total_size = self.total_size.clone(); let local_size = self.local_size.clone(); // Setup a callback that will update the progress bar. @@ -227,7 +225,7 @@ impl EpisodeWidget { // Setup a callback that will update the total_size label // with the http ContentLength header number rather than // relying to the RSS feed. - update_total_size_callback(prog.clone(), &total_size); + update_total_size_callback(prog.clone(), self.media.clone()); lock.cancel_connect_clicked(prog); } @@ -350,11 +348,14 @@ fn progress_bar_helper( // with the http ContentLength header number rather than // relying to the RSS feed. #[inline] -fn update_total_size_callback(prog: Arc>, total_size: >k::Label) { +fn update_total_size_callback( + prog: Arc>, + media: Arc>, +) { timeout_add( 500, - clone!(prog, total_size => move || { - total_size_helper(prog.clone(), &total_size).unwrap_or(glib::Continue(true)) + clone!(prog, media => move || { + total_size_helper(prog.clone(), media.clone()).unwrap_or(glib::Continue(true)) }), ); } @@ -362,7 +363,7 @@ fn update_total_size_callback(prog: Arc>, total_size: & #[inline] fn total_size_helper( prog: Arc>, - total_size: >k::Label, + media: Arc>, ) -> Result { // Get the total_bytes. let total_bytes = { @@ -374,10 +375,12 @@ fn total_size_helper( debug!("Total Size: {}", total_bytes); if total_bytes != 0 { // Update the total_size label - total_bytes - .file_size(SIZE_OPTS.clone()) - .map_err(|err| format_err!("{}", err)) - .map(|x| total_size.set_text(&x))?; + if let Ok(mut m) = media.lock() { + take_mut::take(m.deref_mut(), |machine| { + machine.set_size(Some(total_bytes as i32)) + }); + } + // Do not call again the callback Ok(glib::Continue(false)) } else { diff --git a/hammond-gtk/src/widgets/episode_states.rs b/hammond-gtk/src/widgets/episode_states.rs index 5d3184e..eeb6283 100644 --- a/hammond-gtk/src/widgets/episode_states.rs +++ b/hammond-gtk/src/widgets/episode_states.rs @@ -9,6 +9,7 @@ use chrono; use glib; use gtk; use gtk::prelude::*; +use humansize::FileSize; use std::sync::{Arc, Mutex}; @@ -534,13 +535,13 @@ impl From for Playable { } impl Media { - // fn set_size(self, s: &str) -> Media { - // Media { - // dl: self.dl, - // size: self.size.set_size(s), - // progress: self.progress, - // } - // } + fn set_size(self, s: &str) -> Media { + Media { + dl: self.dl, + size: self.size.set_size(s), + progress: self.progress, + } + } fn hide_size(self) -> Media { Media { @@ -649,7 +650,7 @@ impl ButtonsState { } } - pub fn into_progress(self) -> InProgress { + fn into_progress(self) -> InProgress { use self::ButtonsState::*; match self { @@ -660,6 +661,21 @@ impl ButtonsState { } } + fn set_size(self, size: Option) -> Self { + use self::ButtonsState::*; + + match (self, size) { + (New(m), Some(s)) => New(m.set_size(&s)), + (New(m), None) => NewWithoutSize(m.hide_size()), + (Playable(m), Some(s)) => Playable(m.set_size(&s)), + (Playable(m), None) => PlayableWithoutSize(m.hide_size()), + (bttn @ NewWithoutSize(_), None) => bttn, + (bttn @ PlayableWithoutSize(_), None) => bttn, + (NewWithoutSize(m), Some(s)) => New(m.into_new(&s)), + (PlayableWithoutSize(m), Some(s)) => Playable(m.into_playable(&s)), + } + } + pub fn download_connect_clicked( &self, f: F, @@ -764,18 +780,8 @@ impl MediaMachine { pub fn determine_state(self, bytes: Option, is_active: bool, is_downloaded: bool) -> Self { use self::ButtonsState::*; use self::MediaMachine::*; - use humansize::FileSize; - let size_helper = || -> Option { - let s = bytes?; - if s == 0 { - return None; - } - - s.file_size(SIZE_OPTS.clone()).ok() - }; - - match (self, size_helper(), is_downloaded, is_active) { + match (self, size_helper(bytes), is_downloaded, is_active) { (UnInitialized(m), s, _, true) => InProgress(m.into_progress(s)), // Into New @@ -791,4 +797,26 @@ impl MediaMachine { (i @ InProgress(_), _, _, _) => i, } } + + pub fn set_size(self, bytes: Option) -> Self { + use self::MediaMachine::*; + let size = size_helper(bytes); + + match (self, size) { + (Initialized(bttn), s) => Initialized(bttn.set_size(s)), + (InProgress(val), Some(s)) => InProgress(val.set_size(&s)), + (n @ InProgress(_), None) => n, + (n @ UnInitialized(_), _) => n, + } + } +} + +#[inline] +fn size_helper(bytes: Option) -> Option { + let s = bytes?; + if s == 0 { + return None; + } + + s.file_size(SIZE_OPTS.clone()).ok() }