diff --git a/src/app/browser/window/tab/item/page.rs b/src/app/browser/window/tab/item/page.rs index c2b2e29a..aee25c3e 100644 --- a/src/app/browser/window/tab/item/page.rs +++ b/src/app/browser/window/tab/item/page.rs @@ -76,10 +76,7 @@ impl Page { /// Toggle bookmark for current navigation request pub fn bookmark(&self) { - self.profile - .bookmark - .toggle(&self.navigation.request(), Some(&self.title())) - .unwrap(); // @TODO + self.navigation.bookmark(Some(&self.title())) } /// Request `Escape` action for all page components diff --git a/src/app/browser/window/tab/item/page/navigation.rs b/src/app/browser/window/tab/item/page/navigation.rs index d3355186..d8ebd894 100644 --- a/src/app/browser/window/tab/item/page/navigation.rs +++ b/src/app/browser/window/tab/item/page/navigation.rs @@ -25,6 +25,7 @@ const SPACING: i32 = 6; pub struct Navigation { request: Rc, + bookmark: Rc, pub g_box: Box, } @@ -42,7 +43,7 @@ impl Navigation { let request = Rc::new(Request::build(item_action, profile)); let reload = Button::reload((window_action, tab_action, item_action), &request); let home = Button::home((window_action, tab_action, item_action), &request); - let bookmark = Button::bookmark(window_action, profile, &request.entry); + let bookmark = Rc::new(Bookmark::build(window_action, profile, &request.entry)); // Init main widget let g_box = Box::builder() @@ -57,9 +58,13 @@ impl Navigation { g_box.append(&history); g_box.append(&reload); g_box.append(&request.entry); - g_box.append(&bookmark); + g_box.append(&bookmark.button); - Self { request, g_box } + Self { + request, + bookmark, + g_box, + } } // Actions @@ -68,6 +73,11 @@ impl Navigation { self.request.escape(); } + /// Toggle bookmark for current navigation request + pub fn bookmark(&self, title: Option<&str>) { + self.bookmark.toggle(title) + } + pub fn clean( &self, transaction: &Transaction, diff --git a/src/app/browser/window/tab/item/page/navigation/bookmark.rs b/src/app/browser/window/tab/item/page/navigation/bookmark.rs index a4701fa4..f3b6c56d 100644 --- a/src/app/browser/window/tab/item/page/navigation/bookmark.rs +++ b/src/app/browser/window/tab/item/page/navigation/bookmark.rs @@ -8,13 +8,14 @@ use std::{rc::Rc, sync::Arc}; const ICON_NAME: (&str, &str) = ("non-starred-symbolic", "starred-symbolic"); const TOOLTIP_TEXT: (&str, &str) = ("Add Bookmark", "Remove Bookmark"); -pub trait Bookmark { - fn bookmark(action: &Rc, profile: &Arc, request: &Entry) -> Self; - fn update(&self, profile: &Arc, request: &Entry); +pub struct Bookmark { + profile: Arc, + request: Entry, + pub button: Button, } -impl Bookmark for Button { - fn bookmark(action: &Rc, profile: &Arc, request: &Entry) -> Self { +impl Bookmark { + pub fn build(action: &Rc, profile: &Arc, request: &Entry) -> Self { let button = Button::builder() .action_name(format!( "{}.{}", @@ -22,44 +23,34 @@ impl Bookmark for Button { action.bookmark.simple_action.name() )) .build(); - button.update(profile, request); - - // Setup events - action.bookmark.simple_action.connect_activate({ - let button = button.clone(); - let profile = profile.clone(); - let request = request.clone(); - move |_, _| button.update(&profile, &request) - }); - + update(profile, &button, request.text()); request.connect_changed({ let profile = profile.clone(); let button = button.clone(); - move |this| button.update(&profile, this) + move |entry| update(&profile, &button, entry.text()) }); - - button.connect_clicked({ - let profile = profile.clone(); - let request = request.clone(); - move |this| this.update(&profile, &request) - }); - - button + Self { + profile: profile.clone(), + request: request.clone(), + button, + } } - fn update(&self, profile: &Arc, request: &Entry) { - self.set_sensitive(false); // lock - let this = self.clone(); - let profile = profile.clone(); - let query = request.text(); + pub fn toggle(&self, title: Option<&str>) { + let button = self.button.clone(); + let profile = self.profile.clone(); + let query = self.request.text(); + let title = title.map(|t| t.to_string()); gtk::glib::spawn_future_local(async move { - let has_bookmark = - gtk::gio::spawn_blocking(move || profile.bookmark.is_match_request(&query)) - .await - .unwrap(); - this.set_icon_name(icon_name(has_bookmark)); - this.set_tooltip_text(Some(tooltip_text(has_bookmark))); - this.set_sensitive(true); + button.set_sensitive(false); // lock + let has_bookmark = gtk::gio::spawn_blocking(move || { + profile.bookmark.toggle(&query, title.as_deref()).unwrap() + }) + .await + .unwrap(); + button.set_icon_name(icon_name(has_bookmark)); + button.set_tooltip_text(Some(tooltip_text(has_bookmark))); + button.set_sensitive(true); }); // may take a while } } @@ -79,3 +70,18 @@ fn icon_name(has_bookmark: bool) -> &'static str { ICON_NAME.0 } } + +fn update(profile: &Arc, button: &Button, request: gtk::glib::GString) { + let profile = profile.clone(); + let button = button.clone(); + gtk::glib::spawn_future_local(async move { + button.set_sensitive(false); // lock + let has_bookmark = + gtk::gio::spawn_blocking(move || profile.bookmark.is_match_request(&request)) + .await + .unwrap(); + button.set_icon_name(icon_name(has_bookmark)); + button.set_tooltip_text(Some(tooltip_text(has_bookmark))); + button.set_sensitive(true); + }); // may take a while +}