make bookmark toggle operation async

This commit is contained in:
yggverse 2025-03-14 18:13:17 +02:00
parent d937d923c5
commit 1eaf3a607e
3 changed files with 56 additions and 43 deletions

View File

@ -76,10 +76,7 @@ impl Page {
/// Toggle bookmark for current navigation request /// Toggle bookmark for current navigation request
pub fn bookmark(&self) { pub fn bookmark(&self) {
self.profile self.navigation.bookmark(Some(&self.title()))
.bookmark
.toggle(&self.navigation.request(), Some(&self.title()))
.unwrap(); // @TODO
} }
/// Request `Escape` action for all page components /// Request `Escape` action for all page components

View File

@ -25,6 +25,7 @@ const SPACING: i32 = 6;
pub struct Navigation { pub struct Navigation {
request: Rc<Request>, request: Rc<Request>,
bookmark: Rc<Bookmark>,
pub g_box: Box, pub g_box: Box,
} }
@ -42,7 +43,7 @@ impl Navigation {
let request = Rc::new(Request::build(item_action, profile)); let request = Rc::new(Request::build(item_action, profile));
let reload = Button::reload((window_action, tab_action, item_action), &request); let reload = Button::reload((window_action, tab_action, item_action), &request);
let home = Button::home((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 // Init main widget
let g_box = Box::builder() let g_box = Box::builder()
@ -57,9 +58,13 @@ impl Navigation {
g_box.append(&history); g_box.append(&history);
g_box.append(&reload); g_box.append(&reload);
g_box.append(&request.entry); g_box.append(&request.entry);
g_box.append(&bookmark); g_box.append(&bookmark.button);
Self { request, g_box } Self {
request,
bookmark,
g_box,
}
} }
// Actions // Actions
@ -68,6 +73,11 @@ impl Navigation {
self.request.escape(); self.request.escape();
} }
/// Toggle bookmark for current navigation request
pub fn bookmark(&self, title: Option<&str>) {
self.bookmark.toggle(title)
}
pub fn clean( pub fn clean(
&self, &self,
transaction: &Transaction, transaction: &Transaction,

View File

@ -8,13 +8,14 @@ use std::{rc::Rc, sync::Arc};
const ICON_NAME: (&str, &str) = ("non-starred-symbolic", "starred-symbolic"); const ICON_NAME: (&str, &str) = ("non-starred-symbolic", "starred-symbolic");
const TOOLTIP_TEXT: (&str, &str) = ("Add Bookmark", "Remove Bookmark"); const TOOLTIP_TEXT: (&str, &str) = ("Add Bookmark", "Remove Bookmark");
pub trait Bookmark { pub struct Bookmark {
fn bookmark(action: &Rc<WindowAction>, profile: &Arc<Profile>, request: &Entry) -> Self; profile: Arc<Profile>,
fn update(&self, profile: &Arc<Profile>, request: &Entry); request: Entry,
pub button: Button,
} }
impl Bookmark for Button { impl Bookmark {
fn bookmark(action: &Rc<WindowAction>, profile: &Arc<Profile>, request: &Entry) -> Self { pub fn build(action: &Rc<WindowAction>, profile: &Arc<Profile>, request: &Entry) -> Self {
let button = Button::builder() let button = Button::builder()
.action_name(format!( .action_name(format!(
"{}.{}", "{}.{}",
@ -22,44 +23,34 @@ impl Bookmark for Button {
action.bookmark.simple_action.name() action.bookmark.simple_action.name()
)) ))
.build(); .build();
button.update(profile, request); update(profile, &button, request.text());
// 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)
});
request.connect_changed({ request.connect_changed({
let profile = profile.clone(); let profile = profile.clone();
let button = button.clone(); let button = button.clone();
move |this| button.update(&profile, this) move |entry| update(&profile, &button, entry.text())
}); });
Self {
button.connect_clicked({ profile: profile.clone(),
let profile = profile.clone(); request: request.clone(),
let request = request.clone(); button,
move |this| this.update(&profile, &request) }
});
button
} }
fn update(&self, profile: &Arc<Profile>, request: &Entry) { pub fn toggle(&self, title: Option<&str>) {
self.set_sensitive(false); // lock let button = self.button.clone();
let this = self.clone(); let profile = self.profile.clone();
let profile = profile.clone(); let query = self.request.text();
let query = request.text(); let title = title.map(|t| t.to_string());
gtk::glib::spawn_future_local(async move { gtk::glib::spawn_future_local(async move {
let has_bookmark = button.set_sensitive(false); // lock
gtk::gio::spawn_blocking(move || profile.bookmark.is_match_request(&query)) let has_bookmark = gtk::gio::spawn_blocking(move || {
profile.bookmark.toggle(&query, title.as_deref()).unwrap()
})
.await .await
.unwrap(); .unwrap();
this.set_icon_name(icon_name(has_bookmark)); button.set_icon_name(icon_name(has_bookmark));
this.set_tooltip_text(Some(tooltip_text(has_bookmark))); button.set_tooltip_text(Some(tooltip_text(has_bookmark)));
this.set_sensitive(true); button.set_sensitive(true);
}); // may take a while }); // may take a while
} }
} }
@ -79,3 +70,18 @@ fn icon_name(has_bookmark: bool) -> &'static str {
ICON_NAME.0 ICON_NAME.0
} }
} }
fn update(profile: &Arc<Profile>, 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
}