Skip to content

Add batch DLL swap: select multiple games and apply in one pass - #913

Open
RafaelHGOliveira wants to merge 13 commits into
beeradmoore:mainfrom
RafaelHGOliveira:main
Open

RafaelHGOliveira wants to merge 13 commits into
beeradmoore:mainfrom
RafaelHGOliveira:main

Conversation

@RafaelHGOliveira

@RafaelHGOliveira RafaelHGOliveira commented Jul 19, 2026

Copy link
Copy Markdown

Description of Changes

Adds a selection mode to the games grid so several games can be updated in one operation, instead of opening each game individually.

Flow

1. Select in the toolbar enters selection mode — cards become checkable and a bar appears with the selection count, Select all, Apply DLL, Clear and Done.

Games grid in selection mode with six games selected

2. Apply DLL opens a picker listing every DLL type, each with a version dropdown, plus a preset dropdown for the three DLSS types. Every row defaults to Don't change, so nothing is touched unless it is explicitly chosen.

Apply DLL dialog with a version and preset dropdown per DLL type

3. Applying runs sequentially behind a progress dialog, then shows a summary: how many changes were made across how many games, how many were skipped, how many errored, and a separate count for changes that did not apply because a game does not ship that DLL type.

Batch swap summary listing each change that was applied

Notable details

  • The picker is game-agnostic — it offers what is downloaded locally, and per-game compatibility is resolved at apply time rather than by intersecting the selection up front. A game that cannot take a change is reported, not silently dropped.
  • Results distinguish three outcomes: swapped, skipped (something the user may want to act on) and error. "Game does not use that DLL type" is collapsed into a single count so it does not bury the actionable lines.
  • Failures that need elevation are aggregated into one "relaunch as admin" message rather than one per game.
  • All user-facing strings go through .resw / ResourceHelper. Only en-US is populated in this PR — the other locales fall back until translated.
  • No changes to GameAssetType numbering, the database schema, or the manifest.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Issues Resolved

Related to #157.

The design sketched in that issue is not followed exactly here — the differences I am aware of:

  • selection is not persisted across app restarts
  • no per-game opt-out inside the picker once games are selected
  • Select all is a plain toggle rather than tri-state
  • no bulk "reset to original DLL"

Happy to rework any of these, or to split the PR up, if the design in #157 is the direction you want to take. Opening it as a draft so there is something concrete to react to.

@RafaelHGOliveira
RafaelHGOliveira marked this pull request as ready for review July 19, 2026 22:55
@beeradmoore

Copy link
Copy Markdown
Owner

Hey @RafaelHGOliveira, thanks for pushing this. I just wanted to let you know I see this PR, I just have not had time to review it yet.

@lguerard

Copy link
Copy Markdown

Looking forward for that PR or a similar solution to be added to the amazing software !

@beeradmoore beeradmoore left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @RafaelHGOliveira , apologies for the long time to review. I still have not had time to do a full review yet but have left some notes on what I have seen so far. I have not run locally yet but looking at the screenshots I think this method will work. It is not what I had invisioned in #157, however I think this has many upsides (assuming filter + search will work while bulk editing) and may be preferred.

I had an idea from when you said these two things:

Every row defaults to Don't change, so nothing is touched unless it is explicitly chosen.

no bulk "reset to original DLL"

To add support for that could there be a row in there after "Don't Change" for "Restore original" (or "Restore original DLL") so that functinality could exist?

These are the pages I have not reviewed yet:

  • src/Pages/GameGridPageModel.cs
  • src/UserControls/BatchDllPickerControl.xaml
  • src/UserControls/BatchDllPickerControlModel.cs
  • src/UserControls/BatchDllRowModel.cs
  • src/UserControls/BatchSwapSummaryControl.xaml
  • src/UserControls/BatchSwapSummaryControlModel.cs

Comment thread src/Pages/GameGridPage.xaml Outdated
</AppBarButton.Content>
</AppBarButton>
<AppBarButton Icon="Filter" Label="{x:Bind ViewModel.TranslationProperties.FilterText, Mode=OneWay}" Command="{x:Bind ViewModel.FilterGamesButtonCommand}" IsEnabled="{x:Bind ViewModel.IsGameListLoading, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
<AppBarButton Label="{x:Bind ViewModel.TranslationProperties.SelectText, Mode=OneWay}" Command="{x:Bind ViewModel.ToggleSelectionModeCommand}" IsEnabled="{x:Bind ViewModel.IsGameListLoading, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "Select" is not clear what it is doing. "Bulk Update" and "Bulk Swap" may be a better fit, unsure if they will be too long though. (EDIT: Batch is another word to throw in there, but I am not sure if gamers understand what "batch update" will do as much as developers would)

Comment thread src/Pages/GameGridPage.xaml
@beeradmoore

Copy link
Copy Markdown
Owner

Also another question, does this select method work if we are in list mode and not grid mode for the games?

I would love to have this in before the v1.3 release with Streamline, DirectStorage, FSR4, etc. But I don't know when that is, and I don't know when you are free to look at the above. If it is it is, if it isn't it isn't. I will have to update this screen after that to add support for them. I think I'll be doing changes on the game page to clean up the DLL selection like adding grouping of technolgoies under tabs or something. I'll look at applying those same changes here so they both match.

Backups are only created on swap, so a current DLL with no .dlsss backup is the game's original. Report it as a not-applicable skip instead of an actionable one, and make the not-applicable summary text generic so it no longer claims every such change was for a DLL type the game does not use.
Translate the 41 bulk swap strings to pt-BR, rename the summary title from 'Batch swap' to 'Bulk swap' to match the toolbar, and drop General_Clear, which the 'Select none' rename left unused.
@RafaelHGOliveira

RafaelHGOliveira commented Sep 19, 2026

Copy link
Copy Markdown
Author

Thanks for the review @beeradmoore! I've pushed a follow-up that addresses the notes so far:

Toolbar / selection bar

  • "Select" is now Bulk Swap.
  • The bar now reads: X selected · Select all · Select none · Select DLLs (primary) · Close.
    • "Select all" only adds the currently visible games (it no longer toggles to deselect).
    • "Select none" clears the whole selection, including games hidden by search/filter.
    • "Select DLLs" opens the picker; nothing is applied until you confirm there.
    • I went with "Close" as text rather than a glyph so it reads consistently with the other buttons — happy to switch to the glyph if you prefer.

Filter + search while bulk editing

  • Search and the Filter dialog now stay enabled in selection mode (Add Game and the grid/list switch stay disabled).
  • Selections survive search/filter changes: games that get hidden stay selected and are still counted, and their checks come back when they are visible again. Applying a filter keeps the current search text.
  • With "group by library" on, a favourite appears twice (Favourites + its library). Selection is per game, so both appearances show the same state and it is counted once.

Restore original DLL

  • Every DLL row now offers Don't change → Restore original DLL → versions. Rows for FSR/XeSS are always shown, so a restore is possible even when no version of that type is downloaded.
  • A restore never triggers a download and uses the existing ResetDllAsync path. It can be combined with a preset change on the same row; each outcome is reported separately.
  • In the summary: a game whose DLL has no .dlsss backup already uses the original, so it goes into the "not applicable" count; a backup without a matching game DLL is reported as an error that needs a manual repair.

List mode
Yes — selection mode works on whichever view is active (grid or list). Switching between them is disabled while selecting, but you can enter selection mode from either.

Translations
The summary title now says "Bulk swap" too, to match the toolbar. I also added pt-BR for all the new strings (I'm a native speaker); the other locales still fall back to English until translated.

Screenshots

Toolbar with the new Bulk Swap button:

image1

Selection bar in bulk swap mode:

image2

DLL picker with the Restore original DLL option:

image3

Summary after a bulk restore:

image4

@beeradmoore

Copy link
Copy Markdown
Owner

I went with "Close" as text rather than a glyph so it reads consistently with the other buttons — happy to switch to the glyph if you prefer.

I think this was a good call.

Everything else looks great. I love the extra bug fixes added in as well. I can't wait to find time to re-review and get this merged in. Thanks for the amazing work @RafaelHGOliveira

Comment thread src/Pages/GameGridPage.xaml.cs Outdated
@beeradmoore

Copy link
Copy Markdown
Owner

Code wise this is all approved. I just need to test it and we should be good to go.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants