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)
|
||||
}
|
||||
|
||||
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> {
|
||||
use schema::episode::dsl::*;
|
||||
let db = connection();
|
||||
|
||||
@ -5,10 +5,7 @@ use rayon;
|
||||
use hammond_data::dbqueries;
|
||||
use hammond_downloader::downloader::{get_episode, DownloadProgress};
|
||||
|
||||
use app::Action;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
// use std::sync::atomic::AtomicUsize;
|
||||
// use std::path::PathBuf;
|
||||
@ -78,7 +75,7 @@ lazy_static! {
|
||||
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.
|
||||
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 || {
|
||||
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 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))
|
||||
.ok();
|
||||
|
||||
@ -104,15 +100,6 @@ pub fn add(id: i32, directory: String, sender: Sender<Action>) -> Result<(), Err
|
||||
// if let Ok(m) = ACTIVE_DOWNLOADS.read() {
|
||||
// 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();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -190,13 +190,34 @@ fn determine_media_state(
|
||||
|
||||
// Show or hide the play/delete/download buttons upon widget initialization.
|
||||
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 |_| {
|
||||
if let Ok(mut m) = prog.lock() {
|
||||
m.cancel();
|
||||
}
|
||||
|
||||
if let Ok(mut lock) = media_machine.try_borrow_mut() {
|
||||
if let Ok(episode) = dbqueries::get_episode_widget_from_rowid(id) {
|
||||
take_mut::take(lock.deref_mut(), |media| {
|
||||
media.determine_state(
|
||||
episode.length(),
|
||||
@ -205,6 +226,7 @@ fn determine_media_state(
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
}));
|
||||
drop(lock);
|
||||
|
||||
@ -221,12 +243,15 @@ fn determine_media_state(
|
||||
}
|
||||
|
||||
#[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 download_fold = get_download_folder(&pd.title())?;
|
||||
|
||||
// Start a new download.
|
||||
manager::add(ep.rowid(), download_fold, sender.clone())?;
|
||||
manager::add(ep.rowid(), download_fold)?;
|
||||
|
||||
// Update Views
|
||||
sender.send(Action::RefreshEpisodesViewBGR)?;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user