diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index dfcc7db..f1450d7 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -159,6 +159,37 @@ 1 + + + False + True + + + False + + + False + True + 6 + 0 + + + + + False + Fetching new episodes + + + False + True + 1 + + + + + 3 + + True diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index cb3aa36..01725ae 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -151,7 +151,7 @@ True center center - app.update + app.refresh diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 200a016..cd953f5 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -66,8 +66,9 @@ impl App { pub fn setup_actions(&self) { let update = gio::SimpleAction::new("update", None); let content = self.content.clone(); + let header = self.header.clone(); update.connect_activate(move |_, _| { - utils::refresh_feed(content.clone(), None); + utils::refresh_feed(content.clone(), header.clone(), None); }); self.app_instance.add_action(&update); @@ -97,23 +98,25 @@ impl App { pub fn setup_timed_callbacks(&self) { let content = self.content.clone(); + let header = self.header.clone(); // Update 30 seconds after the Application is initialized. gtk::timeout_add_seconds( 30, clone!(content => move || { - utils::refresh_feed(content.clone(), None); + utils::refresh_feed(content.clone(), header.clone(), None); glib::Continue(false) }), ); let content = self.content.clone(); + let header = self.header.clone(); // Auto-updater, runs every hour. // TODO: expose the interval in which it run to a user setting. // TODO: show notifications. gtk::timeout_add_seconds( 3600, clone!(content => move || { - utils::refresh_feed(content.clone(), None); + utils::refresh_feed(content.clone(), header.clone(), None); glib::Continue(true) }), ); diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index a399182..983cb5c 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -8,7 +8,7 @@ use std::rc::Rc; use utils; use content::Content; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Header { pub container: gtk::HeaderBar, add_toggle: gtk::MenuButton, @@ -16,6 +16,9 @@ pub struct Header { switch: gtk::StackSwitcher, back_button: gtk::Button, show_title: gtk::Label, + update_box: gtk::Box, + update_label: gtk::Label, + update_spinner: gtk::Spinner, } impl Default for Header { @@ -28,6 +31,9 @@ impl Default for Header { let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); let back_button: gtk::Button = builder.get_object("back_button").unwrap(); let show_title: gtk::Label = builder.get_object("show_title").unwrap(); + let update_box: gtk::Box = builder.get_object("update_notification").unwrap(); + let update_label: gtk::Label = builder.get_object("update_label").unwrap(); + let update_spinner: gtk::Spinner = builder.get_object("update_spinner").unwrap(); Header { container: header, @@ -36,6 +42,9 @@ impl Default for Header { switch, back_button, show_title, + update_box, + update_label, + update_spinner, } } } @@ -61,8 +70,9 @@ impl Header { println!("{:?}", url.get_text()); }); - add_button.connect_clicked(clone!(content, add_popover, new_url => move |_| { - on_add_bttn_clicked(content.clone(), &new_url); + let header = Rc::new(self.clone()); + add_button.connect_clicked(clone!(content, header, add_popover, new_url => move |_| { + on_add_bttn_clicked(content.clone(), header.clone(), &new_url); // TODO: lock the button instead of hiding and add notification of feed added. // TODO: map the spinner @@ -104,16 +114,30 @@ impl Header { pub fn set_show_title(&self, title: &str) { self.show_title.set_text(title) } + + pub fn show_update_notification(&self) { + self.update_spinner.start(); + self.update_box.show(); + self.update_spinner.show(); + self.update_label.show(); + } + + pub fn hide_update_notification(&self) { + self.update_spinner.stop(); + self.update_box.hide(); + self.update_spinner.hide(); + self.update_label.hide(); + } } -fn on_add_bttn_clicked(content: Rc, entry: >k::Entry) { +fn on_add_bttn_clicked(content: Rc, headerbar: Rc
, entry: >k::Entry) { let url = entry.get_text().unwrap_or_default(); let source = Source::from_url(&url); if let Ok(s) = source { info!("{:?} feed added", url); // update the db - utils::refresh_feed(content, Some(vec![s])); + utils::refresh_feed(content, headerbar, Some(vec![s])); } else { error!("Feed probably already exists."); error!("Error: {:?}", source.unwrap_err()); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 7bb3853..26c236d 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -14,8 +14,9 @@ use std::rc::Rc; use std::collections::HashMap; use content::Content; +use headerbar::Header; -type Foo = RefCell, Receiver)>>; +type Foo = RefCell, Rc
, Receiver)>>; // Create a thread local storage that will store the arguments to be transfered. thread_local!(static GLOBAL: Foo = RefCell::new(None)); @@ -24,13 +25,15 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None)); /// 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. /// When It's done,it queues up a `podcast_view` refresh. -pub fn refresh_feed(content: Rc, source: Option>) { +pub fn refresh_feed(content: Rc, headerbar: Rc
, source: Option>) { + headerbar.show_update_notification(); + // Create a async channel. let (sender, receiver) = channel(); // Pass the desired arguments into the Local Thread Storage. - GLOBAL.with(clone!(content => move |global| { - *global.borrow_mut() = Some((content.clone(), receiver)); + GLOBAL.with(clone!(content, headerbar => move |global| { + *global.borrow_mut() = Some((content.clone(), headerbar.clone(), receiver)); })); thread::spawn(move || { @@ -51,9 +54,10 @@ pub fn refresh_feed(content: Rc, source: Option>) { fn refresh_everything() -> glib::Continue { GLOBAL.with(|global| { - if let Some((ref content, ref reciever)) = *global.borrow() { + if let Some((ref content, ref headerbar, ref reciever)) = *global.borrow() { if reciever.try_recv().is_ok() { content.update(); + headerbar.hide_update_notification(); } } });