implement suggestion titles, search in history, show bookmark as icon indicator

This commit is contained in:
yggverse 2025-03-11 11:09:49 +02:00
parent 2b2ffd00de
commit 73c35d25d8
8 changed files with 71 additions and 19 deletions

View File

@ -205,5 +205,7 @@ fn snap_history(page: &Page) {
page.item_action page.item_action
.history .history
.add(page.navigation.request(), true); .add(page.navigation.request(), true);
page.profile.history.open(page.navigation.request()) page.profile
.history
.open(page.navigation.request(), Some(page.title()))
} }

View File

@ -123,7 +123,9 @@ impl Page {
// Restore child components // Restore child components
self.navigation.restore(transaction, &record.id)?; self.navigation.restore(transaction, &record.id)?;
// Make initial page history snap // Make initial page history snap
self.profile.history.open(self.navigation.request()); self.profile
.history
.open(self.navigation.request(), Some(self.title()));
} }
Ok(()) Ok(())
} }
@ -166,6 +168,12 @@ impl Page {
self.navigation.set_progress_fraction(progress_fraction); self.navigation.set_progress_fraction(progress_fraction);
self.tab_page.set_loading(progress_fraction > 0.0) self.tab_page.set_loading(progress_fraction > 0.0)
} }
// Getters
pub fn title(&self) -> gtk::glib::GString {
self.tab_page.title()
}
} }
// Tools // Tools

View File

@ -80,6 +80,15 @@ impl Suggestion {
let r = l.child().and_downcast::<ActionRow>().unwrap(); let r = l.child().and_downcast::<ActionRow>().unwrap();
r.set_title(&i.title()); r.set_title(&i.title());
r.set_subtitle(&i.subtitle()); r.set_subtitle(&i.subtitle());
if i.has_bookmark() {
r.add_suffix(
&gtk::Image::builder()
.icon_name("starred-symbolic")
.margin_end(4)
.pixel_size(11)
.build(),
);
}
}); });
f f
}) })
@ -134,22 +143,31 @@ impl Suggestion {
// Actions // Actions
pub fn update(&self, limit: Option<usize>) { pub fn update(&self, limit: Option<usize>) {
use gtk::prelude::EditableExt; use gtk::{glib::GString, prelude::EditableExt};
use itertools::Itertools; use itertools::Itertools;
if self.request.text_length() > 0 { if self.request.text_length() > 0 {
self.list_store.remove_all(); self.list_store.remove_all();
let query = self.request.text(); let query = self.request.text();
let items = self.profile.bookmark.contains_request(&query, limit); let items = self.profile.history.contains_request(&query, limit);
if !items.is_empty() { if !items.is_empty() {
for item in items for item in items
.into_iter() .into_iter()
.sorted_by(|a, b| Ord::cmp(&b.request, &a.request)) .sorted_by(|a, b| Ord::cmp(&b.opened.len(), &a.opened.len()))
{ {
let subtitle =
GString::from(item.request.replace(&*query, &format!("<b>{query}</b>")));
let title = match item.title {
Some(title) => title.replace(&*query, &format!("<b>{query}</b>")).into(),
None => subtitle.clone(),
};
self.list_store.append(&Item::build( self.list_store.append(&Item::build(
item.request.replace(&*query, &format!("<b>{query}</b>")), title,
item.request.clone(), subtitle,
item.request.clone(), self.profile.bookmark.is_match_request(&item.request),
)); // @TODO item.request,
));
} }
self.popover.popup(); self.popover.popup();
return; return;

View File

@ -1,6 +1,6 @@
mod imp; mod imp;
use gtk::glib::{self, Object}; use gtk::glib::{self, GString, Object};
glib::wrapper! { glib::wrapper! {
pub struct Item(ObjectSubclass<imp::Item>); pub struct Item(ObjectSubclass<imp::Item>);
@ -9,11 +9,12 @@ glib::wrapper! {
impl Item { impl Item {
// Constructors // Constructors
pub fn build(title: String, subtitle: String, request: String) -> Self { pub fn build(title: GString, subtitle: GString, has_bookmark: bool, request: GString) -> Self {
Object::builder() Object::builder()
.property("title", title) .property("title", title)
.property("subtitle", subtitle) .property("subtitle", subtitle)
.property("request", request) .property("request", request)
.property("has-bookmark", has_bookmark)
.build() .build()
} }
} }

View File

@ -1,19 +1,21 @@
use gtk::{ use gtk::{
gio::subclass::prelude::{DerivedObjectProperties, ObjectImpl, ObjectImplExt, ObjectSubclass}, gio::subclass::prelude::{DerivedObjectProperties, ObjectImpl, ObjectImplExt, ObjectSubclass},
glib::{self, Object, Properties}, glib::{self, GString, Object, Properties},
prelude::ObjectExt, prelude::ObjectExt,
}; };
use std::cell::RefCell; use std::cell::{Cell, RefCell};
#[derive(Properties, Default)] #[derive(Properties, Default)]
#[properties(wrapper_type = super::Item)] #[properties(wrapper_type = super::Item)]
pub struct Item { pub struct Item {
#[property(get, set)] #[property(get, set)]
title: RefCell<String>, title: RefCell<GString>,
#[property(get, set)] #[property(get, set)]
subtitle: RefCell<String>, subtitle: RefCell<GString>,
#[property(get, set)] #[property(get, set)]
request: RefCell<String>, request: RefCell<GString>,
#[property(get, set)]
has_bookmark: Cell<bool>,
} }
#[glib::object_subclass] #[glib::object_subclass]

View File

@ -27,10 +27,10 @@ impl History {
// Actions // Actions
/// Create new history record /// Create new history record
pub fn open(&self, request: GString) { pub fn open(&self, request: GString, title: Option<GString>) {
let mut memory = self.memory.borrow_mut(); let mut memory = self.memory.borrow_mut();
if !memory.open(&request) { if !memory.open(&request) {
memory.add(Item::create(0, request)) // @TODO memory.add(Item::create(0, request, title)) // @TODO
} }
} }
@ -50,4 +50,9 @@ impl History {
pub fn recently_closed(&self, limit: Option<usize>) -> Vec<Item> { pub fn recently_closed(&self, limit: Option<usize>) -> Vec<Item> {
self.memory.borrow().recently_closed(limit) self.memory.borrow().recently_closed(limit)
} }
/// Get unordered Items vector contains `request`
pub fn contains_request(&self, request: &str, limit: Option<usize>) -> Vec<Item> {
self.memory.borrow().contains_request(request, limit)
}
} }

View File

@ -4,6 +4,7 @@ use gtk::glib::{DateTime, GString};
pub struct Item { pub struct Item {
pub id: i64, pub id: i64,
pub request: GString, pub request: GString,
pub title: Option<GString>,
pub opened: Vec<DateTime>, pub opened: Vec<DateTime>,
pub closed: Vec<DateTime>, pub closed: Vec<DateTime>,
} }
@ -11,10 +12,11 @@ pub struct Item {
impl Item { impl Item {
// Constructors // Constructors
pub fn create(id: i64, request: GString) -> Self { pub fn create(id: i64, request: GString, title: Option<GString>) -> Self {
Self { Self {
id, id,
request, request,
title,
opened: vec![now()], opened: vec![now()],
closed: vec![], closed: vec![],
} }

View File

@ -76,6 +76,20 @@ impl Memory {
} }
recent recent
} }
/// Get unordered Items vector contains `request`
pub fn contains_request(&self, request: &str, limit: Option<usize>) -> Vec<Item> {
let mut items: Vec<Item> = Vec::new();
for (i, item) in self.0.iter().enumerate() {
if limit.is_some_and(|l| i > l) {
break;
}
if item.request.contains(request) {
items.push(item.clone())
}
}
items
}
} }
impl Default for Memory { impl Default for Memory {