Async update of the download and play buttons upon download finished.
This commit is contained in:
@@ -10,13 +10,22 @@ use hammond_downloader::downloader;
|
||||
use dissolve::strip_html_tags;
|
||||
|
||||
use std::thread;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::{channel, Receiver};
|
||||
use std::path::Path;
|
||||
|
||||
use glib;
|
||||
use gtk;
|
||||
use gtk::prelude::*;
|
||||
use gtk::ContainerExt;
|
||||
|
||||
thread_local!(
|
||||
static GLOBAL: RefCell<Option<((gtk::Button,
|
||||
gtk::Button,
|
||||
Receiver<bool>))>> = RefCell::new(None));
|
||||
|
||||
// TODO: REFACTOR AND MODULATE ME.
|
||||
fn epidose_widget(
|
||||
connection: Arc<Mutex<SqliteConnection>>,
|
||||
episode: &mut Episode,
|
||||
@@ -65,35 +74,67 @@ fn epidose_widget(
|
||||
}
|
||||
}
|
||||
|
||||
let pd_title_cloned = pd_title.to_owned();
|
||||
// TODO: figure out how to use the gtk-clone macro,
|
||||
// to make it less tedious.
|
||||
let pd_title_clone = pd_title.to_owned();
|
||||
let db = connection.clone();
|
||||
let ep_clone = episode.clone();
|
||||
let play_button_clone = play_button.clone();
|
||||
dl_button.connect_clicked(move |dl| {
|
||||
// ugly hack to bypass the borrowchecker
|
||||
let pd_title = pd_title_cloned.clone();
|
||||
let db_clone = db.clone();
|
||||
let mut ep_clone = ep_clone.clone();
|
||||
|
||||
// TODO: emit a signal and show notification when dl is finished and block play_bttn till
|
||||
// then.
|
||||
thread::spawn(move || {
|
||||
let dl_fold = downloader::get_dl_folder(&pd_title).unwrap();
|
||||
let tempdb = db_clone.lock().unwrap();
|
||||
let e = downloader::get_episode(&tempdb, &mut ep_clone, dl_fold.as_str());
|
||||
drop(tempdb);
|
||||
if let Err(err) = e {
|
||||
error!("Error while trying to download: {}", ep_clone.uri());
|
||||
error!("Error: {}", err);
|
||||
};
|
||||
});
|
||||
dl.hide();
|
||||
play_button_clone.show();
|
||||
let dl_button_clone = dl_button.clone();
|
||||
dl_button.connect_clicked(move |_| {
|
||||
on_dl_clicked(
|
||||
db.clone(),
|
||||
&pd_title_clone,
|
||||
&mut ep_clone.clone(),
|
||||
dl_button_clone.clone(),
|
||||
play_button_clone.clone(),
|
||||
);
|
||||
});
|
||||
|
||||
ep
|
||||
}
|
||||
|
||||
// TODO: show notification when dl is finished and block play_bttn till then.
|
||||
fn on_dl_clicked(
|
||||
db: Arc<Mutex<SqliteConnection>>,
|
||||
pd_title: &str,
|
||||
ep: &mut Episode,
|
||||
dl_bttn: gtk::Button,
|
||||
play_bttn: gtk::Button,
|
||||
) {
|
||||
// Create a async channel.
|
||||
let (sender, receiver) = channel();
|
||||
|
||||
// Pass the desired arguments into the Local Thread Storage.
|
||||
GLOBAL.with(move |global| {
|
||||
*global.borrow_mut() = Some((dl_bttn, play_bttn, receiver));
|
||||
});
|
||||
|
||||
let pd_title = pd_title.to_owned();
|
||||
let mut ep = ep.clone();
|
||||
thread::spawn(move || {
|
||||
let dl_fold = downloader::get_dl_folder(&pd_title).unwrap();
|
||||
let e = downloader::get_episode(db, &mut ep, dl_fold.as_str());
|
||||
if let Err(err) = e {
|
||||
error!("Error while trying to download: {}", ep.uri());
|
||||
error!("Error: {}", err);
|
||||
};
|
||||
sender.send(true).expect("Couldn't send data to channel");;
|
||||
glib::idle_add(receive);
|
||||
});
|
||||
}
|
||||
|
||||
fn receive() -> glib::Continue {
|
||||
GLOBAL.with(|global| {
|
||||
if let Some((ref dl_bttn, ref play_bttn, ref reciever)) = *global.borrow() {
|
||||
if reciever.try_recv().is_ok() {
|
||||
dl_bttn.hide();
|
||||
play_bttn.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
glib::Continue(false)
|
||||
}
|
||||
|
||||
pub fn episodes_listbox(connection: Arc<Mutex<SqliteConnection>>, pd_title: &str) -> gtk::ListBox {
|
||||
// TODO: handle unwraps.
|
||||
|
||||
@@ -102,10 +102,11 @@ pub fn podcast_liststore(connection: &SqliteConnection) -> gtk::ListStore {
|
||||
// &Podcast){
|
||||
// let old = stack.get_child_by_name("pdw").unwrap();
|
||||
// let pdw = pd_widget_from_diesel_model(&db.clone(), pd, &stack.clone());
|
||||
// let vis = stack.get_visible_child_name().unwrap();
|
||||
|
||||
// stack.remove(&old);
|
||||
// stack.add_named(&pdw, "pdw");
|
||||
// stack.set_visible_child_full("pdw", StackTransitionType::None);
|
||||
// stack.set_visible_child_name(&vis);
|
||||
// }
|
||||
|
||||
pub fn pd_widget_from_diesel_model(db: Arc<Mutex<SqliteConnection>>, pd: &Podcast) -> gtk::Box {
|
||||
|
||||
Reference in New Issue
Block a user