EpisodeWidget: Handle updating states, withotu having to reload the views.
This code is ugly and terrible but it works™. Previsously when a download would finish it would refresh all the views. Now the if the widget get's into the Donwloading state, it will setup a callback that will check periodicly if it's still downloading and update the widget state when the episode stops downloading.
This commit is contained in:
parent
63e2ea987e
commit
03bd951848
@ -103,6 +103,20 @@ pub fn get_episode_from_rowid(ep_id: i32) -> Result<Episode, DataError> {
|
|||||||
.map_err(From::from)
|
.map_err(From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_episode_widget_from_rowid(ep_id: i32) -> Result<EpisodeWidgetQuery, DataError> {
|
||||||
|
use schema::episode::dsl::*;
|
||||||
|
let db = connection();
|
||||||
|
let con = db.get()?;
|
||||||
|
|
||||||
|
episode
|
||||||
|
.select((
|
||||||
|
rowid, title, uri, local_uri, epoch, length, duration, played, podcast_id,
|
||||||
|
))
|
||||||
|
.filter(rowid.eq(ep_id))
|
||||||
|
.get_result::<EpisodeWidgetQuery>(&con)
|
||||||
|
.map_err(From::from)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_episode_local_uri_from_id(ep_id: i32) -> Result<Option<String>, DataError> {
|
pub fn get_episode_local_uri_from_id(ep_id: i32) -> Result<Option<String>, DataError> {
|
||||||
use schema::episode::dsl::*;
|
use schema::episode::dsl::*;
|
||||||
let db = connection();
|
let db = connection();
|
||||||
|
|||||||
@ -5,10 +5,7 @@ use rayon;
|
|||||||
use hammond_data::dbqueries;
|
use hammond_data::dbqueries;
|
||||||
use hammond_downloader::downloader::{get_episode, DownloadProgress};
|
use hammond_downloader::downloader::{get_episode, DownloadProgress};
|
||||||
|
|
||||||
use app::Action;
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
// use std::sync::atomic::AtomicUsize;
|
// use std::sync::atomic::AtomicUsize;
|
||||||
// use std::path::PathBuf;
|
// use std::path::PathBuf;
|
||||||
@ -78,7 +75,7 @@ lazy_static! {
|
|||||||
static ref DLPOOL: rayon::ThreadPool = rayon::ThreadPoolBuilder::new().build().unwrap();
|
static ref DLPOOL: rayon::ThreadPool = rayon::ThreadPoolBuilder::new().build().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(id: i32, directory: String, sender: Sender<Action>) -> Result<(), Error> {
|
pub fn add(id: i32, directory: String) -> Result<(), Error> {
|
||||||
// Create a new `Progress` struct to keep track of dl progress.
|
// Create a new `Progress` struct to keep track of dl progress.
|
||||||
let prog = Arc::new(Mutex::new(Progress::default()));
|
let prog = Arc::new(Mutex::new(Progress::default()));
|
||||||
|
|
||||||
@ -88,11 +85,10 @@ 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(mut episode) = dbqueries::get_episode_widget_from_rowid(id) {
|
||||||
let id = episode.rowid();
|
let id = episode.rowid();
|
||||||
let pid = episode.podcast_id();
|
|
||||||
|
|
||||||
get_episode(&mut episode.into(), directory.as_str(), Some(prog))
|
get_episode(&mut episode, directory.as_str(), Some(prog))
|
||||||
.map_err(|err| error!("Download Failed: {}", err))
|
.map_err(|err| error!("Download Failed: {}", err))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
@ -104,15 +100,6 @@ pub fn add(id: i32, directory: String, sender: Sender<Action>) -> Result<(), Err
|
|||||||
// if let Ok(m) = ACTIVE_DOWNLOADS.read() {
|
// if let Ok(m) = ACTIVE_DOWNLOADS.read() {
|
||||||
// debug!("ACTIVE DOWNLOADS: {:#?}", m);
|
// debug!("ACTIVE DOWNLOADS: {:#?}", m);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
sender
|
|
||||||
.send(Action::RefreshWidgetIfSame(pid))
|
|
||||||
.map_err(|err| error!("Action Sender: {}", err))
|
|
||||||
.ok();
|
|
||||||
sender
|
|
||||||
.send(Action::RefreshEpisodesView)
|
|
||||||
.map_err(|err| error!("Action Sender: {}", err))
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -128,10 +128,10 @@ impl EpisodeWidget {
|
|||||||
.and_then(|_| {
|
.and_then(|_| {
|
||||||
info!("Donwload started succesfully.");
|
info!("Donwload started succesfully.");
|
||||||
determine_media_state(media_machine.clone(), &ep)
|
determine_media_state(media_machine.clone(), &ep)
|
||||||
})
|
})
|
||||||
.map_err(|err| error!("Error: {}", err))
|
.map_err(|err| error!("Error: {}", err))
|
||||||
.map_err(|_| error!("Could not determine Media State"))
|
.map_err(|_| error!("Could not determine Media State"))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore sensitivity after operations above complete
|
// Restore sensitivity after operations above complete
|
||||||
@ -190,20 +190,42 @@ 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 {
|
||||||
let episode = episode.clone();
|
|
||||||
|
// set a callback that will update the state when the download finishes
|
||||||
|
let id = episode.rowid();
|
||||||
|
let callback = clone!(media_machine => move || {
|
||||||
|
if let Ok(guard) = manager::ACTIVE_DOWNLOADS.read() {
|
||||||
|
if !guard.contains_key(&id) {
|
||||||
|
if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
||||||
|
determine_media_state(media_machine.clone(), &ep)
|
||||||
|
.map_err(|err| error!("Error: {}", err))
|
||||||
|
.map_err(|_| error!("Could not determine Media State"))
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
return glib::Continue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glib::Continue(true)
|
||||||
|
});
|
||||||
|
gtk::timeout_add(250, callback);
|
||||||
|
|
||||||
lock.cancel_connect_clicked(clone!(prog, media_machine => move |_| {
|
lock.cancel_connect_clicked(clone!(prog, media_machine => move |_| {
|
||||||
if let Ok(mut m) = prog.lock() {
|
if let Ok(mut m) = prog.lock() {
|
||||||
m.cancel();
|
m.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(mut lock) = media_machine.try_borrow_mut() {
|
if let Ok(mut lock) = media_machine.try_borrow_mut() {
|
||||||
take_mut::take(lock.deref_mut(), |media| {
|
if let Ok(episode) = dbqueries::get_episode_widget_from_rowid(id) {
|
||||||
media.determine_state(
|
take_mut::take(lock.deref_mut(), |media| {
|
||||||
episode.length(),
|
media.determine_state(
|
||||||
false,
|
episode.length(),
|
||||||
episode.local_uri().is_some(),
|
false,
|
||||||
)
|
episode.local_uri().is_some(),
|
||||||
});
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
drop(lock);
|
drop(lock);
|
||||||
@ -221,12 +243,15 @@ fn determine_media_state(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: Sender<Action>) -> Result<(), Error> {
|
fn on_download_clicked(
|
||||||
|
ep: &EpisodeWidgetQuery,
|
||||||
|
sender: Sender<Action>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
let pd = dbqueries::get_podcast_from_id(ep.podcast_id())?;
|
let pd = dbqueries::get_podcast_from_id(ep.podcast_id())?;
|
||||||
let download_fold = get_download_folder(&pd.title())?;
|
let download_fold = get_download_folder(&pd.title())?;
|
||||||
|
|
||||||
// Start a new download.
|
// Start a new download.
|
||||||
manager::add(ep.rowid(), download_fold, sender.clone())?;
|
manager::add(ep.rowid(), download_fold)?;
|
||||||
|
|
||||||
// Update Views
|
// Update Views
|
||||||
sender.send(Action::RefreshEpisodesViewBGR)?;
|
sender.send(Action::RefreshEpisodesViewBGR)?;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user