[gnome-software/1409-add-available-for-fedora-section-to-the-explore-page: 187/187] gs-overview-page: Add a distro-featured section




commit 42e4c46f437807c3bb3fa2d8c80ee5e36d955f4a
Author: Milan Crha <mcrha redhat com>
Date:   Wed Sep 8 16:15:49 2021 +0200

    gs-overview-page: Add a distro-featured section
    
    The distro-featured section shows applications, which are tagged
    with "GnomeSoftware::DistroFeatured" key. This can be done with an appstream
    data file saved into /usr/share/app-info/xmls/.  An example file can be found
    at contrib/org.gnome.Software.DistroFeatured.xml . The applications can be
    tagged with this key by other means, this is only one way to do it.
    
    The section is shown if there are found enough applications (currently at least 12).

 contrib/org.gnome.Software.DistroFeatured.xml | 11 ++++
 src/gs-overview-page.c                        | 85 +++++++++++++++++++++++++++
 src/gs-overview-page.ui                       | 25 ++++++++
 3 files changed, 121 insertions(+)
---
diff --git a/contrib/org.gnome.Software.DistroFeatured.xml b/contrib/org.gnome.Software.DistroFeatured.xml
new file mode 100644
index 000000000..1b5b7a216
--- /dev/null
+++ b/contrib/org.gnome.Software.DistroFeatured.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- This is only an example file, what the distro-featured file can look like;
+     it should be installed beside the org.gnome.Software.Featured.xml file. -->
+<components>
+  <component merge="append">
+    <id>org.gnome.Software.desktop</id>
+    <custom>
+      <value key="GnomeSoftware::DistroFeatured">True</value>
+    </custom>
+  </component>
+</components>
diff --git a/src/gs-overview-page.c b/src/gs-overview-page.c
index 7c08a8849..813d3b9a3 100644
--- a/src/gs-overview-page.c
+++ b/src/gs-overview-page.c
@@ -35,6 +35,7 @@ struct _GsOverviewPage
        GsShell                 *shell;
        gint                     action_cnt;
        gboolean                 loading_featured;
+       gboolean                 loading_distro_featured;
        gboolean                 loading_popular;
        gboolean                 loading_recent;
        gboolean                 loading_categories;
@@ -49,11 +50,13 @@ struct _GsOverviewPage
        GtkWidget               *box_overview;
        GtkWidget               *box_popular;
        GtkWidget               *box_recent;
+       GtkWidget               *box_distro_featured;
        GtkWidget               *flowbox_categories;
        GtkWidget               *flowbox_iconless_categories;
        GtkWidget               *iconless_categories_heading;
        GtkWidget               *popular_heading;
        GtkWidget               *recent_heading;
+       GtkWidget               *distro_featured_heading;
        GtkWidget               *scrolledwindow_overview;
        GtkWidget               *stack_overview;
 };
@@ -113,6 +116,7 @@ gs_overview_page_decrement_action_cnt (GsOverviewPage *self)
        self->cache_valid = TRUE;
        g_signal_emit (self, signals[SIGNAL_REFRESHED], 0);
        self->loading_categories = FALSE;
+       self->loading_distro_featured = FALSE;
        self->loading_featured = FALSE;
        self->loading_popular = FALSE;
        self->loading_recent = FALSE;
@@ -284,6 +288,56 @@ out:
        gs_overview_page_decrement_action_cnt (self);
 }
 
+static void
+gs_overview_page_get_distro_featured_cb (GObject *source_object,
+                                        GAsyncResult *res,
+                                        gpointer user_data)
+{
+       GsOverviewPage *self = GS_OVERVIEW_PAGE (user_data);
+       GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source_object);
+       guint i;
+       GsApp *app;
+       GtkWidget *tile;
+       g_autoptr(GError) error = NULL;
+       g_autoptr(GsAppList) list = NULL;
+
+       /* get distro-featured apps */
+       list = gs_plugin_loader_job_process_finish (plugin_loader, res, &error);
+       if (list == NULL) {
+               if (!g_error_matches (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED))
+                       g_warning ("failed to get distro-featured apps: %s", error->message);
+               goto out;
+       }
+
+       /* not enough to show */
+       if (gs_app_list_length (list) < N_TILES) {
+               g_warning ("Only %u apps for distro-featured list, hiding",
+                          gs_app_list_length (list));
+               gtk_widget_set_visible (self->box_distro_featured, FALSE);
+               gtk_widget_set_visible (self->distro_featured_heading, FALSE);
+               goto out;
+       }
+
+       gs_app_list_randomize (list);
+
+       gs_widget_remove_all (self->box_distro_featured, (GsRemoveFunc) gtk_flow_box_remove);
+
+       for (i = 0; i < gs_app_list_length (list) && i < N_TILES; i++) {
+               app = gs_app_list_index (list, i);
+               tile = gs_summary_tile_new (app);
+               g_signal_connect (tile, "clicked",
+                         G_CALLBACK (app_tile_clicked), self);
+               gtk_flow_box_insert (GTK_FLOW_BOX (self->box_distro_featured), tile, -1);
+       }
+       gtk_widget_set_visible (self->box_distro_featured, TRUE);
+       gtk_widget_set_visible (self->distro_featured_heading, TRUE);
+
+       self->empty = FALSE;
+
+out:
+       gs_overview_page_decrement_action_cnt (self);
+}
+
 static void
 category_tile_clicked (GsCategoryTile *tile, gpointer data)
 {
@@ -483,6 +537,25 @@ gs_overview_page_load (GsOverviewPage *self)
                self->action_cnt++;
        }
 
+       if (!self->loading_distro_featured) {
+               g_autoptr(GsPluginJob) plugin_job = NULL;
+
+               self->loading_distro_featured = TRUE;
+               plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_DISTRO_FEATURED,
+                                                "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING |
+                                                                GS_PLUGIN_REFINE_FLAGS_REQUIRE_CATEGORIES |
+                                                                GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON,
+                                                "dedupe-flags", GS_APP_LIST_FILTER_FLAG_PREFER_INSTALLED |
+                                                                GS_APP_LIST_FILTER_FLAG_KEY_ID_PROVIDES,
+                                                NULL);
+               gs_plugin_loader_job_process_async (self->plugin_loader,
+                                                   plugin_job,
+                                                   self->cancellable,
+                                                   gs_overview_page_get_distro_featured_cb,
+                                                   self);
+               self->action_cnt++;
+       }
+
        if (!self->loading_popular) {
                g_autoptr(GsPluginJob) plugin_job = NULL;
 
@@ -647,9 +720,19 @@ refreshed_cb (GsOverviewPage *self, gpointer user_data)
 static void
 gs_overview_page_init (GsOverviewPage *self)
 {
+       g_autoptr(GsOsRelease) os_release = NULL;
+
        gtk_widget_init_template (GTK_WIDGET (self));
 
        g_signal_connect (self, "refreshed", G_CALLBACK (refreshed_cb), self);
+
+       os_release = gs_os_release_new (NULL);
+       if (os_release != NULL) {
+               g_autofree gchar *text = NULL;
+               /* Translators: the '%s' is replaced with the distribution name */
+               text = g_strdup_printf (_("Available for %s"), gs_os_release_get_name (os_release));
+               gtk_label_set_text (GTK_LABEL (self->distro_featured_heading), text);
+       }
 }
 
 static void
@@ -737,11 +820,13 @@ gs_overview_page_class_init (GsOverviewPageClass *klass)
        gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, box_overview);
        gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, box_popular);
        gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, box_recent);
+       gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, box_distro_featured);
        gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, flowbox_categories);
        gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, flowbox_iconless_categories);
        gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, iconless_categories_heading);
        gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, popular_heading);
        gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, recent_heading);
+       gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, distro_featured_heading);
        gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, scrolledwindow_overview);
        gtk_widget_class_bind_template_child (widget_class, GsOverviewPage, stack_overview);
        gtk_widget_class_bind_template_callback (widget_class, featured_carousel_app_clicked_cb);
diff --git a/src/gs-overview-page.ui b/src/gs-overview-page.ui
index faa9a12ce..61816c8c9 100644
--- a/src/gs-overview-page.ui
+++ b/src/gs-overview-page.ui
@@ -151,6 +151,31 @@
                                   </object>
                                 </child>
 
+                                <child>
+                                  <object class="GtkLabel" id="distro_featured_heading">
+                                    <property name="xalign">0</property>
+                                    <property name="label">Available for Distro</property> <!-- placeholder, 
set in the code -->
+                                    <property name="margin-top">21</property>
+                                    <property name="margin-bottom">6</property>
+                                    <style>
+                                      <class name="index-title-alignment-software"/>
+                                    </style>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkFlowBox" id="box_distro_featured">
+                                    <property name="row_spacing">14</property>
+                                    <property name="column_spacing">14</property>
+                                    <property name="homogeneous">True</property>
+                                    <property name="min_children_per_line">2</property>
+                                    <property name="max_children_per_line">3</property>
+                                    <property name="selection_mode">none</property>
+                                    <accessibility>
+                                      <relation name="labelled-by">distro_featured_heading</relation>
+                                    </accessibility>
+                                  </object>
+                                </child>
+
                                 <child>
                                   <object class="GtkLabel" id="iconless_categories_heading">
                                     <property name="xalign">0</property>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]