From 879637115c4c248e79031da64b916cd748525086 Mon Sep 17 00:00:00 2001 From: Gabriele Musco Date: Wed, 8 Jan 2025 07:50:44 +0100 Subject: [PATCH] feat: homepage and author in plugin details --- src/ui/plugins/mod.rs | 1 + src/ui/plugins/store_detail.rs | 70 ++++++++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/ui/plugins/mod.rs b/src/ui/plugins/mod.rs index 91d55ca..c900fd6 100644 --- a/src/ui/plugins/mod.rs +++ b/src/ui/plugins/mod.rs @@ -16,6 +16,7 @@ use std::path::PathBuf; pub struct Plugin { pub appid: String, pub name: String, + pub author: Option, pub icon_url: Option, pub version: Option, pub short_description: Option, diff --git a/src/ui/plugins/store_detail.rs b/src/ui/plugins/store_detail.rs index 5a1b12c..4bd9d9f 100644 --- a/src/ui/plugins/store_detail.rs +++ b/src/ui/plugins/store_detail.rs @@ -2,7 +2,7 @@ use super::Plugin; use crate::{downloader::cache_file, ui::SENDER_IO_ERR_MSG}; use adw::prelude::*; use relm4::prelude::*; -use tracing::warn; +use tracing::{error, warn}; #[tracker::track] pub struct StoreDetail { @@ -25,6 +25,7 @@ pub enum StoreDetailMsg { Install, Remove, SetEnabled(bool), + OpenHomepage, } #[derive(Debug)] @@ -91,18 +92,42 @@ impl AsyncComponent for StoreDetail { set_margin_end: 12, set_pixel_size: 96, }, - gtk::Label { - add_css_class: "title-2", + gtk::Box { + set_orientation: gtk::Orientation::Vertical, set_hexpand: true, - set_xalign: 0.0, - #[track = "model.changed(Self::plugin())"] - set_text: model - .plugin - .as_ref() - .map(|p| p.name.as_str()) - .unwrap_or_default(), - set_ellipsize: gtk::pango::EllipsizeMode::None, - set_wrap: true, + set_valign: gtk::Align::Center, + set_spacing: 6, + gtk::Label { + add_css_class: "title-2", + set_xalign: 0.0, + #[track = "model.changed(Self::plugin())"] + set_text: model + .plugin + .as_ref() + .map(|p| p.name.as_str()) + .unwrap_or_default(), + set_ellipsize: gtk::pango::EllipsizeMode::None, + set_wrap: true, + }, + gtk::Label { + add_css_class: "dim-label", + set_xalign: 0.0, + #[track = "model.changed(Self::plugin())"] + set_visible: model + .plugin + .as_ref() + .is_some_and(|p| p.author.is_some()), + #[track = "model.changed(Self::plugin())"] + set_text: model + .plugin + .as_ref() + .and_then( + |p| p.author.as_deref() + ) + .unwrap_or_default(), + set_ellipsize: gtk::pango::EllipsizeMode::None, + set_wrap: true, + }, }, gtk::Box { set_orientation: gtk::Orientation::Vertical, @@ -161,6 +186,15 @@ impl AsyncComponent for StoreDetail { gtk::glib::Propagation::Proceed } }, + gtk::Button { + #[track = "model.changed(Self::plugin())"] + set_visible: model.plugin.as_ref() + .is_some_and(|p| p.homepage_url.is_some()), + set_label: "Homepage", + connect_clicked[sender] => move |_| { + sender.input(Self::Input::OpenHomepage); + } + } } } }, @@ -211,6 +245,18 @@ impl AsyncComponent for StoreDetail { self.reset(); match message { + Self::Input::OpenHomepage => { + if let Some(plugin) = self.plugin.as_ref() { + if let Some(homepage) = plugin.homepage_url.as_ref() { + if let Err(e) = gtk::gio::AppInfo::launch_default_for_uri( + homepage, + gtk::gio::AppLaunchContext::NONE, + ) { + error!("opening uri {homepage}: {e}"); + }; + } + } + } Self::Input::SetPlugin(p, enabled, needs_update) => { self.set_plugin(Some(p)); self.set_enabled(enabled);