diff --git a/hammond-gtk/resources/gtk/inapp_notif.ui b/hammond-gtk/resources/gtk/inapp_notif.ui new file mode 100644 index 0000000..c14a5e9 --- /dev/null +++ b/hammond-gtk/resources/gtk/inapp_notif.ui @@ -0,0 +1,77 @@ + + + + + + True + False + center + start + + + True + False + + + True + False + center + center + 0 + none + + + True + False + center + center + 6 + 6 + 12 + + + True + False + center + center + An in-app action notification + + + False + False + 0 + + + + + Undo + True + True + True + center + center + + + False + False + end + 1 + + + + + + + + + + + + + -1 + + + + diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index 5bd1c86..2b54c11 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -68,250 +68,167 @@ Tobias Bernard - + + 600 True False + 32 + 32 + 32 + 32 + False + vertical + 24 - 600 True False - 32 - 32 - 32 - 32 - False - vertical - 24 + center + 12 + + + True + False + 128 + image-x-generic-symbolic + + + False + False + 0 + + True False - center - 12 - - + end + True + vertical + 6 + + True False - 128 - image-x-generic-symbolic + start + end + Show description + True + word-char + 100 + + + False False - 0 + 1 True False - end - True - vertical 6 - - + + True - False - start - end - Show description - True - word-char - 100 - - - + True + True + + + True + False + center + center + emblem-system-symbolic + + False - False + True + 0 + + + + + Website + True + True + True + center + center + + + False + True + 5 1 - + + Unsubscribe True - False - 6 - - - True - True - True - - - True - False - center - center - emblem-system-symbolic - - - - - False - True - 0 - - - - - Website - True - True - True - center - center - - - False - True - 5 - 1 - - - - - Unsubscribe - True - True - True - center - center - - - - False - True - 5 - end - 2 - - + True + True + center + center + False - False + True + 5 end - 0 + 2 False - True - 1 + False + end + 0 False - False + True 1 - - - True - False - True - 0 - in - - - - - - - - - False - False - 2 - - - -1 + False + False + 1 - - + + True False - center - start + True + 0 + in - - True - False - - - True - False - center - center - 0 - none - - - True - False - center - center - 6 - 6 - 12 - - - True - False - center - center - An in-app action notification - - - False - False - 0 - - - - - Undo - True - True - True - center - center - - - False - False - end - 1 - - - - - - - - - - - - - -1 - + + + + + + False + False + 2 + diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 7f47456..215ecf9 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -39,6 +39,7 @@ pub enum Action { pub struct App { app_instance: gtk::Application, window: gtk::Window, + overlay: gtk::Overlay, header: Arc
, content: Arc, receiver: Receiver, @@ -73,12 +74,17 @@ impl App { // Create the headerbar let header = Arc::new(Header::new(&content, &window, sender.clone())); - // Add the content main stack to the window. - window.add(&content.get_stack()); + // Add the content main stack to the overlay. + let overlay = gtk::Overlay::new(); + overlay.add(&content.get_stack()); + + // Add the overlay to the main window + window.add(&overlay); App { app_instance: application, window, + overlay, header, content, receiver, diff --git a/hammond-gtk/src/appnotif.rs b/hammond-gtk/src/appnotif.rs new file mode 100644 index 0000000..593688c --- /dev/null +++ b/hammond-gtk/src/appnotif.rs @@ -0,0 +1,68 @@ +use glib; +use gtk; +use gtk::prelude::*; + +use app::Action; + +use std::cell::RefCell; +use std::rc::Rc; +use std::sync::mpsc::Sender; + +#[derive(Debug, Clone)] +pub struct InAppNotification { + revealer: gtk::Revealer, + text: gtk::Label, + undo: gtk::Button, +} + +impl Default for InAppNotification { + fn default() -> Self { + let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/inappp_notif.ui"); + + let revealer: gtk::Revealer = builder.get_object("notif_revealer").unwrap(); + let text: gtk::Label = builder.get_object("notif_label").unwrap(); + let undo: gtk::Button = builder.get_object("undo_button").unwrap(); + + InAppNotification { + revealer, + text, + undo, + } + } +} + +impl InAppNotification { + pub fn new(text: &str, callback: F, sender: Sender) -> Self + where + F: FnMut() -> Continue + 'static, + { + let notif = InAppNotification::default(); + + notif.text.set_text(text); + notif.revealer.set_reveal_child(true); + + let id = timeout_add_seconds(10, callback); + let id = Rc::new(RefCell::new(Some(id))); + + // Cancel the callback + let revealer = notif.revealer.clone(); + notif.undo.connect_clicked(move |_| { + let foo = id.borrow_mut().take(); + if let Some(id) = foo { + glib::source::source_remove(id); + } + + // Hide the notification + revealer.set_reveal_child(false); + // Refresh the widget if visible + if let Err(err) = sender.send(Action::RefreshWidgetIfVis) { + error!( + "Something went horribly wrong with the Action channel: {}", + err + ) + } + }); + + notif + } +} diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index fa09b19..013fcdc 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -65,6 +65,7 @@ pub mod app; pub mod utils; pub mod manager; pub mod static_resource; +pub mod appnotif; use app::App; diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 1d7597c..118d830 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -10,11 +10,10 @@ use hammond_data::dbqueries; use hammond_data::utils::{delete_show, replace_extra_spaces}; use app::Action; +use appnotif::InAppNotification; use utils::get_pixbuf_from_path; use widgets::episode::episodes_listbox; -use std::cell::RefCell; -use std::rc::Rc; use std::sync::Arc; use std::sync::mpsc::Sender; use std::thread; @@ -29,9 +28,6 @@ pub struct ShowWidget { settings: gtk::MenuButton, unsub: gtk::Button, episodes: gtk::Frame, - notif: gtk::Revealer, - notif_label: gtk::Label, - notif_undo: gtk::Button, } impl Default for ShowWidget { @@ -47,10 +43,6 @@ impl Default for ShowWidget { let link: gtk::Button = builder.get_object("link_button").unwrap(); let settings: gtk::MenuButton = builder.get_object("settings_button").unwrap(); - let notif: gtk::Revealer = builder.get_object("notif_revealer").unwrap(); - let notif_label: gtk::Label = builder.get_object("notif_label").unwrap(); - let notif_undo: gtk::Button = builder.get_object("undo_button").unwrap(); - ShowWidget { container, scrolled_window, @@ -60,9 +52,6 @@ impl Default for ShowWidget { link, settings, episodes, - notif, - notif_label, - notif_undo, } } } @@ -107,16 +96,10 @@ impl ShowWidget { let show_menu: gtk::Popover = builder.get_object("show_menu").unwrap(); let mark_all: gtk::ModelButton = builder.get_object("mark_all_watched").unwrap(); - let notif = self.notif.clone(); - let notif_label = self.notif_label.clone(); - let notif_undo = self.notif_undo.clone(); let episodes = self.episodes.clone(); mark_all.connect_clicked(clone!(pd, sender => move |_| { on_played_button_clicked( pd.clone(), - ¬if, - ¬if_label, - ¬if_undo, &episodes, sender.clone() ) @@ -176,21 +159,13 @@ fn on_unsub_button_clicked( Ok(()) } -fn on_played_button_clicked( - pd: Arc, - notif: >k::Revealer, - label: >k::Label, - undo: >k::Button, - episodes: >k::Frame, - sender: Sender, -) { +fn on_played_button_clicked(pd: Arc, episodes: >k::Frame, sender: Sender) { if dim_titles(episodes).is_none() { error!("Something went horribly wrong when dimming the titles."); warn!("RUN WHILE YOU STILL CAN!"); } - label.set_text("All episodes where marked as watched."); - notif.set_reveal_child(true); + let text = "All episodes where marked as watched."; // Set up the callback let callback = clone!(sender => move || { @@ -199,23 +174,7 @@ fn on_played_button_clicked( } glib::Continue(false) }); - let id = timeout_add_seconds(10, callback); - let id = Rc::new(RefCell::new(Some(id))); - - // Cancel the callback - undo.connect_clicked(clone!(id, notif, sender => move |_| { - let foo = id.borrow_mut().take(); - if let Some(id) = foo { - glib::source::source_remove(id); - } - - // Hide the notification - notif.set_reveal_child(false); - // Refresh the widget if visible - if let Err(err) = sender.send(Action::RefreshWidgetIfVis) { - error!("Something went horribly wrong with the Action channel: {}", err) - } - })); + let _notif = InAppNotification::new(text, callback, sender); } fn wrap(pd: &Podcast, sender: Sender) -> Result<(), Error> {