Improve catalog view with relative timestamps, auto-refresh, and installed badges
Show app count with relative last-refreshed time in subtitle. Auto-refresh catalog on first visit when empty. Show "Installed" badge on catalog entries that match already-installed AppImages instead of the Install button.
This commit is contained in:
@@ -95,20 +95,10 @@ pub fn build_catalog_page(db: &Rc<Database>) -> adw::NavigationPage {
|
||||
stack.add_named(&scrolled, Some("results"));
|
||||
|
||||
// Show empty or results based on catalog data
|
||||
let sources = catalog::get_sources(db);
|
||||
let enabled_sources: Vec<_> = sources.iter().filter(|s| s.enabled).collect();
|
||||
let app_count = db.catalog_app_count().unwrap_or(0);
|
||||
if app_count > 0 {
|
||||
stack.set_visible_child_name("results");
|
||||
if let Some(src) = enabled_sources.first() {
|
||||
let synced = src.last_synced.as_deref().unwrap_or("never");
|
||||
title.set_subtitle(&format!(
|
||||
"{} apps from {} ({}), synced: {}",
|
||||
src.app_count, src.name, src.source_type.as_str(), synced,
|
||||
));
|
||||
} else {
|
||||
title.set_subtitle(&format!("{} apps available", app_count));
|
||||
}
|
||||
update_catalog_subtitle(&title, app_count);
|
||||
} else {
|
||||
stack.set_visible_child_name("empty");
|
||||
}
|
||||
@@ -195,7 +185,7 @@ pub fn build_catalog_page(db: &Rc<Database>) -> adw::NavigationPage {
|
||||
toast_c.add_toast(adw::Toast::new(
|
||||
&format!("Catalog refreshed: {} apps", count),
|
||||
));
|
||||
title_c.set_subtitle(&format!("{} apps available", count));
|
||||
update_catalog_subtitle(&title_c, count as i64);
|
||||
stack_c.set_visible_child_name("results");
|
||||
populate_categories(&db_c, &cat_box_c, &active_cat_c, &results_c, &search_c);
|
||||
populate_results(&db_c, "", None, &results_c, &toast_c);
|
||||
@@ -221,6 +211,11 @@ pub fn build_catalog_page(db: &Rc<Database>) -> adw::NavigationPage {
|
||||
wire_refresh(&refresh_btn);
|
||||
wire_refresh(&refresh_header_btn);
|
||||
|
||||
// Auto-refresh on first visit when catalog is empty
|
||||
if app_count == 0 {
|
||||
refresh_btn.emit_clicked();
|
||||
}
|
||||
|
||||
adw::NavigationPage::builder()
|
||||
.title(&i18n("Catalog"))
|
||||
.tag("catalog")
|
||||
@@ -228,6 +223,18 @@ pub fn build_catalog_page(db: &Rc<Database>) -> adw::NavigationPage {
|
||||
.build()
|
||||
}
|
||||
|
||||
/// Update the catalog subtitle to show app count and relative last-refreshed time.
|
||||
fn update_catalog_subtitle(title: &adw::WindowTitle, app_count: i64) {
|
||||
let settings = gtk::gio::Settings::new(crate::config::APP_ID);
|
||||
let last_refreshed = settings.string("catalog-last-refreshed");
|
||||
if last_refreshed.is_empty() {
|
||||
title.set_subtitle(&format!("{} apps available", app_count));
|
||||
} else {
|
||||
let relative = widgets::relative_time(&last_refreshed);
|
||||
title.set_subtitle(&format!("{} apps - Refreshed {}", app_count, relative));
|
||||
}
|
||||
}
|
||||
|
||||
fn populate_results(
|
||||
db: &Rc<Database>,
|
||||
query: &str,
|
||||
@@ -254,6 +261,14 @@ fn populate_results(
|
||||
let toast_ref = toast_overlay.clone();
|
||||
let db_ref = db.clone();
|
||||
|
||||
// Get installed app names for matching
|
||||
let installed_names: std::collections::HashSet<String> = db
|
||||
.get_all_appimages()
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.filter_map(|r| r.app_name.as_ref().map(|n| n.to_lowercase()))
|
||||
.collect();
|
||||
|
||||
for app in &results {
|
||||
let row = adw::ActionRow::builder()
|
||||
.title(&app.name)
|
||||
@@ -280,6 +295,16 @@ fn populate_results(
|
||||
}
|
||||
}
|
||||
|
||||
// Show "Installed" badge if already installed, otherwise show Install button
|
||||
let is_installed = installed_names.contains(&app.name.to_lowercase());
|
||||
if is_installed {
|
||||
let installed_badge = widgets::status_badge(&i18n("Installed"), "success");
|
||||
installed_badge.set_valign(gtk::Align::Center);
|
||||
row.add_suffix(&installed_badge);
|
||||
list_box.append(&row);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Install button
|
||||
let install_btn = gtk::Button::builder()
|
||||
.label(&i18n("Install"))
|
||||
|
||||
Reference in New Issue
Block a user