diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 598d694..dd5bd8c 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -37,11 +37,14 @@ pub fn get_headerbar(db: Arc>, stack: gtk::Stack) -> gtk let url = new_url.get_text().unwrap_or_default(); // TODO: check if the feed is already present. let f = index_feed::insert_return_source(&tempdb, &url); + drop(tempdb); info!("{:?} feed added", url); + + let stack_clone = stack_clone.clone(); if let Ok(mut source) = f { // update the db - utils::refresh_feed(db_clone.clone(), &stack_clone, &mut source); + utils::refresh_feed(db_clone.clone(), stack_clone, &mut source); } else { error!("Expected Error, feed probably already exists."); error!("Error: {:?}", f.unwrap_err()); diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 6cedd2b..742cf9c 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -55,9 +55,9 @@ fn build_ui(app: >k::Application) { }); // Get the headerbar - let header = headerbar::get_headerbar(db, stack); - // Uncomment this when etag implementation is fixed and refesh_db thread is non blocking. - // utils::refresh_db(&db, &stack); + let header = headerbar::get_headerbar(db.clone(), stack.clone()); + // TODO: add delay, cause else theres lock contention for the db obj. + // utils::refresh_db(db.clone(), stack.clone()); window.set_titlebar(&header); window.show_all(); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index cf3c7dc..8b86db8 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -18,20 +18,24 @@ use std::sync::mpsc::{channel, Receiver}; use views::podcasts_view; +// Create a thread local storage that will store the arguments to be transfered. thread_local!( static GLOBAL: RefCell>, gtk::Stack, Receiver)>> = RefCell::new(None)); pub fn refresh_db(db: Arc>, stack: gtk::Stack) { + // Create a async channel. let (sender, receiver) = channel(); let db_clone = db.clone(); + // Pass the desired arguments into the Local Thread Storage. GLOBAL.with(move |global| { *global.borrow_mut() = Some((db_clone, stack, receiver)); }); // The implementation of how this is done is probably terrible but it works!. + // TODO: add timeout option and error reporting. let db_clone = db.clone(); thread::spawn(move || { let t = hammond_data::index_feed::index_loop(db_clone, false); @@ -41,15 +45,23 @@ pub fn refresh_db(db: Arc>, stack: gtk::Stack) { }; sender.send(true).expect("Couldn't send data to channel");; - glib::idle_add(receive); + // http://gtk-rs.org/docs/glib/source/fn.idle_add.html + glib::idle_add(refresh_podcasts_view); }); } -pub fn refresh_feed(db: Arc>, stack: >k::Stack, source: &mut Source) { +pub fn refresh_feed(db: Arc>, stack: gtk::Stack, source: &mut Source) { + let (sender, receiver) = channel(); + + let db_clone = db.clone(); + GLOBAL.with(move |global| { + *global.borrow_mut() = Some((db_clone, stack, receiver)); + }); + let db_clone = db.clone(); let mut source_ = source.clone(); // TODO: add timeout option and error reporting. - let handle = thread::spawn(move || { + thread::spawn(move || { let db_ = db_clone.clone(); let db_ = db_.lock().unwrap(); let foo_ = hammond_data::index_feed::refresh_source(&db_, &mut source_, false); @@ -62,39 +74,17 @@ pub fn refresh_feed(db: Arc>, stack: >k::Stack, source error!("Error While trying to update the database."); error!("Error msg: {}", s.unwrap_err()); }; + + sender.send(true).expect("Couldn't send data to channel");; + glib::idle_add(refresh_podcasts_view); }; }); - // FIXME: atm freezing the ui till update is done. - // Make it instead emmit a signal on update completion. - // TODO: emit a signal in order to update the podcast widget. - let _ = handle.join(); - podcasts_view::update_podcasts_view(db, stack); } -// https://github. -// com/needle-and-thread/vocal/blob/8b21f1c18c2be32921e84e289576a659ab3c8f2e/src/Utils/Utils. -// vala#L136 -// TODO: -// pub fn html_to_markup(s: String) -> String { -// let markup = glib::uri_escape_string(s.as_str(), None, true); - -// let markup = if let Some(m) = markup { -// m -// } else { -// warn!("unable to unescape markup: {}", s); -// s -// }; -// // let markup = s; - - -// info!("{}", markup); -// markup -// } - -fn receive() -> glib::Continue { +fn refresh_podcasts_view() -> glib::Continue { GLOBAL.with(|global| { if let Some((ref db, ref stack, ref reciever)) = *global.borrow() { - if let Ok(_) = reciever.try_recv() { + if reciever.try_recv().is_ok() { podcasts_view::update_podcasts_view(db.clone(), stack); } } diff --git a/hammond-gtk/src/views/podcasts_view.rs b/hammond-gtk/src/views/podcasts_view.rs index 30d823b..b4c41da 100644 --- a/hammond-gtk/src/views/podcasts_view.rs +++ b/hammond-gtk/src/views/podcasts_view.rs @@ -2,7 +2,6 @@ use gtk; use gtk::prelude::*; -use gtk::StackTransitionType; use diesel::prelude::SqliteConnection; @@ -107,7 +106,10 @@ pub fn update_podcasts_view(db: Arc>, stack: >k::Stack populate_podcasts_flowbox(db, stack, &flowbox); let old = stack.get_child_by_name("pd_grid").unwrap(); + let vis = stack.get_visible_child_name().unwrap(); + stack.remove(&old); stack.add_named(&grid, "pd_grid"); - stack.set_visible_child_full("pd_grid", StackTransitionType::None); + // preserve the visible widget + stack.set_visible_child_name(&vis); } diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index b53bd0a..2eb1bb2 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -7,9 +7,6 @@ use diesel::prelude::SqliteConnection; use hammond_data::dbqueries; use hammond_data::models::Episode; use hammond_downloader::downloader; -// use html5ever::parse_document; -// use html5ever::rcdom::RcDom; -// use tendril::stream::TendrilSink; use dissolve::strip_html_tags; use std::thread; @@ -20,8 +17,6 @@ use gtk; use gtk::prelude::*; use gtk::ContainerExt; -// use utils; - fn epidose_widget( connection: Arc>, episode: &mut Episode, @@ -47,8 +42,6 @@ fn epidose_widget( } if episode.description().is_some() { - // let mk = utils::html_to_markup(d.to_string()); - // desc_label.set_markup(mk.as_str()); let d = episode.description().unwrap().to_owned(); expander.connect_activate(move |_| {