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 || {
|
DLPOOL.spawn(move || {
|
||||||
if let Ok(episode) = dbqueries::get_episode_from_rowid(id) {
|
if let Ok(episode) = dbqueries::get_episode_from_rowid(id) {
|
||||||
let pid = episode.podcast_id();
|
|
||||||
let id = episode.rowid();
|
let id = episode.rowid();
|
||||||
|
|
||||||
if let Err(err) = get_episode(&mut episode.into(), directory.as_str(), Some(prog)) {
|
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
|
sender
|
||||||
.send(Action::RefreshEpisodesView)
|
.send(Action::RefreshEpisodesViewBGR)
|
||||||
.expect("Action channel blew up.");
|
|
||||||
sender
|
|
||||||
.send(Action::RefreshWidgetIfSame(pid))
|
|
||||||
.expect("Action channel blew up.");
|
.expect("Action channel blew up.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -119,6 +119,7 @@ impl EpisodeWidget {
|
|||||||
|
|
||||||
let media_machine = self.media.clone();
|
let media_machine = self.media.clone();
|
||||||
media.download_connect_clicked(clone!(media_machine, episode, sender => move |dl| {
|
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);
|
dl.set_sensitive(false);
|
||||||
if let Ok(ep) = episode.lock() {
|
if let Ok(ep) = episode.lock() {
|
||||||
if let Err(err) = on_download_clicked(&ep, sender.clone()) {
|
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.
|
// Show or hide the play/delete/download buttons upon widget initialization.
|
||||||
if let Some(prog) = active_dl {
|
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);
|
drop(lock);
|
||||||
|
|
||||||
// Setup a callback that will update the progress bar.
|
// Setup a callback that will update the progress bar.
|
||||||
|
|||||||
@ -13,9 +13,7 @@ use chrono::prelude::*;
|
|||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use humansize::{file_size_opts as size_opts, FileSize};
|
use humansize::{file_size_opts as size_opts, FileSize};
|
||||||
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use manager::Progress as OtherProgress;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref SIZE_OPTS: Arc<size_opts::FileSizeOpts> = {
|
pub static ref SIZE_OPTS: Arc<size_opts::FileSizeOpts> = {
|
||||||
@ -501,13 +499,8 @@ impl<S> Progress<S> {
|
|||||||
self.bar.set_fraction(fraction);
|
self.bar.set_fraction(fraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
self.cancel.connect_clicked(move |cancel| {
|
self.cancel.connect_clicked(f)
|
||||||
if let Ok(mut m) = prog.lock() {
|
|
||||||
m.cancel();
|
|
||||||
cancel.set_sensitive(false);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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> {
|
fn into_playable(self, size: &str) -> Playable<Shown> {
|
||||||
Media {
|
Media {
|
||||||
dl: self.dl.into_playable(),
|
dl: self.dl.into_playable(),
|
||||||
@ -641,6 +642,14 @@ impl<X, Y, Z> Media<X, Y, Z> {
|
|||||||
progress: self.progress.into_hidden(),
|
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> {
|
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::*;
|
use self::ButtonsState::*;
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
New(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(prog),
|
NewWithoutSize(ref val) => val.progress.cancel_connect_clicked(f),
|
||||||
Playable(ref val) => val.progress.cancel_connect_clicked(prog),
|
Playable(ref val) => val.progress.cancel_connect_clicked(f),
|
||||||
PlayableWithoutSize(ref val) => val.progress.cancel_connect_clicked(prog),
|
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::*;
|
use self::MediaMachine::*;
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
UnInitialized(ref val) => val.progress.cancel_connect_clicked(prog),
|
UnInitialized(ref val) => val.progress.cancel_connect_clicked(f),
|
||||||
Initialized(ref val) => val.cancel_connect_clicked(prog),
|
Initialized(ref val) => val.cancel_connect_clicked(f),
|
||||||
InProgress(ref val) => val.progress.cancel_connect_clicked(prog),
|
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), s, dl, false) => Initialized(bttn.determine_state(s, dl)),
|
||||||
(Initialized(bttn), _, _, true) => InProgress(bttn.into_progress()),
|
(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,
|
(i @ InProgress(_), _, _, _) => i,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user