Skip to content

fix(platforms): hide empty platforms behind a toolbar filter - #3982

Merged
gantoine merged 3 commits into
masterfrom
fix/platforms-index-hide-empty
Jul 29, 2026
Merged

fix(platforms): hide empty platforms behind a toolbar filter#3982
gantoine merged 3 commits into
masterfrom
fix/platforms-index-hide-empty

Conversation

@gantoine

Copy link
Copy Markdown
Member

Description
Explain the changes or enhancements you are proposing with this pull request.

#3945 switched the Platforms index from filledPlatforms to allPlatforms so empty (0-game) platforms would be reachable and therefore deletable (#3902). The side effect: every leftover platform row now renders in the grid. Users who keep large exclude.platforms lists (excluded folders leave behind 0-game rows) went from a clean library to hundreds of stubs.

This keeps both properties:

  • Empty platforms are hidden by default again.
  • A new segmented toolbar cluster (Only platforms with games / Include empty platforms) reveals them on demand, so an empty platform can still be opened and removed through the existing Settings → Delete platform flow.

Details:

  • The filter is URL-synced as ?show=all, omitted at the default, matching the ?kind= / ?vis= pattern on the Collections index and the "active filters live in the URL" rule.
  • Header count and search run over the visible set.
  • The "no platforms found, run a scan" empty state now keys off allPlatforms, so it doesn't misfire when the filter is what's hiding everything. A library whose platforms are all empty gets a message pointing at the filter instead.
  • 4 new platform.json keys, translated across all 18 locales.

Note for context on the issue report: the reporter's exclude.platforms list was not wiped by the upgrade. _update_config_file rewrites the full list and there's no truncation path. Those platforms were never hidden by the exclusions themselves, only by the rom_count > 0 filter that #3945 removed.

Fixes #3979

Checklist
Please check all that apply.

  • I've tested the changes locally
  • I've updated relevant comments
  • I've assigned reviewers for this PR
  • I've added unit tests that cover the changes

Verification:

  • npm run test — 40 files, 580 tests pass
  • npm run typecheck — clean
  • trunk fmt && trunk check — no issues
  • python3 src/locales/check_i18n_locales.py and check_i18n_sorted.py — both pass

Not verified in a browser (developed in a worktree without a running app).

AI assistance disclosure

This change was written with AI assistance (Claude Code). I directed the investigation and reviewed the result; the implementation, translations, and tests were AI-generated.

Screenshots (if applicable)

n/a

🤖 Generated with Claude Code

The Platforms index switched to allPlatforms, so every leftover 0-game
platform row rendered in the grid, burying real libraries under hundreds
of stubs.

Empty platforms are hidden again by default and surface through a new
segmented toolbar cluster, URL-synced as ?show=all. They stay reachable
(and deletable) that way, so they don't become stranded in the database
again.

Fixes #3979

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 28, 2026 22:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread frontend/src/v2/views/PlatformsIndex.vue Outdated
@greptile-apps

greptile-apps Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a URL-synchronized platform visibility filter that hides empty platforms by default while keeping them accessible on demand.

  • Filters platform counts, search results, grouped views, and list/grid rendering against the selected visibility mode.
  • Distinguishes a genuinely empty library from platforms hidden by the default filter.
  • Adds unit coverage for default filtering, ?show=all, and the all-empty state.
  • Adds the four required strings across all supported locales.

Confidence Score: 3/5

The concurrent URL update path needs to be fixed before merging because toolbar interactions can discard each other's active query state.

The new visibility watcher independently snapshots route.query and calls router.replace, while existing search and view-mode watchers do the same; concurrent updates therefore overwrite one another and reset an active toolbar filter.

Files Needing Attention: frontend/src/v2/views/PlatformsIndex.vue

Fix All in Claude Code

Prompt To Fix All With AI
### Issue 1
frontend/src/v2/views/PlatformsIndex.vue:89
**Concurrent query updates overwrite filters**

When the platform segment and another URL-backed toolbar control update in the same reactive flush, each watcher copies the same stale `route.query` into a separate `router.replace`, so the later navigation drops the other control's parameter and resets its visible state.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(platforms): hide empty platforms beh..." | Re-trigger Greptile

gantoine and others added 2 commits July 28, 2026 18:41
…tomp

`router.replace` is async, so `route.query` keeps reading the pre-navigation
value. Two URL-backed controls changing in the same flush each built their
next query from that stale snapshot, and the second navigation won with a
query that never saw the first one's key.

Reachable today on the Collections index: picking the "virtual" kind also
clears the visibility filter in the same flush, and the clear dropped
`?kind=virtual`.

Route every writer (search, view mode, Platforms and Collections filters)
through `patchQuery`, which merges patches and issues one navigation per
tick.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mdi-select-all is a marquee-selection glyph, so it read as an action
rather than a filter state. mdi-asterisk carries the wildcard
"everything" meaning the segment actually has.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gantoine
gantoine merged commit 79a64c4 into master Jul 29, 2026
13 checks passed
@gantoine
gantoine deleted the fix/platforms-index-hide-empty branch July 29, 2026 01:06
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.

[Bug] All hidden platforms are showing in the new 5.1.0-beta.3

2 participants