[gnome-software/1364-implement-other-apps-by-author-section-in-app-details-page: 10/14] gs-details-page: Add "Other Apps by $author" section
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/1364-implement-other-apps-by-author-section-in-app-details-page: 10/14] gs-details-page: Add "Other Apps by $author" section
- Date: Thu, 17 Mar 2022 10:20:30 +0000 (UTC)
commit 6dadef76932b5e27b3932bcb40798588d4b8285d
Author: Milan Crha <mcrha redhat com>
Date: Tue Mar 15 18:19:57 2022 +0100
gs-details-page: Add "Other Apps by $author" section
Add the "Other Apps by $author" section at the end of the page,
thus the users can check what other apps the developer or a project
group offers.
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1364
src/gs-details-page.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++-
src/gs-details-page.ui | 42 +++++++++++++++++++++
2 files changed, 140 insertions(+), 1 deletion(-)
---
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index dd1591087..d23229492 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -32,6 +32,7 @@
#include "gs-progress-button.h"
#include "gs-screenshot-carousel.h"
#include "gs-star-widget.h"
+#include "gs-summary-tile.h"
#include "gs-review-histogram.h"
#include "gs-review-dialog.h"
#include "gs-review-row.h"
@@ -147,6 +148,9 @@ struct _GsDetailsPage
GsLicenseTile *license_tile;
GtkInfoBar *translation_infobar;
GtkButton *translation_infobar_button;
+ GtkWidget *other_apps_heading;
+ GtkWidget *box_other_apps;
+ gchar *last_developer_name;
};
G_DEFINE_TYPE (GsDetailsPage, gs_details_page, GS_TYPE_PAGE)
@@ -947,6 +951,55 @@ update_action_row_from_link (AdwActionRow *row,
return (url != NULL);
}
+static void
+gs_details_page_app_tile_clicked (GsAppTile *tile,
+ gpointer user_data)
+{
+ GsDetailsPage *self = GS_DETAILS_PAGE (user_data);
+ GsApp *app;
+
+ app = gs_app_tile_get_app (tile);
+ gs_details_page_set_app (self, app);
+}
+
+static void
+gs_details_page_search_other_apps_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GsDetailsPage *self = GS_DETAILS_PAGE (user_data);
+ g_autoptr(GsAppList) list = NULL;
+ g_autoptr(GError) local_error = NULL;
+ gboolean any_added = FALSE;
+
+ list = gs_plugin_loader_job_process_finish (GS_PLUGIN_LOADER (source_object), result, &local_error);
+ if (list == NULL) {
+ if (g_error_matches (local_error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED) ||
+ g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_debug ("search cancelled");
+ return;
+ }
+ g_warning ("failed to get other apps: %s", local_error->message);
+ return;
+ }
+
+ if (!self->app || !gs_page_is_active (GS_PAGE (self)))
+ return;
+
+ for (guint i = 0; i < gs_app_list_length (list); i++) {
+ GsApp *app = gs_app_list_index (list, i);
+ if (g_strcmp0 (gs_app_get_id (app), gs_app_get_id (self->app)) != 0) {
+ GtkWidget *tile = gs_summary_tile_new (app);
+ g_signal_connect (tile, "clicked", G_CALLBACK (gs_details_page_app_tile_clicked),
self);
+ gtk_flow_box_insert (GTK_FLOW_BOX (self->box_other_apps), tile, -1);
+
+ any_added = TRUE;
+ }
+ }
+
+ gtk_widget_set_visible (self->box_other_apps, any_added);
+}
+
static void
gs_details_page_refresh_all (GsDetailsPage *self)
{
@@ -1027,8 +1080,49 @@ gs_details_page_refresh_all (GsDetailsPage *self)
tmp = gs_app_get_developer_name (self->app);
if (tmp == NULL)
tmp = gs_app_get_project_group (self->app);
- if (tmp != NULL)
+ if (tmp != NULL) {
gtk_label_set_label (GTK_LABEL (self->developer_name_label), tmp);
+
+ if (g_strcmp0 (tmp, self->last_developer_name) != 0) {
+ g_autoptr(GsPluginJob) plugin_job = NULL;
+ g_autofree gchar *heading = NULL;
+
+ /* Hide the section, it will be shown only if any other app had been found */
+ gtk_widget_set_visible (self->box_other_apps, FALSE);
+
+ g_clear_pointer (&self->last_developer_name, g_free);
+ self->last_developer_name = g_strdup (tmp);
+
+ /* Translators: the '%s' is replaced with a developer name or a project group */
+ heading = g_strdup_printf (_("Other Apps by %s"), self->last_developer_name);
+ gtk_label_set_label (GTK_LABEL (self->other_apps_heading), heading);
+ gs_widget_remove_all (self->box_other_apps, (GsRemoveFunc) gtk_flow_box_remove);
+
+ plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_SEARCH_OTHER_APPS,
+ "search", self->last_developer_name,
+ "max-results", 18,
+ "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON |
+
GS_PLUGIN_REFINE_FLAGS_REQUIRE_VERSION |
+
GS_PLUGIN_REFINE_FLAGS_REQUIRE_HISTORY |
+
GS_PLUGIN_REFINE_FLAGS_REQUIRE_SETUP_ACTION |
+
GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS |
+
GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION |
+
GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENSE |
+
GS_PLUGIN_REFINE_FLAGS_REQUIRE_PERMISSIONS |
+
GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING,
+ "dedupe-flags",
GS_APP_LIST_FILTER_FLAG_KEY_ID_PROVIDES,
+ NULL);
+ gs_plugin_loader_job_process_async (self->plugin_loader, plugin_job,
+ self->cancellable,
+ gs_details_page_search_other_apps_cb,
+ self);
+ }
+ } else if (tmp == NULL) {
+ g_clear_pointer (&self->last_developer_name, g_free);
+ gs_widget_remove_all (self->box_other_apps, (GsRemoveFunc) gtk_flow_box_remove);
+ gtk_widget_set_visible (self->box_other_apps, FALSE);
+ }
+
gtk_widget_set_visible (GTK_WIDGET (self->developer_name_label), tmp != NULL);
gtk_widget_set_visible (GTK_WIDGET (self->developer_verified_image), gs_app_has_quirk (self->app,
GS_APP_QUIRK_DEVELOPER_VERIFIED));
@@ -2153,6 +2247,7 @@ gs_details_page_dispose (GObject *object)
g_clear_object (&self->size_group_origin_popover);
g_clear_object (&self->odrs_provider);
g_clear_object (&self->app_info_monitor);
+ g_clear_pointer (&self->last_developer_name, g_free);
G_OBJECT_CLASS (gs_details_page_parent_class)->dispose (object);
}
@@ -2281,6 +2376,8 @@ gs_details_page_class_init (GsDetailsPageClass *klass)
gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, license_tile);
gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, translation_infobar);
gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, translation_infobar_button);
+ gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, other_apps_heading);
+ gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, box_other_apps);
gtk_widget_class_bind_template_callback (widget_class, gs_details_page_link_row_activated_cb);
gtk_widget_class_bind_template_callback (widget_class,
gs_details_page_license_tile_get_involved_activated_cb);
diff --git a/src/gs-details-page.ui b/src/gs-details-page.ui
index cda8392a1..5fb88fd0e 100644
--- a/src/gs-details-page.ui
+++ b/src/gs-details-page.ui
@@ -899,6 +899,48 @@
</child>
</object>
</child>
+ <child>
+ <object class="AdwClamp">
+ <property name="visible" bind-source="box_other_apps"
bind-property="visible" bind-flags="sync-create"/>
+ <property name="maximum-size">860</property>
+ <!-- ~⅔ of the maximum size. -->
+ <property name="tightening-threshold">576</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <child>
+ <object class="GtkBox">
+ <property name="halign">center</property>
+ <property name="hexpand">False</property>
+ <property name="orientation">vertical</property>
+ <property name="valign">start</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="other_apps_heading">
+ <property name="xalign">0</property>
+ <!-- the label is set in the code -->
+ <property name="label">Other Apps by ...</property>
+ <property name="margin-top">21</property>
+ <property name="margin-bottom">6</property>
+ <style>
+ <class name="heading"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFlowBox" id="box_other_apps">
+ <property name="homogeneous">True</property>
+ <property name="column-spacing">14</property>
+ <property name="row-spacing">14</property>
+ <property name="valign">start</property>
+ <accessibility>
+ <relation name="labelled-by">other_apps_heading</relation>
+ </accessibility>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]