From b2a62f8e178e1f3e5fdbb58c4d35b8714f33626d Mon Sep 17 00:00:00 2001 From: LynithDev <61880709+LynithDev@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:39:37 +0200 Subject: [PATCH] feat: list required dependencies in the browser versions page (#889) --- .../src/view/app/browser/package/mod.rs | 23 ++++++++++++++---- .../src/view/app/browser/package/panels.rs | 24 ++++++++++++++++++- .../src/packages/dependencies.rs | 1 + .../src/packages/provider/curseforge.rs | 1 + .../src/packages/provider/modrinth.rs | 1 + .../oneclient_content/src/packages/types.rs | 2 ++ 6 files changed, 47 insertions(+), 5 deletions(-) diff --git a/packages/oneclient_app/src/view/app/browser/package/mod.rs b/packages/oneclient_app/src/view/app/browser/package/mod.rs index 8c252900..c545ea34 100644 --- a/packages/oneclient_app/src/view/app/browser/package/mod.rs +++ b/packages/oneclient_app/src/view/app/browser/package/mod.rs @@ -1,13 +1,16 @@ use freya::prelude::*; +use std::collections::HashMap; + +use oneclient_content::packages::types::DependencyKind; use oneclient_content::packages::{ContentType, ProviderId}; use crate::components::{ScrollArea, use_shared_delete}; use crate::hooks::use_cluster; use crate::hooks::{ - bundles_with_status_items, cluster_content_items, content_type_for_slug, project_detail, - use_browser_compat, use_bundles_with_status, use_cluster_content, use_dispatch, - use_installs_snapshot, use_link_confirm, use_package_project, use_package_versions, - version_list, versions_total, + bundles_with_status_items, cluster_content_items, content_type_for_slug, package_meta_batch, + project_detail, use_browser_compat, use_bundles_with_status, use_cluster_content, + use_dispatch, use_installs_snapshot, use_link_confirm, use_package_meta_batch, + use_package_project, use_package_versions, version_list, versions_total, }; use crate::theme::colors; use crate::ui::border_all_color; @@ -197,6 +200,17 @@ impl Component for BrowserPackage { let versions = version_list(&versions_query); let total_versions = versions_total(&versions_query); + let dependency_ids: Vec = versions + .iter() + .flat_map(|v| &v.dependencies) + .filter(|d| d.kind == DependencyKind::Required) + .filter_map(|d| d.project_id.clone()) + .collect(); + let dependency_names: HashMap = + package_meta_batch(&use_package_meta_batch(provider, dependency_ids)) + .into_iter() + .map(|(id, meta)| (id, meta.name)) + .collect(); let latest_version = preferred_version(&versions, content_type).map(|v| v.version_id.clone()); @@ -215,6 +229,7 @@ impl Component for BrowserPackage { versions, total_versions, versions_page, + dependency_names, project.id.clone(), installer.clone(), on_remove, diff --git a/packages/oneclient_app/src/view/app/browser/package/panels.rs b/packages/oneclient_app/src/view/app/browser/package/panels.rs index 42400e6b..38478964 100644 --- a/packages/oneclient_app/src/view/app/browser/package/panels.rs +++ b/packages/oneclient_app/src/view/app/browser/package/panels.rs @@ -1,7 +1,9 @@ use super::*; use oneclient_content::packages::markdown::normalize_markdown; -use oneclient_content::packages::types::{PackageBody, ProjectDetail, ReleaseType, VersionSummary}; +use oneclient_content::packages::types::{ + DependencyKind, PackageBody, ProjectDetail, ReleaseType, VersionSummary, +}; use crate::components::{ Button, Icon, IconType, Markdown, MarkdownStyle, Segment, SegmentedControl, @@ -105,6 +107,7 @@ pub(super) fn versions_panel( versions: Vec, total_versions: usize, versions_page: State, + dependency_names: HashMap, project_id: String, installer: Installer, on_remove: EventHandler<(String, String)>, @@ -141,6 +144,7 @@ pub(super) fn versions_panel( .is_some_and(|installed| installed.is_duplicated()); version_row( v, + &dependency_names, project_id.clone(), installer.clone(), on_remove.clone(), @@ -211,8 +215,10 @@ fn version_pager(current: usize, total_pages: usize, page: State) -> impl .into_element() } +#[allow(clippy::too_many_arguments)] fn version_row( v: VersionSummary, + dependency_names: &HashMap, project_id: String, installer: Installer, on_remove: EventHandler<(String, String)>, @@ -233,6 +239,13 @@ fn version_row( parts.join(" ยท ") }; let has_chips = !chips.is_empty(); + let requires: Vec<&str> = v + .dependencies + .iter() + .filter(|d| d.kind == DependencyKind::Required) + .filter_map(|d| d.project_id.as_deref()) + .map(|id| dependency_names.get(id).map_or(id, String::as_str)) + .collect(); rect() .horizontal() @@ -259,6 +272,15 @@ fn version_row( .color(colors::fg_primary()), ) .maybe(has_chips, |el| el.child(pill_flow(&chips, 10))) + .maybe(!requires.is_empty(), |el| { + el.child( + label() + .text(format!("Requires {}", requires.join(", "))) + .font_size(11.) + .max_lines(2) + .color(colors::fg_secondary()), + ) + }) .child( label() .text(stats) diff --git a/packages/oneclient_content/src/packages/dependencies.rs b/packages/oneclient_content/src/packages/dependencies.rs index 9e3d89f2..19e12317 100644 --- a/packages/oneclient_content/src/packages/dependencies.rs +++ b/packages/oneclient_content/src/packages/dependencies.rs @@ -299,6 +299,7 @@ mod tests { loaders, downloads: 0, file_size: 0, + dependencies: Vec::new(), } } diff --git a/packages/oneclient_content/src/packages/provider/curseforge.rs b/packages/oneclient_content/src/packages/provider/curseforge.rs index cb935117..1fa2fa0d 100644 --- a/packages/oneclient_content/src/packages/provider/curseforge.rs +++ b/packages/oneclient_content/src/packages/provider/curseforge.rs @@ -707,6 +707,7 @@ impl From for VersionSummary { .collect(), downloads: f.download_count, file_size: f.file_length, + dependencies: f.dependencies.into_iter().map(Into::into).collect(), } } } diff --git a/packages/oneclient_content/src/packages/provider/modrinth.rs b/packages/oneclient_content/src/packages/provider/modrinth.rs index 05e27a42..84eb4aa8 100644 --- a/packages/oneclient_content/src/packages/provider/modrinth.rs +++ b/packages/oneclient_content/src/packages/provider/modrinth.rs @@ -753,6 +753,7 @@ impl From for VersionSummary { .collect(), downloads: v.downloads, file_size, + dependencies: v.dependencies.into_iter().map(Into::into).collect(), } } } diff --git a/packages/oneclient_content/src/packages/types.rs b/packages/oneclient_content/src/packages/types.rs index e68677ab..6c668659 100644 --- a/packages/oneclient_content/src/packages/types.rs +++ b/packages/oneclient_content/src/packages/types.rs @@ -140,6 +140,8 @@ pub struct VersionSummary { pub loaders: Vec, pub downloads: u64, pub file_size: u64, + #[serde(default)] + pub dependencies: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize)]