[gnome-software/154-gs-details-page-lack-of-information-when-flatpak-app-data-is-being-loaded: 5/5] gs-details-page: Lack of information when flatpak app data is being loaded
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/154-gs-details-page-lack-of-information-when-flatpak-app-data-is-being-loaded: 5/5] gs-details-page: Lack of information when flatpak app data is being loaded
- Date: Fri, 23 Oct 2020 12:26:37 +0000 (UTC)
commit 69f74a81a19e81b1fbbf7ee489de8b54e4d9d1ce
Author: Milan Crha <mcrha redhat com>
Date: Thu Oct 22 18:25:03 2020 +0200
gs-details-page: Lack of information when flatpak app data is being loaded
Show information from the plugin loader when populating the details page,
thus there's a feedback about what the plugin does when it takes long time.
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/154
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/merge_requests/529
src/gs-details-page.c | 114 ++++++++++++++++++++++++++++++++++++++++++-------
src/gs-details-page.ui | 22 +++++++---
2 files changed, 115 insertions(+), 21 deletions(-)
---
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index 210724ce..aaa0ccae 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -124,8 +124,11 @@ struct _GsDetailsPage
GtkWidget *button_review;
GtkWidget *list_box_reviews;
GtkWidget *scrolledwindow_details;
- GtkWidget *spinner_details;
GtkWidget *spinner_remove;
+ GtkWidget *loading_progressbar;
+ guint loading_progress_pulse_id;
+ gulong loading_status_handler_id;
+ GtkWidget *loading_label;
GtkWidget *stack_details;
GtkWidget *grid_details_kudo;
GtkWidget *image_details_kudo_docs;
@@ -157,6 +160,43 @@ struct _GsDetailsPage
G_DEFINE_TYPE (GsDetailsPage, gs_details_page, GS_TYPE_PAGE)
+static gboolean
+gs_details_page_loading_pulse_cb (gpointer user_data)
+{
+ GsDetailsPage *self = GS_DETAILS_PAGE (user_data);
+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (self->loading_progressbar));
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+gs_details_page_status_changed_cb (GsPluginLoader *plugin_loader,
+ GsApp *app,
+ GsPluginStatus status,
+ GsDetailsPage *self)
+{
+ const gchar *str = NULL;
+
+ if (status == GS_PLUGIN_STATUS_DOWNLOADING && app)
+ str = gs_app_get_summary_missing (app);
+
+ if (str)
+ gtk_label_set_label (GTK_LABEL (self->loading_label), str);
+
+ if (app) {
+ if (self->loading_progress_pulse_id != 0) {
+ g_source_remove (self->loading_progress_pulse_id);
+ self->loading_progress_pulse_id = 0;
+ }
+
+ if (gs_app_get_progress (app) == GS_APP_PROGRESS_UNKNOWN) {
+ self->loading_progress_pulse_id = g_timeout_add (50,
gs_details_page_loading_pulse_cb, self);
+ } else {
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (self->loading_progressbar),
+ (gdouble) gs_app_get_progress (app) / 100.0f);
+ }
+ }
+}
+
static void
gs_details_page_set_state (GsDetailsPage *self,
GsDetailsPageState state)
@@ -164,13 +204,26 @@ gs_details_page_set_state (GsDetailsPage *self,
/* spinner */
switch (state) {
case GS_DETAILS_PAGE_STATE_LOADING:
- gs_start_spinner (GTK_SPINNER (self->spinner_details));
- gtk_widget_show (self->spinner_details);
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (self->loading_progressbar), 0.0);
+ if (!self->loading_progress_pulse_id)
+ self->loading_progress_pulse_id = g_timeout_add (50,
gs_details_page_loading_pulse_cb, self);
+ gtk_label_set_label (GTK_LABEL (self->loading_label), _("Loading Application Details…"));
+ if (!self->loading_status_handler_id) {
+ self->loading_status_handler_id =
+ g_signal_connect (self->plugin_loader, "status-changed",
+ G_CALLBACK (gs_details_page_status_changed_cb), self);
+ }
break;
case GS_DETAILS_PAGE_STATE_READY:
case GS_DETAILS_PAGE_STATE_FAILED:
- gs_stop_spinner (GTK_SPINNER (self->spinner_details));
- gtk_widget_hide (self->spinner_details);
+ if (self->loading_status_handler_id) {
+ g_signal_handler_disconnect (self->plugin_loader, self->loading_status_handler_id);
+ self->loading_status_handler_id = 0;
+ }
+ if (self->loading_progress_pulse_id) {
+ g_source_remove (self->loading_progress_pulse_id);
+ self->loading_progress_pulse_id = 0;
+ }
break;
default:
g_assert_not_reached ();
@@ -261,11 +314,21 @@ app_has_pending_action (GsApp *app)
(gs_app_get_state (app) == AS_APP_STATE_QUEUED_FOR_INSTALL);
}
+static void
+gs_details_page_set_header_label (GsDetailsPage *self,
+ const gchar *text)
+{
+ GtkWidget *widget;
+
+ widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "application_details_header"));
+ gtk_label_set_label (GTK_LABEL (widget), text ? text : "");
+ gtk_widget_set_visible (widget, text != NULL);
+}
+
static void
gs_details_page_switch_to (GsPage *page, gboolean scroll_up)
{
GsDetailsPage *self = GS_DETAILS_PAGE (page);
- GtkWidget *widget;
GtkAdjustment *adj;
if (gs_shell_get_mode (self->shell) != GS_SHELL_MODE_DETAILS) {
@@ -274,14 +337,12 @@ gs_details_page_switch_to (GsPage *page, gboolean scroll_up)
return;
}
- widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "application_details_header"));
- gtk_label_set_label (GTK_LABEL (widget), "");
- gtk_widget_show (widget);
-
/* not set, perhaps file-to-app */
if (self->app == NULL)
return;
+ gs_details_page_set_header_label (self, gs_app_get_name (self->app));
+
adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self->scrolledwindow_details));
gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
@@ -1127,7 +1188,6 @@ gs_details_page_refresh_all (GsDetailsPage *self)
GsAppList *history;
GdkPixbuf *pixbuf = NULL;
GList *addons;
- GtkWidget *widget;
const gchar *tmp;
gboolean ret;
gchar **menu_path;
@@ -1139,14 +1199,12 @@ gs_details_page_refresh_all (GsDetailsPage *self)
/* change widgets */
tmp = gs_app_get_name (self->app);
- widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "application_details_header"));
+ gs_details_page_set_header_label (self, tmp);
if (tmp != NULL && tmp[0] != '\0') {
gtk_label_set_label (GTK_LABEL (self->application_details_title), tmp);
- gtk_label_set_label (GTK_LABEL (widget), tmp);
gtk_widget_set_visible (self->application_details_title, TRUE);
} else {
gtk_widget_set_visible (self->application_details_title, FALSE);
- gtk_label_set_label (GTK_LABEL (widget), "");
}
tmp = gs_app_get_summary (self->app);
if (tmp != NULL && tmp[0] != '\0') {
@@ -1966,8 +2024,17 @@ void
gs_details_page_set_local_file (GsDetailsPage *self, GFile *file)
{
g_autoptr(GsPluginJob) plugin_job = NULL;
+ g_autoptr(GFileInfo) file_info = NULL;
+ const gchar *display_name = NULL;
gs_details_page_set_state (self, GS_DETAILS_PAGE_STATE_LOADING);
g_clear_object (&self->app_local_file);
+ g_clear_object (&self->app);
+
+ file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, G_FILE_QUERY_INFO_NONE,
NULL, NULL);
+ if (file_info)
+ display_name = g_file_info_get_attribute_string (file_info,
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
+ gs_details_page_set_header_label (self, display_name);
+
plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_FILE_TO_APP,
"file", file,
"refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON |
@@ -1999,8 +2066,16 @@ void
gs_details_page_set_url (GsDetailsPage *self, const gchar *url)
{
g_autoptr(GsPluginJob) plugin_job = NULL;
+ const gchar *dash;
gs_details_page_set_state (self, GS_DETAILS_PAGE_STATE_LOADING);
g_clear_object (&self->app_local_file);
+ g_clear_object (&self->app);
+
+ dash = strrchr (url, '/');
+ if (dash)
+ dash++;
+ gs_details_page_set_header_label (self, dash);
+
plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_URL_TO_APP,
"search", url,
"refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON |
@@ -2726,6 +2801,14 @@ gs_details_page_dispose (GObject *object)
g_signal_handlers_disconnect_by_func (self->app, gs_details_page_progress_changed_cb, self);
g_clear_object (&self->app);
}
+ if (self->plugin_loader && self->loading_status_handler_id) {
+ g_signal_handler_disconnect (self->plugin_loader, self->loading_status_handler_id);
+ self->loading_status_handler_id = 0;
+ }
+ if (self->loading_progress_pulse_id != 0) {
+ g_source_remove (self->loading_progress_pulse_id);
+ self->loading_progress_pulse_id = 0;
+ }
g_clear_object (&self->app_local_file);
g_clear_object (&self->builder);
g_clear_object (&self->plugin_loader);
@@ -2820,8 +2903,9 @@ gs_details_page_class_init (GsDetailsPageClass *klass)
gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, button_review);
gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, list_box_reviews);
gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, scrolledwindow_details);
- gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, spinner_details);
gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, spinner_remove);
+ gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, loading_progressbar);
+ gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, loading_label);
gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, stack_details);
gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, grid_details_kudo);
gtk_widget_class_bind_template_child (widget_class, GsDetailsPage, image_details_kudo_docs);
diff --git a/src/gs-details-page.ui b/src/gs-details-page.ui
index f86674fe..b006fb31 100644
--- a/src/gs-details-page.ui
+++ b/src/gs-details-page.ui
@@ -23,14 +23,24 @@
<class name="dim-label"/>
</style>
<child>
- <object class="GtkSpinner" id="spinner_details">
+ <object class="GtkProgressBar" id="loading_progressbar">
<property name="visible">True</property>
- <property name="width_request">32</property>
- <property name="height_request">32</property>
+ <property name="width_request">480</property>
<property name="halign">center</property>
- <property name="valign">center</property>
- <property name="hexpand">True</property>
- <property name="vexpand">True</property>
+ <property name="fraction">0.0</property>
+ <property name="margin_top">8</property>
+ <style>
+ <class name="upgrade-progressbar"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="loading_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Loading Application Details…</property>
+ <attributes>
+ <attribute name="scale" value="1.4"/>
+ </attributes>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]