Async update refinements, Stack transition refinements.

This commit is contained in:
Jordan Petridis 2017-10-21 23:27:53 +03:00
parent 2077215491
commit 28a10ac462
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
5 changed files with 31 additions and 43 deletions

View File

@ -37,11 +37,14 @@ pub fn get_headerbar(db: Arc<Mutex<SqliteConnection>>, 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());

View File

@ -55,9 +55,9 @@ fn build_ui(app: &gtk::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();

View File

@ -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<Option<(Arc<Mutex<SqliteConnection>>,
gtk::Stack,
Receiver<bool>)>> = RefCell::new(None));
pub fn refresh_db(db: Arc<Mutex<SqliteConnection>>, 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<Mutex<SqliteConnection>>, 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<Mutex<SqliteConnection>>, stack: &gtk::Stack, source: &mut Source) {
pub fn refresh_feed(db: Arc<Mutex<SqliteConnection>>, 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<Mutex<SqliteConnection>>, stack: &gtk::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);
}
}

View File

@ -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<Mutex<SqliteConnection>>, stack: &gtk::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);
}

View File

@ -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<Mutex<SqliteConnection>>,
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 |_| {