EpidoseWidget: Recalculate widget's state when cancel is clicked.
Previously we would refresh all the views when download/cancel button was clicked. This was done mainly to avoid zombie widget bugs that would arise from shared state. Now we still refresh all the background views but not the visible one. Instead the widget has the reponsibility of recalculating it's state.
This commit is contained in:
parent
67bdd3664a
commit
b86f288e86
@ -89,7 +89,6 @@ pub fn add(id: i32, directory: String, sender: Sender<Action>) -> Result<(), Err
|
||||
|
||||
DLPOOL.spawn(move || {
|
||||
if let Ok(episode) = dbqueries::get_episode_from_rowid(id) {
|
||||
let pid = episode.podcast_id();
|
||||
let id = episode.rowid();
|
||||
|
||||
if let Err(err) = get_episode(&mut episode.into(), directory.as_str(), Some(prog)) {
|
||||
@ -107,10 +106,7 @@ pub fn add(id: i32, directory: String, sender: Sender<Action>) -> Result<(), Err
|
||||
// }
|
||||
|
||||
sender
|
||||
.send(Action::RefreshEpisodesView)
|
||||
.expect("Action channel blew up.");
|
||||
sender
|
||||
.send(Action::RefreshWidgetIfSame(pid))
|
||||
.send(Action::RefreshEpisodesViewBGR)
|
||||
.expect("Action channel blew up.");
|
||||
}
|
||||
});
|
||||
|
||||
@ -119,6 +119,7 @@ impl EpisodeWidget {
|
||||
|
||||
let media_machine = self.media.clone();
|
||||
media.download_connect_clicked(clone!(media_machine, episode, sender => move |dl| {
|
||||
// Make the button insensitive so it won't be pressed twice
|
||||
dl.set_sensitive(false);
|
||||
if let Ok(ep) = episode.lock() {
|
||||
if let Err(err) = on_download_clicked(&ep, sender.clone()) {
|
||||
@ -132,6 +133,9 @@ impl EpisodeWidget {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore sensitivity after operations above complete
|
||||
dl.set_sensitive(true);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -182,7 +186,22 @@ fn determine_media_state(
|
||||
|
||||
// Show or hide the play/delete/download buttons upon widget initialization.
|
||||
if let Some(prog) = active_dl {
|
||||
lock.cancel_connect_clicked(prog.clone());
|
||||
let episode = episode.clone();
|
||||
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.lock() {
|
||||
take_mut::take(lock.deref_mut(), |media| {
|
||||
media.determine_state(
|
||||
episode.length(),
|
||||
false,
|
||||
episode.local_uri().is_some(),
|
||||
)
|
||||
});
|
||||
}
|
||||
}));
|
||||
drop(lock);
|
||||
|
||||
// Setup a callback that will update the progress bar.
|
||||
|
||||
@ -13,9 +13,7 @@ use chrono::prelude::*;
|
||||
use gtk::prelude::*;
|
||||
use humansize::{file_size_opts as size_opts, FileSize};
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use manager::Progress as OtherProgress;
|
||||
use std::sync::Arc;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref SIZE_OPTS: Arc<size_opts::FileSizeOpts> = {
|
||||
@ -501,13 +499,8 @@ impl<S> Progress<S> {
|
||||
self.bar.set_fraction(fraction);
|
||||
}
|
||||
|
||||
fn cancel_connect_clicked(&self, prog: Arc<Mutex<OtherProgress>>) -> glib::SignalHandlerId {
|
||||
self.cancel.connect_clicked(move |cancel| {
|
||||
if let Ok(mut m) = prog.lock() {
|
||||
m.cancel();
|
||||
cancel.set_sensitive(false);
|
||||
}
|
||||
})
|
||||
fn cancel_connect_clicked<F: Fn(>k::Button) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
||||
self.cancel.connect_clicked(f)
|
||||
}
|
||||
}
|
||||
|
||||
@ -634,6 +627,14 @@ impl<X, Y, Z> Media<X, Y, Z> {
|
||||
}
|
||||
}
|
||||
|
||||
fn into_new_without(self) -> New<Hidden> {
|
||||
Media {
|
||||
dl: self.dl.into_fetchable(),
|
||||
size: self.size.into_hidden(),
|
||||
progress: self.progress.into_hidden(),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_playable(self, size: &str) -> Playable<Shown> {
|
||||
Media {
|
||||
dl: self.dl.into_playable(),
|
||||
@ -641,6 +642,14 @@ impl<X, Y, Z> Media<X, Y, Z> {
|
||||
progress: self.progress.into_hidden(),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_playable_without(self) -> Playable<Hidden> {
|
||||
Media {
|
||||
dl: self.dl.into_playable(),
|
||||
size: self.size.into_hidden(),
|
||||
progress: self.progress.into_hidden(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<X, Z> Media<X, Shown, Z> {
|
||||
@ -788,14 +797,14 @@ impl ButtonsState {
|
||||
}
|
||||
}
|
||||
|
||||
fn cancel_connect_clicked(&self, prog: Arc<Mutex<OtherProgress>>) -> glib::SignalHandlerId {
|
||||
fn cancel_connect_clicked<F: Fn(>k::Button) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
||||
use self::ButtonsState::*;
|
||||
|
||||
match *self {
|
||||
New(ref val) => val.progress.cancel_connect_clicked(prog),
|
||||
NewWithoutSize(ref val) => val.progress.cancel_connect_clicked(prog),
|
||||
Playable(ref val) => val.progress.cancel_connect_clicked(prog),
|
||||
PlayableWithoutSize(ref val) => val.progress.cancel_connect_clicked(prog),
|
||||
New(ref val) => val.progress.cancel_connect_clicked(f),
|
||||
NewWithoutSize(ref val) => val.progress.cancel_connect_clicked(f),
|
||||
Playable(ref val) => val.progress.cancel_connect_clicked(f),
|
||||
PlayableWithoutSize(ref val) => val.progress.cancel_connect_clicked(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -852,13 +861,16 @@ impl MediaMachine {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cancel_connect_clicked(&self, prog: Arc<Mutex<OtherProgress>>) -> glib::SignalHandlerId {
|
||||
pub fn cancel_connect_clicked<F: Fn(>k::Button) + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> glib::SignalHandlerId {
|
||||
use self::MediaMachine::*;
|
||||
|
||||
match *self {
|
||||
UnInitialized(ref val) => val.progress.cancel_connect_clicked(prog),
|
||||
Initialized(ref val) => val.cancel_connect_clicked(prog),
|
||||
InProgress(ref val) => val.progress.cancel_connect_clicked(prog),
|
||||
UnInitialized(ref val) => val.progress.cancel_connect_clicked(f),
|
||||
Initialized(ref val) => val.cancel_connect_clicked(f),
|
||||
InProgress(ref val) => val.progress.cancel_connect_clicked(f),
|
||||
}
|
||||
}
|
||||
|
||||
@ -879,6 +891,19 @@ impl MediaMachine {
|
||||
|
||||
(Initialized(bttn), s, dl, false) => Initialized(bttn.determine_state(s, dl)),
|
||||
(Initialized(bttn), _, _, true) => InProgress(bttn.into_progress()),
|
||||
|
||||
// Into New
|
||||
(InProgress(m), Some(s), false, false) => Initialized(New(m.into_new(&s))),
|
||||
(InProgress(m), None, false, false) => {
|
||||
Initialized(NewWithoutSize(m.into_new_without()))
|
||||
}
|
||||
|
||||
// Into Playable
|
||||
(InProgress(m), Some(s), true, false) => Initialized(Playable(m.into_playable(&s))),
|
||||
(InProgress(m), None, true, false) => {
|
||||
Initialized(PlayableWithoutSize(m.into_playable_without()))
|
||||
}
|
||||
|
||||
(i @ InProgress(_), _, _, _) => i,
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user