hammond_gtk: Refactor refresh_feed func to use the Application channel.

This commit is contained in:
Jordan Petridis 2018-01-04 16:05:42 +02:00
parent 67bc3e5225
commit f30c645596
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
2 changed files with 32 additions and 30 deletions

View File

@ -12,7 +12,7 @@ use content::Content;
use utils; use utils;
use std::rc::Rc; use std::rc::Rc;
use std::sync::mpsc::{channel, Receiver}; use std::sync::mpsc::{channel, Receiver, Sender};
use std::time::Duration; use std::time::Duration;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -31,6 +31,7 @@ pub struct App {
header: Rc<Header>, header: Rc<Header>,
content: Rc<Content>, content: Rc<Content>,
receiver: Receiver<Action>, receiver: Receiver<Action>,
sender: Sender<Action>,
} }
impl App { impl App {
@ -59,7 +60,7 @@ impl App {
let content = Content::new(sender.clone()); let content = Content::new(sender.clone());
// Create the headerbar // Create the headerbar
let header = Header::new(content.clone(), sender); let header = Header::new(content.clone(), sender.clone());
// Add the Headerbar to the window. // Add the Headerbar to the window.
window.set_titlebar(&header.container); window.set_titlebar(&header.container);
@ -72,44 +73,39 @@ impl App {
header, header,
content, content,
receiver, receiver,
sender,
} }
} }
pub fn setup_actions(&self) { pub fn setup_actions(&self) {
// Updates the database and refreshes every view. // Updates the database and refreshes every view.
let update = gio::SimpleAction::new("update", None); let update = gio::SimpleAction::new("update", None);
let content = self.content.clone();
let header = self.header.clone(); let header = self.header.clone();
let sender = self.sender.clone();
update.connect_activate(move |_, _| { update.connect_activate(move |_, _| {
utils::refresh_feed(content.clone(), header.clone(), None); utils::refresh_feed(header.clone(), None, sender.clone());
}); });
self.app_instance.add_action(&update); self.app_instance.add_action(&update);
} }
pub fn setup_timed_callbacks(&self) { pub fn setup_timed_callbacks(&self) {
let content = self.content.clone();
let header = self.header.clone(); let header = self.header.clone();
let sender = self.sender.clone();
// Update the feeds right after the Application is initialized. // Update the feeds right after the Application is initialized.
gtk::timeout_add_seconds( gtk::timeout_add_seconds(2, move || {
2, utils::refresh_feed(header.clone(), None, sender.clone());
clone!(content => move || {
utils::refresh_feed(content.clone(), header.clone(), None);
glib::Continue(false) glib::Continue(false)
}), });
);
let content = self.content.clone();
let header = self.header.clone(); let header = self.header.clone();
let sender = self.sender.clone();
// Auto-updater, runs every hour. // Auto-updater, runs every hour.
// TODO: expose the interval in which it run to a user setting. // TODO: expose the interval in which it run to a user setting.
// TODO: show notifications. // TODO: show notifications.
gtk::timeout_add_seconds( gtk::timeout_add_seconds(3600, move || {
3600, utils::refresh_feed(header.clone(), None, sender.clone());
clone!(content => move || {
utils::refresh_feed(content.clone(), header.clone(), None);
glib::Continue(true) glib::Continue(true)
}), });
);
// Run a database checkup once the application is initialized. // Run a database checkup once the application is initialized.
gtk::timeout_add(300, || { gtk::timeout_add(300, || {
@ -130,11 +126,12 @@ impl App {
let receiver = self.receiver; let receiver = self.receiver;
let content = self.content.clone(); let content = self.content.clone();
let headerbar = self.header.clone(); let headerbar = self.header.clone();
let sender = self.sender.clone();
gtk::idle_add(clone!(content, headerbar => move || { gtk::idle_add(clone!(content, headerbar => move || {
match receiver.recv_timeout(Duration::from_millis(5)) { match receiver.recv_timeout(Duration::from_millis(5)) {
Ok(Action::UpdateSources(source)) => { Ok(Action::UpdateSources(source)) => {
if let Some(s) = source { if let Some(s) = source {
utils::refresh_feed(content.clone(), headerbar.clone(), Some(vec!(s))) utils::refresh_feed(headerbar.clone(), Some(vec!(s)), sender.clone())
} }
} }
Ok(Action::RefreshViews) => { Ok(Action::RefreshViews) => {

View File

@ -8,15 +8,15 @@ use hammond_downloader::downloader;
use std::thread; use std::thread;
use std::cell::RefCell; use std::cell::RefCell;
use std::sync::mpsc::{channel, Receiver}; use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::Mutex; use std::sync::Mutex;
use std::rc::Rc; use std::rc::Rc;
use std::collections::HashMap; use std::collections::HashMap;
use content::Content;
use headerbar::Header; use headerbar::Header;
use app::Action;
type Foo = RefCell<Option<(Rc<Content>, Rc<Header>, Receiver<bool>)>>; type Foo = RefCell<Option<(Rc<Header>, Receiver<bool>)>>;
// Create a thread local storage that will store the arguments to be transfered. // Create a thread local storage that will store the arguments to be transfered.
thread_local!(static GLOBAL: Foo = RefCell::new(None)); thread_local!(static GLOBAL: Foo = RefCell::new(None));
@ -25,15 +25,19 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None));
/// If `source` is None, Fetches all the `Source` entries in the database and updates them. /// If `source` is None, Fetches all the `Source` entries in the database and updates them.
/// `delay` represents the desired time in seconds for the thread to sleep before executing. /// `delay` represents the desired time in seconds for the thread to sleep before executing.
/// When It's done,it queues up a `podcast_view` refresh. /// When It's done,it queues up a `podcast_view` refresh.
pub fn refresh_feed(content: Rc<Content>, headerbar: Rc<Header>, source: Option<Vec<Source>>) { pub fn refresh_feed(
headerbar: Rc<Header>,
source: Option<Vec<Source>>,
app_sender: Sender<Action>,
) {
headerbar.show_update_notification(); headerbar.show_update_notification();
// Create a async channel. // Create a async channel.
let (sender, receiver) = channel(); let (sender, receiver) = channel();
// Pass the desired arguments into the Local Thread Storage. // Pass the desired arguments into the Local Thread Storage.
GLOBAL.with(clone!(content, headerbar => move |global| { GLOBAL.with(clone!(headerbar => move |global| {
*global.borrow_mut() = Some((content.clone(), headerbar.clone(), receiver)); *global.borrow_mut() = Some((headerbar.clone(), receiver));
})); }));
thread::spawn(move || { thread::spawn(move || {
@ -47,16 +51,17 @@ pub fn refresh_feed(content: Rc<Content>, headerbar: Rc<Header>, source: Option<
}; };
}; };
sender.send(true).expect("Couldn't send data to channel");; app_sender.send(Action::RefreshViews).unwrap();
glib::idle_add(refresh_everything);
let _ = sender.send(true);
glib::idle_add(hide_update_indicator);
}); });
} }
fn refresh_everything() -> glib::Continue { fn hide_update_indicator() -> glib::Continue {
GLOBAL.with(|global| { GLOBAL.with(|global| {
if let Some((ref content, ref headerbar, ref reciever)) = *global.borrow() { if let Some((ref headerbar, ref reciever)) = *global.borrow() {
if reciever.try_recv().is_ok() { if reciever.try_recv().is_ok() {
content.update();
headerbar.hide_update_notification(); headerbar.hide_update_notification();
} }
} }