diff --git a/src/bz-entry.c b/src/bz-entry.c index 809d851f..5dd63836 100644 --- a/src/bz-entry.c +++ b/src/bz-entry.c @@ -99,7 +99,6 @@ typedef struct char *project_group; char *developer; char *developer_id; - GListModel *developer_apps; GListModel *screenshot_paintables; GListModel *screenshot_captions; GdkPaintable *thumbnail_paintable; @@ -167,7 +166,6 @@ enum PROP_PROJECT_GROUP, PROP_DEVELOPER, PROP_DEVELOPER_ID, - PROP_DEVELOPER_APPS, PROP_SCREENSHOT_PAINTABLES, PROP_SCREENSHOT_CAPTIONS, PROP_THUMBNAIL_PAINTABLE, @@ -206,11 +204,9 @@ BZ_DEFINE_DATA ( GWeakRef self; int prop; char *id; - char *developer; }, g_weak_ref_clear (&self->self); - BZ_RELEASE_DATA (id, g_free); - BZ_RELEASE_DATA (developer, g_free)); + BZ_RELEASE_DATA (id, g_free);); static DexFuture * query_flathub_fiber (QueryFlathubData *data); static DexFuture * @@ -350,10 +346,6 @@ bz_entry_get_property (GObject *object, case PROP_DEVELOPER_ID: g_value_set_string (value, priv->developer_id); break; - case PROP_DEVELOPER_APPS: - query_flathub (self, PROP_DEVELOPER_APPS); - g_value_set_object (value, priv->developer_apps); - break; case PROP_SCREENSHOT_PAINTABLES: g_value_set_object (value, priv->screenshot_paintables); break; @@ -557,10 +549,6 @@ bz_entry_set_property (GObject *object, g_clear_pointer (&priv->developer_id, g_free); priv->developer_id = g_value_dup_string (value); break; - case PROP_DEVELOPER_APPS: - g_clear_object (&priv->developer_apps); - priv->developer_apps = g_value_dup_object (value); - break; case PROP_SCREENSHOT_PAINTABLES: g_clear_object (&priv->screenshot_paintables); priv->screenshot_paintables = g_value_dup_object (value); @@ -850,13 +838,6 @@ bz_entry_class_init (BzEntryClass *klass) NULL, NULL, NULL, G_PARAM_READWRITE); - props[PROP_DEVELOPER_APPS] = - g_param_spec_object ( - "developer-apps", - NULL, NULL, - G_TYPE_LIST_MODEL, - G_PARAM_READWRITE); - props[PROP_SCREENSHOT_PAINTABLES] = g_param_spec_object ( "screenshot-paintables", @@ -2381,7 +2362,6 @@ query_flathub (BzEntry *self, g_weak_ref_init (&data->self, self); data->prop = prop; data->id = g_strdup (priv->id); - data->developer = g_strdup (priv->developer); future = dex_scheduler_spawn ( bz_get_io_scheduler (), @@ -2412,7 +2392,6 @@ query_flathub_fiber (QueryFlathubData *data) { int prop = data->prop; char *id = data->id; - char *developer = data->developer; g_autoptr (GError) local_error = NULL; g_autofree char *request = NULL; g_autoptr (JsonNode) node = NULL; @@ -2425,9 +2404,6 @@ query_flathub_fiber (QueryFlathubData *data) case PROP_TOTAL_DOWNLOADS: request = g_strdup_printf ("/stats/%s?all=false&days=175", id); break; - case PROP_DEVELOPER_APPS: - request = g_strdup_printf ("/collection/developer/%s", developer); - break; case PROP_FAVORITES_COUNT: request = g_strdup_printf ("/favorites/%s/count", id); break; @@ -2517,29 +2493,6 @@ query_flathub_fiber (QueryFlathubData *data) return dex_future_new_for_int (total_downloads); } break; - - case PROP_DEVELOPER_APPS: - { - JsonObject *response_obj = NULL; - JsonArray *apps_array = NULL; - g_autoptr (GtkStringList) app_ids = NULL; - - response_obj = json_node_get_object (node); - apps_array = json_object_get_array_member (response_obj, "hits"); - - app_ids = gtk_string_list_new (NULL); - for (guint i = 0; i < json_array_get_length (apps_array); i++) - { - JsonObject *app_obj = json_array_get_object_element (apps_array, i); - const char *app_id = json_object_get_string_member (app_obj, "app_id"); - - if (app_id != NULL) - gtk_string_list_append (app_ids, app_id); - } - - return dex_future_new_for_object (app_ids); - } - break; case PROP_FAVORITES_COUNT: { int favorites_count = 0; @@ -2815,7 +2768,6 @@ clear_entry (BzEntry *self) g_clear_pointer (&priv->project_group, g_free); g_clear_pointer (&priv->developer, g_free); g_clear_pointer (&priv->developer_id, g_free); - g_clear_object (&priv->developer_apps); g_clear_object (&priv->screenshot_paintables); g_clear_object (&priv->screenshot_captions); g_clear_object (&priv->thumbnail_paintable); diff --git a/src/bz-full-view.blp b/src/bz-full-view.blp index 13dc1ba6..c0fd9d9d 100644 --- a/src/bz-full-view.blp +++ b/src/bz-full-view.blp @@ -670,12 +670,15 @@ template $BzFullView: Adw.Bin { model: SliceListModel other_apps_model { offset: 0; size: 6; - model: bind $get_developer_apps_entries(template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>.developer-apps, template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>) as ; + model: FilterListModel { + model: bind template.developer-apps-model as ; + filter: CustomFilter is_group_equal_filter {}; + }; }; } Button { - visible: bind $is_longer(template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>.developer-apps, 6) as ; + visible: bind $is_longer(template.developer-apps-model, 6) as ; clicked => $more_apps_button_clicked_cb(template); halign: center; margin-top: 11; diff --git a/src/bz-full-view.c b/src/bz-full-view.c index ee00663f..b41169b1 100644 --- a/src/bz-full-view.c +++ b/src/bz-full-view.c @@ -66,6 +66,7 @@ struct _BzFullView BzResult *runtime; BzResult *group_model; gboolean show_sidebar; + GListModel *developer_apps_model; GMenuModel *main_menu; @@ -74,6 +75,7 @@ struct _BzFullView AdwViewStack *stack; GtkWidget *shadow_overlay; GtkToggleButton *description_toggle; + GtkCustomFilter *is_group_equal_filter; }; G_DEFINE_FINAL_TYPE (BzFullView, bz_full_view, ADW_TYPE_BIN) @@ -86,6 +88,7 @@ enum PROP_ENTRY_GROUP, PROP_UI_ENTRY, PROP_MAIN_MENU, + PROP_DEVELOPER_APPS_MODEL, LAST_PROP }; @@ -138,6 +141,9 @@ bz_full_view_get_property (GObject *object, case PROP_MAIN_MENU: g_value_set_object (value, self->main_menu); break; + case PROP_DEVELOPER_APPS_MODEL: + g_value_set_object (value, self->developer_apps_model); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -670,40 +676,29 @@ static void more_apps_button_clicked_cb (BzFullView *self, GtkButton *button) { - g_autoptr (GListModel) model = NULL; - guint n_items; - g_autofree char *title = NULL; - g_autofree char *subtitle = NULL; - AdwNavigationPage *apps_page = NULL; - GtkWidget *nav_view = NULL; - g_autoptr (GListModel) app_ids = NULL; - BzEntry *entry = NULL; - const char *developer = NULL; + guint n_items = 0; + g_autofree char *title = NULL; + g_autofree char *subtitle = NULL; + AdwNavigationPage *apps_page = NULL; + GtkWidget *nav_view = NULL; + const char *developer = NULL; g_return_if_fail (BZ_IS_FULL_VIEW (self)); g_return_if_fail (GTK_IS_BUTTON (button)); - entry = bz_result_get_object (self->ui_entry); - if (entry == NULL) + if (self->developer_apps_model == NULL) return; - g_object_get (entry, "developer-apps", &app_ids, NULL); + developer = bz_entry_group_get_developer (self->group); + n_items = g_list_model_get_n_items (self->developer_apps_model); - model = bz_application_map_factory_generate ( - bz_state_info_get_application_factory (self->state), - app_ids); - - n_items = g_list_model_get_n_items (model); - - developer = bz_entry_get_developer (entry); if (developer != NULL && *developer != '\0') - title = g_strdup_printf (_ ("Other Apps by %s"), developer); + title = g_strdup_printf (_ ("All Apps by %s"), developer); else - title = g_strdup (_ ("Other Apps")); - - subtitle = g_strdup_printf (ngettext ("%d Application", "%d Applications", n_items), n_items); + title = g_strdup (_ ("All Apps by developer")); - apps_page = bz_apps_page_new (title, model); + subtitle = g_strdup_printf (ngettext ("%d Application", "%d Applications", n_items), n_items); + apps_page = bz_apps_page_new (title, self->developer_apps_model); bz_apps_page_set_subtitle (BZ_APPS_PAGE (apps_page), subtitle); nav_view = gtk_widget_get_ancestor (GTK_WIDGET (self), ADW_TYPE_NAVIGATION_VIEW); @@ -948,6 +943,13 @@ get_description_toggle_text (gpointer object, return g_strdup (active ? _ ("Show Less") : _ ("Show More")); } +static gboolean +filter_own_group (BzEntryGroup *group, + BzFullView *self) +{ + return g_strcmp0 (bz_entry_group_get_id (group), bz_entry_group_get_id (self->group)) != 0; +} + static void copy_id_cb (BzFullView *self, GtkButton *button) @@ -1027,6 +1029,13 @@ bz_full_view_class_init (BzFullViewClass *klass) G_TYPE_MENU_MODEL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + props[PROP_DEVELOPER_APPS_MODEL] = + g_param_spec_object ( + "developer-apps-model", + NULL, NULL, + G_TYPE_LIST_MODEL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (object_class, LAST_PROP, props); signals[SIGNAL_UPDATE] = @@ -1068,6 +1077,7 @@ bz_full_view_class_init (BzFullViewClass *klass) gtk_widget_class_bind_template_child (widget_class, BzFullView, main_scroll); gtk_widget_class_bind_template_child (widget_class, BzFullView, shadow_overlay); gtk_widget_class_bind_template_child (widget_class, BzFullView, description_toggle); + gtk_widget_class_bind_template_child (widget_class, BzFullView, is_group_equal_filter); gtk_widget_class_bind_template_callback (widget_class, is_scrolled_down); gtk_widget_class_bind_template_callback (widget_class, format_favorites_count); gtk_widget_class_bind_template_callback (widget_class, format_recent_downloads); @@ -1093,6 +1103,7 @@ bz_full_view_class_init (BzFullViewClass *klass) gtk_widget_class_bind_template_callback (widget_class, format_leftover_label); gtk_widget_class_bind_template_callback (widget_class, format_other_apps_label); gtk_widget_class_bind_template_callback (widget_class, format_more_other_apps_label); + gtk_widget_class_bind_template_callback (widget_class, filter_own_group); gtk_widget_class_bind_template_callback (widget_class, get_developer_apps_entries); gtk_widget_class_bind_template_callback (widget_class, get_dev_apps_max_children_per_line); gtk_widget_class_bind_template_callback (widget_class, more_apps_button_clicked_cb); @@ -1117,10 +1128,21 @@ bz_full_view_class_init (BzFullViewClass *klass) gtk_widget_class_bind_template_callback (widget_class, debug_id_inspect_cb); } +static gboolean +is_group_equal_filter (BzEntryGroup *group, + BzFullView *self) +{ + return g_strcmp0 (bz_entry_group_get_id (group), bz_entry_group_get_id (self->group)) != 0; +} + static void bz_full_view_init (BzFullView *self) { gtk_widget_init_template (GTK_WIDGET (self)); + + gtk_custom_filter_set_filter_func ( + self->is_group_equal_filter, (GtkCustomFilterFunc) is_group_equal_filter, + self, NULL); } GtkWidget * @@ -1152,6 +1174,13 @@ on_ui_entry_resolved (DexFuture *future, return dex_future_new_for_boolean (TRUE); } +static gboolean +filter_by_developer (BzEntryGroup *group, + const char *developer) +{ + return g_strcmp0 (bz_entry_group_get_developer (group), developer) == 0; +} + void bz_full_view_set_entry_group (BzFullView *self, BzEntryGroup *group) @@ -1168,6 +1197,7 @@ bz_full_view_set_entry_group (BzFullView *self, g_clear_object (&self->ui_entry); g_clear_object (&self->runtime); g_clear_object (&self->group_model); + g_clear_object (&self->developer_apps_model); gtk_toggle_button_set_active (self->description_toggle, FALSE); if (group != NULL) @@ -1216,6 +1246,27 @@ bz_full_view_set_entry_group (BzFullView *self, } } + { + const char *developer = NULL; + GListModel *all_groups = NULL; + + developer = bz_entry_group_get_developer (group); + if (developer != NULL && *developer != '\0') + { + all_groups = bz_state_info_get_filtered_entry_groups ( + self->state); + + if (all_groups != NULL) + self->developer_apps_model = G_LIST_MODEL ( + gtk_filter_list_model_new ( + g_object_ref (all_groups), + GTK_FILTER (gtk_custom_filter_new ( + (GtkCustomFilterFunc) filter_by_developer, + g_strdup (developer), + g_free)))); + } + } + adw_view_stack_set_visible_child_name (self->stack, "content"); } else @@ -1225,6 +1276,7 @@ bz_full_view_set_entry_group (BzFullView *self, g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ENTRY_GROUP]); g_object_notify_by_pspec (G_OBJECT (self), props[PROP_UI_ENTRY]); + g_object_notify_by_pspec (G_OBJECT (self), props[PROP_DEVELOPER_APPS_MODEL]); } BzEntryGroup *