Skip to content

Downloads UI Architecture & Views

The Downloads UI in GenHub provides a responsive, desktop-optimized interface for browsing, filtering, inspecting, and installing community modifications, patches, game clients, and tools. Built with Avalonia UI and CommunityToolkit MVVM, it replaces legacy publisher card interfaces with a unified master-detail browser experience.

For pipeline architecture, background downloading, and service mechanics, see the Downloads Feature Guide.


Component Architecture

The Downloads UI consists of seven specialized Avalonia views and dialogs coordinated by MVVM ViewModels:


1. DownloadsBrowserView

Source: GenHub/Features/Downloads/Views/DownloadsBrowserView.axaml
DataContext: DownloadsBrowserViewModel

DownloadsBrowserView is the primary tab view. It is structured around an Avalonia SidebarLayout containing a collapsible publisher pane and a main scrollable content area.

Visual Structure

  1. Left Sidebar Pane (SidebarLayout):

    • Displays available publishers: built-in static providers (Generals Online, TheSuperHackers, Community Outpost), built-in dynamic providers (GitHub), and user-subscribed creator catalogs.
    • Each item displays the publisher logo (via infraControls:ImageLoader), publisher display name, and content count badge.
    • Footer contains a "Manifests Folder" button (OpenManifestsFolderCommand) to open local manifests in file manager.
  2. Top Header & Toolbar:

    • Page title dynamically displaying the selected publisher's name.
    • Search box (TextBox.search-box) with two-way binding to SearchTerm and reactive search debouncing.
    • Filter toggle button (ToggleButton.filter-toggle-btn) visible when the active publisher supports filtering (CanShowFilters).
    • Refresh button and in-flight loading spinners.
  3. Flyout Filter Panel:

    • Embeds FilterPanelView, bound to CurrentFilterViewModel.
    • Slides down or toggles open when the user clicks the Filter button.
  4. Content Cards Grid:

    • An adaptive responsive grid presenting ContentCardView cards for each item in ContentItems.
    • Handles empty states ("No content found") and loading shimmer indicators.
  5. Load More Footer:

    • Displays a "Load More" button when CanLoadMore is true and more content is available from the publisher.
  6. Detail View Modal Layer:

    • Renders ContentDetailView in a full overlay when IsDetailViewVisible is true (SelectedContent != null).

2. ContentCardView

Source: GenHub/Features/Downloads/Views/ContentCardView.axaml
DataContext: ContentGridItemViewModel

ContentCardView represents an individual downloadable item in the browser grid.

Key Card Elements

  • Preview Media: Thumbnail image with fallback icon when no screenshot is provided.
  • Header Badges:
    • Content Type Badge: Styled using ContentTypeToBrushConverter (for border and foreground text against CardBackground) to visually identify Mod, Patch, GameClient, Tool, Map, etc. (Tinted background via ContentTypeToBadgeBackgroundConverter is featured in ContentDetailView).
    • Publisher Identifier: Pill identifying the source publisher.
  • Title & Description: Title with two-line character ellipsis truncation, and clean summary text formatted by ReleaseDescriptionHelper.
  • Variant Selector: Dropdown selector displayed when HasVariants is true (e.g. resolution variants, game-client variants for Generals vs Zero Hour).
  • Bundle Components Indicator: Displays component count and individual completion status when HasBundleComponents is true.
  • State-Driven Action Buttons:
    • Download Button (visible when CurrentState == NotDownloaded): Triggers DownloadContentCommand via IContentDownloadCoordinator.
    • Progress Indicator (visible when IsDownloading == true): Displays live progress bar and status text (DownloadStatus).
    • Update Available Button (visible when CurrentState == UpdateAvailable): Orange highlight to acquire the latest version.
    • Add to Profile Button (visible when CurrentState == Downloaded): Opens ProfileSelectionView modal.

3. ContentDetailView

Source: GenHub/Features/Downloads/Views/ContentDetailView.axaml
DataContext: ContentDetailViewModel

ContentDetailView provides an immersive modal overlay with tabbed navigation, rich media carousels, and version management.

Tab Organization

  1. Overview Tab:
    • Hero banner and screenshot carousel.
    • Rich Markdown description rendered via Markdown.Avalonia.
    • Markdown Security: Employs SafeMarkdownHyperlinkCommand (restricting navigation strictly to HTTP/HTTPS URLs) and SafeMarkdownPathResolver to prevent arbitrary URL scheme execution or UNC exploits.
  2. Releases Tab:
    • Detailed list of releases, changelogs, file sizes, and release dates.
  3. Addons Tab:
    • Discovered compatible addons, map packs, and complementary files.
  4. Dynamic Custom Tabs:
    • Populated dynamically at runtime via ITabProviderRegistry and CatalogTabProvider.
    • Allows creator catalogs to define dedicated documentation, server configuration, or extra information tabs directly in their catalog.json.

4. FilterPanelView

Source: GenHub/Features/Downloads/Views/FilterPanelView.axaml
DataContext: IFilterPanelViewModel (e.g. GitHubFilterViewModel, CommunityOutpostFilterViewModel, SuperHackersFilterViewModel)

Provides a collapsible drawer of publisher-specific filters.

  • Reactive Filtering: Raising FiltersApplied updates the content collection without full-page reloads.
  • Clear All Filters: Resets filters to defaults and re-runs the baseline discovery query.

5. ProfileSelectionView

Source: GenHub/Features/Downloads/Views/ProfileSelectionView.axaml
DataContext: ProfileSelectionViewModel

A modal dialog that appears when a user clicks "Add to Profile" on downloaded content.

  • Game Compatibility Categorization:
    • Compatible Profiles: Highlighted profiles matching the content's target game (Generals or Zero Hour).
    • Other Profiles: Incompatible profiles shown with cautionary badges to avoid accidental cross-game attachment.
  • Direct Command Selection: Directly binds SelectProfileCommand with the selected ProfileOptionViewModel parameter.
  • Quick Create Profile: Allows one-click creation of a new game profile preconfigured with the downloaded content.

6. DependencyPreviewView

Source: GenHub/Features/Downloads/Views/DependencyPreviewView.axaml
DataContext: DependencyPreviewViewModel

Shown before attaching content to a profile if unresolved dependencies or conflicts exist.

  • Displays hierarchical dependency requirements (e.g. requires specific patches or base clients).
  • Highlights already satisfied dependencies vs missing dependencies that must be downloaded first.

7. SubscriptionConfirmationDialog

Source: GenHub/Features/Downloads/Views/SubscriptionConfirmationDialog.axaml
DataContext: SubscriptionConfirmationViewModel

Modal dialog displayed when the application intercepts a genhub://subscribe?url=<catalog_url> protocol link or when the user enters a catalog subscription URL manually.

  • Fetches and previews catalog metadata (publisher name, avatar, catalog version, description, content item count) using CatalogDocumentReader.
  • Confirms user intent before saving the subscription to IPublisherSubscriptionStore.

UI Converters and Theme Resources

The Downloads UI utilizes several custom Avalonia converters located in GenHub.Infrastructure.Converters:

ConverterTypeRole in Downloads UI
ContentTypeToBrushConverterIValueConverterTranslates ContentType enum values into vivid accent brushes for badge borders, text, and card outlines.
ContentTypeToBadgeBackgroundConverterIValueConverterProduces a 14.5% opacity tinted background brush (alpha 0x25 / 37) matching the content type accent color.
ProfileSelectionConverterIMultiValueConverterLegacy multi-value converter packaging content item and target GameProfile into command parameters for profile assignment.
SafeMarkdownHyperlinkCommandICommandSanitizes markdown hyperlinks to ensure only external HTTP/HTTPS browser links can be triggered.

All styling tokens, including brush keys (SurfaceElevatedBrush, SurfaceHoverBrush, AccentBrush, BorderBrush), are defined in GenHub/Assets/Styles/ThemeResources.axaml.

GeneralsHub Docs