Skip to content

Mod install - Add a Browse Mods page for NexusMods and itch.io - #127

Merged
Tapawingo merged 1 commit into
mainfrom
feature/browse-mods
Sep 23, 2026
Merged

Tapawingo merged 1 commit into
mainfrom
feature/browse-mods

Conversation

@Tapawingo

Copy link
Copy Markdown
Owner

What does this PR do?

Installing a mod used to mean pasting its URL into a modal. This adds a "Browse Mods"
button (next to Add Mod) that opens NexusMods' or itch.io's own Foxhole pages in an
embedded browser instead — a full page (swapped into MainWindow's bodyStack, the same
way Settings is), not a modal, since browsing is naturally a multi-download session.
Installing a mod is then just downloading it like normal:

  • Clicking "Mod Manager Download" on NexusMods redeems the nxm:// link the same way the
    existing download flow already does.
  • Any other captured download (a plain Nexus link, or an itch.io download button) is
    matched against the page's URL to fetch real metadata (author, upload date, etc.) before
    installing, so the mod is update-checkable like one added the old way — falling back to
    just the filename if that lookup fails, rather than losing the download.
  • Install feedback is a small auto-dismissing ToastWidget instead of a blocking dialog,
    so the user can keep browsing and grab several mods in one session.

Also along the way:

  • Fixes ItchClient::getGameId() reading an author from a "user" object that doesn't
    exist in itch's data.json response (the real field is "authors", an array) — this
    bug predates this PR and affected the existing itch download flow too.
  • Adds BrowserWidget::warmUp(), called shortly after the main window shows, so
    Chromium's one-time engine-startup cost is paid in the background instead of during the
    user's first browser open.
  • Fixes BrowserWidget's download-progress bar being squeezable to a sliver by a
    long/ugly download name (no max-width/eliding before); it's also now driven by
    API-based downloads (the nxm:// redeem path) via showExternalDownload(), not just
    browser-captured ones, so both show the same live progress instead of a static toast.
  • Fixes ModInstallHelper (new in this PR, factored out of AddModModalContent's
    archive-extraction/multi-pak-selection pattern for installing a single downloaded file)
    always reporting an install as successful regardless of whether
    ModManager::addModAsync() actually succeeded.

How was it tested?

  • Full builds + ctest pass on both platforms this was verified against: Windows (MSVC,
    Release) and Ubuntu 24.04 (WSL, Debug), both via Qt 6.10.1 kits with the WebEngine
    module. ui_smoke launches the real app successfully on both.
  • Manually tested live against real NexusMods and itch.io accounts on Windows through
    several rounds of iteration: the nxm:// redeem path, a direct Nexus download, and an
    itch.io download all land as correctly-installed mods with author metadata populated
    (verified via debug logging against the live API responses, which is how the
    ItchClient bug above was actually found and confirmed fixed).
  • Not independently re-verified on Linux or macOS against a live NexusMods/itch.io
    account (Linux verification above is build/test-suite only).

Checklist

  • I have read and understood the contribution guidelines
  • PR title follows the format: area - Add|Fix|Improve|Change|Make|Remove {changes}

Installing a mod used to mean pasting its URL. Now there's a "Browse Mods" button
that opens NexusMods' or itch.io's own Foxhole pages in an embedded browser (full
page, swapped into MainWindow's bodyStack like Settings) — installing is then just
downloading like normal, no URL needed.

- Add BrowseModsWidget (src/views/mod_manager/), hosting BrowserWidget with a
  NexusMods/itch.io tab switch. An nxm:// "Mod Manager Download" link is redeemed
  the same way the existing download flow does; any other captured download is
  matched against the page's URL (NexusUrlParser/ItchUrlParser) to fetch real
  metadata (author, upload date, etc.) before installing, falling back to just the
  filename if that fails rather than losing the download.
- Add ModInstallHelper, factoring AddModModalContent's archive-extraction and
  multi-pak-selection pattern out for this single-file case.
- Add ToastWidget, a small auto-dismissing banner, for install feedback that
  doesn't interrupt an ongoing multi-download browsing session the way a modal would.
- Fix ItchClient::getGameId() reading an author from a "user" object that doesn't
  exist in itch's data.json response; the real field is "authors" (an array).
- Add BrowserWidget::warmUp(), called shortly after the main window shows, so the
  Chromium engine's one-time startup cost is paid in the background instead of
  during the user's first browser open.
- Give BrowserWidget's download bar a maximum width with elided text (a long/ugly
  name could otherwise squeeze the progress bar to a sliver) and drive it from
  external (API-based) downloads too via showExternalDownload()/
  updateExternalDownloadProgress(), so the nxm:// redeem path shows the same live
  progress bar as a browser-captured one instead of a static toast.
- Fix ModInstallHelper always reporting an install as successful regardless of
  whether ModManager::addModAsync() actually succeeded.
@Tapawingo Tapawingo added type: feature Implement a new feature. area: mod install Add/install mods (local .pak/.zip, import flows). source: nexusmods Nexus-specific behavior, APIs, IDs, auth, downloads. source: itch.io Itch-specific behavior, keys, downloads, metadata. labels Sep 23, 2026
@Tapawingo
Tapawingo merged commit 2416256 into main Sep 23, 2026
14 checks passed
@Tapawingo
Tapawingo deleted the feature/browse-mods branch September 23, 2026 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: mod install Add/install mods (local .pak/.zip, import flows). source: itch.io Itch-specific behavior, keys, downloads, metadata. source: nexusmods Nexus-specific behavior, APIs, IDs, auth, downloads. type: feature Implement a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant