Skip to content

Downloads Flow

NOTE

This document details the Unified Downloads User Flow implemented in PR #443 (feat/downloads-browser, carved from PR #265 feat/ui-downloads), illustrating how user interaction in DownloadsBrowserViewModel connects with discovery, resolution, state tracking via ContentStateService, background download coordination via ContentDownloadCoordinator, and game profile integration.

This flowchart details the complete user journey from browsing publishers to downloading, verifying, and adding content to profiles, including state management, deduplication, and caching.


Table of Contents

  1. User Browsing Flow
  2. Content State Management
  3. Publisher Selection
  4. Content Acquisition Flow
  5. Profile Selection Flow
  6. Roadmap & External Web Scraper Pipeline
  7. Content Caching Layer
  8. Key Components
  9. Error Handling

User Browsing Flow


Content State Management

The ContentStateService centralizes content state determination for UI display, enabling the Downloads browser to show appropriate buttons (Download, Update, Add to Profile) based on local manifest presence.

State Transitions

ContentStateService Mechanics

Location: GenHub/Features/Downloads/Services/ContentStateService.cs

The service uses the 5-segment manifest ID structure to correlate content versions:

text
Format: schemaVersion.userVersion.publisher.contentType.contentName
Example: 1.20240315.superhackers.patch.generals

Detection Logic:

  1. Exact Match: Generates prospective manifest ID using ManifestIdGenerator.GeneratePublisherContentId(publisher, contentType, name, releaseDate) and checks IContentManifestPool.IsManifestAcquiredAsync(id).
  2. Update Detection: Searches for local manifests with matching publisher, contentType, and contentName but older userVersion.
  3. State Evaluation:
    • Downloaded: Exact match found in manifest pool.
    • UpdateAvailable: Older version found in pool.
    • NotDownloaded: No matching version found.
csharp
var state = await contentStateService.GetStateAsync(searchResult);
switch (state)
{
    case ContentState.NotDownloaded:
        // Show Download button
        break;
    case ContentState.UpdateAvailable:
        // Show Update button (orange accent)
        break;
    case ContentState.Downloaded:
        // Show "Add to Profile" button
        break;
}

Content State Sequence Diagram


Publisher Selection


Content Acquisition Flow

This sequence diagram illustrates the coordinated download pipeline managed by ContentDownloadCoordinator:


Profile Selection Flow

The ProfileSelectionViewModel provides compatibility filtering for game profiles, showing compatible profiles first and flagging incompatible profiles with warnings to prevent accidental cross-game attachment.

Profile Selection Sequence Diagram


Roadmap & External Web Scraper Pipeline

Web-scraping discoverers for external repositories (ModDB, CNC Labs, AOD Maps) are part of GenHub's content ingestion architecture:

  • ModDB Web Ingestion: Uses Playwright for JavaScript rendering and AngleSharp for structured HTML extraction. Supports persistent browser cookies for Cloudflare clearance.
  • Section Parsing: Handles separate /downloads and /addons sections with FileSectionType.Downloads vs FileSectionType.Addons.
  • Planned Browser Integration: Once scraper sandboxes are finalized, these providers will be added to the downloads browser sidebar alongside static partners.

Content Caching Layer

The ContentCacheService provides an in-memory cache for parsed content with a configurable TTL (Time To Live). This reduces redundant network traffic and page parsing.

Cache Architecture


Key Components

DownloadsBrowserViewModel

Location: GenHub/Features/Downloads/ViewModels/DownloadsBrowserViewModel.cs

Property / CommandTypePurpose
PublishersObservableCollection<PublisherItemViewModel>Available content sources
SelectedPublisherPublisherItemViewModel?Currently selected publisher
ContentItemsObservableCollection<ContentGridItemViewModel>Discovered content items
CurrentFilterViewModelIFilterPanelViewModel?Publisher-specific filter model
DownloadContentCommandIAsyncRelayCommandInitiates content acquisition
AddContentToProfileCommandIAsyncRelayCommandOpens profile selection modal and attaches content
ViewContentCommandIRelayCommandOpens content detail view overlay

ContentDownloadCoordinator

Location: GenHub/Features/Downloads/Services/ContentDownloadCoordinator.cs

MethodReturn TypePurpose
DownloadContentAsyncTask<OperationResult<ContentManifest>>Deduplicates in-flight downloads, multiplexes progress, acquires content via IContentOrchestrator, and updates ContentStateService.
IsDownloadingboolChecks whether content is actively downloading.
TryGetDownloadProgressboolRetrieves current progress percentage and message for in-flight tasks.

ContentGridItemViewModel

Location: GenHub/Features/Downloads/ViewModels/ContentGridItemViewModel.cs

PropertyConditionPurpose
ShowDownloadButtonCurrentState == NotDownloadedShows download action
ShowUpdateButtonCurrentState == UpdateAvailableShows update action
ShowAddToProfileButtonCurrentState == DownloadedShows profile addition action
CanDownload!IsDownloaded && !IsDownloadingEnables download button

Filter ViewModels

Location: GenHub/Features/Downloads/ViewModels/Filters/

PublisherFilter ViewModelCapabilities
GitHubGitHubFilterViewModelSort order (recent, popular), release types
Community OutpostCommunityOutpostFilterViewModelContent type (tools vs. patches)
TheSuperHackersSuperHackersFilterViewModelGame client vs. patch releases
Static CuratedStaticPublisherFilterViewModelContent type and target game

ContentStateService

Location: GenHub/Features/Downloads/Services/ContentStateService.cs

Method / EventPurpose
GetStateAsync(item)Evaluates state (NotDownloaded, UpdateAvailable, Downloaded)
GetStateByManifestIdAsync(manifestId)Checks state for a specific manifest ID
NotifyStateChanged(contentId, newState)Broadcasts state updates to UI subscribers
ContentStateChangedEvent raised when content state changes

Error Handling


GeneralsHub Docs