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

View File

@ -80,6 +80,15 @@ impl Suggestion {
let r = l.child().and_downcast::<ActionRow>().unwrap();
r.set_title(&i.title());
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
})
@ -134,22 +143,31 @@ impl Suggestion {
// Actions
pub fn update(&self, limit: Option<usize>) {
use gtk::prelude::EditableExt;
use gtk::{glib::GString, prelude::EditableExt};
use itertools::Itertools;
if self.request.text_length() > 0 {
self.list_store.remove_all();
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() {
for item in items
.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(
item.request.replace(&*query, &format!("<b>{query}</b>")),
item.request.clone(),
item.request.clone(),
)); // @TODO
title,
subtitle,
self.profile.bookmark.is_match_request(&item.request),
item.request,
));
}
self.popover.popup();
return;

View File

@ -1,6 +1,6 @@
mod imp;
use gtk::glib::{self, Object};
use gtk::glib::{self, GString, Object};
glib::wrapper! {
pub struct Item(ObjectSubclass<imp::Item>);
@ -9,11 +9,12 @@ glib::wrapper! {
impl Item {
// 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()
.property("title", title)
.property("subtitle", subtitle)
.property("request", request)
.property("has-bookmark", has_bookmark)
.build()
}
}

View File

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

View File

@ -27,10 +27,10 @@ impl History {
// Actions
/// 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();
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> {
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 id: i64,
pub request: GString,
pub title: Option<GString>,
pub opened: Vec<DateTime>,
pub closed: Vec<DateTime>,
}
@ -11,10 +12,11 @@ pub struct Item {
impl Item {
// Constructors
pub fn create(id: i64, request: GString) -> Self {
pub fn create(id: i64, request: GString, title: Option<GString>) -> Self {
Self {
id,
request,
title,
opened: vec![now()],
closed: vec![],
}

View File

@ -76,6 +76,20 @@ impl Memory {
}
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 {