Skip to content

Commit def46e8

Browse files
fix(ui): hide platform-mapping filters that have no options (#247)
Category and Family are populated from IGDB platform metadata that RomM often leaves empty, so their filter rows showed only "All" and did nothing. Build each metadata filter's values via distinctPlatformValues and only show the row when it has at least one value (Generation gated the same way).
1 parent 19e7a88 commit def46e8

2 files changed

Lines changed: 83 additions & 28 deletions

File tree

ui/settings_platform_mapping.go

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@ func NewPlatformMappingScreen() *PlatformMappingScreen {
4343
return &PlatformMappingScreen{}
4444
}
4545

46+
// distinctPlatformValues returns the sorted, deduplicated, non-empty values produced
47+
// by get across platforms. An empty result means the corresponding metadata filter has
48+
// no options and should be hidden rather than shown as an "All"-only picker.
49+
func distinctPlatformValues(platforms []romm.Platform, get func(romm.Platform) string) []string {
50+
set := make(map[string]bool)
51+
for _, p := range platforms {
52+
if v := get(p); v != "" {
53+
set[v] = true
54+
}
55+
}
56+
values := make([]string, 0, len(set))
57+
for v := range set {
58+
values = append(values, v)
59+
}
60+
slices.Sort(values)
61+
return values
62+
}
63+
4664
func (s *PlatformMappingScreen) Draw(input PlatformMappingInput) (PlatformMappingOutput, error) {
4765
logger := gaba.GetLogger()
4866
output := PlatformMappingOutput{Action: PlatformMappingActionBack, Mappings: make(map[string]internal.DirectoryMapping)}
@@ -223,17 +241,7 @@ func (s *PlatformMappingScreen) Draw(input PlatformMappingInput) (PlatformMappin
223241
}
224242

225243
// Build dynamic list of categories present in rommPlatforms
226-
categorySet := make(map[string]bool)
227-
for _, p := range rommPlatforms {
228-
if p.Category != "" {
229-
categorySet[p.Category] = true
230-
}
231-
}
232-
var uniqueCategories []string
233-
for c := range categorySet {
234-
uniqueCategories = append(uniqueCategories, c)
235-
}
236-
slices.Sort(uniqueCategories)
244+
uniqueCategories := distinctPlatformValues(rommPlatforms, func(p romm.Platform) string { return p.Category })
237245

238246
categoryOptions := []gaba.Option{
239247
{DisplayName: i18n.Localize(&goi18n.Message{ID: "filter_all", Other: "All"}, nil), Value: "all"},
@@ -250,17 +258,7 @@ func (s *PlatformMappingScreen) Draw(input PlatformMappingInput) (PlatformMappin
250258
}
251259

252260
// Build dynamic list of families present in rommPlatforms
253-
familySet := make(map[string]bool)
254-
for _, p := range rommPlatforms {
255-
if p.Family != "" {
256-
familySet[p.Family] = true
257-
}
258-
}
259-
var uniqueFamilies []string
260-
for f := range familySet {
261-
uniqueFamilies = append(uniqueFamilies, f)
262-
}
263-
slices.Sort(uniqueFamilies)
261+
uniqueFamilies := distinctPlatformValues(rommPlatforms, func(p romm.Platform) string { return p.Family })
264262

265263
familyOptions := []gaba.Option{
266264
{DisplayName: i18n.Localize(&goi18n.Message{ID: "filter_all", Other: "All"}, nil), Value: "all"},
@@ -298,27 +296,38 @@ func (s *PlatformMappingScreen) Draw(input PlatformMappingInput) (PlatformMappin
298296
},
299297
SelectedOption: boolToIndex(showGamesOnlySub),
300298
},
301-
{
299+
}
300+
301+
// Only show a metadata filter when RomM actually populated values for it —
302+
// otherwise it's a useless "All"-only picker (#247). Category/Family are
303+
// frequently empty (they require IGDB platform metadata); Generation usually
304+
// has values but is gated the same way for consistency.
305+
if len(uniqueCategories) > 0 {
306+
filterItems = append(filterItems, gaba.ItemWithOptions{
302307
Item: gaba.MenuItem{
303308
Text: i18n.Localize(&goi18n.Message{ID: "settings_category", Other: "Category"}, nil),
304309
},
305310
Options: categoryOptions,
306311
SelectedOption: categorySelectedIndex,
307-
},
308-
{
312+
})
313+
}
314+
if len(uniqueFamilies) > 0 {
315+
filterItems = append(filterItems, gaba.ItemWithOptions{
309316
Item: gaba.MenuItem{
310317
Text: i18n.Localize(&goi18n.Message{ID: "settings_family", Other: "Family"}, nil),
311318
},
312319
Options: familyOptions,
313320
SelectedOption: familySelectedIndex,
314-
},
315-
{
321+
})
322+
}
323+
if len(uniqueGenerations) > 0 {
324+
filterItems = append(filterItems, gaba.ItemWithOptions{
316325
Item: gaba.MenuItem{
317326
Text: i18n.Localize(&goi18n.Message{ID: "settings_generation", Other: "Generation"}, nil),
318327
},
319328
Options: generationOptions,
320329
SelectedOption: generationSelectedIndex,
321-
},
330+
})
322331
}
323332

324333
filterResult, err := gaba.OptionsList(
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package ui
2+
3+
import (
4+
"slices"
5+
"testing"
6+
7+
"grout/romm"
8+
)
9+
10+
// The platform-mapping filters (Category/Family) are built from the distinct values
11+
// present across platforms; when RomM doesn't populate a field, the list is empty and
12+
// the filter row must be hidden instead of showing a useless "All"-only picker (#247).
13+
func TestDistinctPlatformValues(t *testing.T) {
14+
platforms := []romm.Platform{
15+
{Category: "console", Family: "Nintendo"},
16+
{Category: "handheld", Family: "Nintendo"},
17+
{Category: "console", Family: "Sega"}, // duplicate category
18+
{Category: "", Family: ""}, // empty values are skipped
19+
}
20+
21+
gotCategory := distinctPlatformValues(platforms, func(p romm.Platform) string { return p.Category })
22+
if want := []string{"console", "handheld"}; !slices.Equal(gotCategory, want) {
23+
t.Errorf("category values = %v, want %v (sorted, deduped, no empties)", gotCategory, want)
24+
}
25+
26+
gotFamily := distinctPlatformValues(platforms, func(p romm.Platform) string { return p.Family })
27+
if want := []string{"Nintendo", "Sega"}; !slices.Equal(gotFamily, want) {
28+
t.Errorf("family values = %v, want %v", gotFamily, want)
29+
}
30+
}
31+
32+
func TestDistinctPlatformValues_AllEmptyHidesFilter(t *testing.T) {
33+
// RomM returned no category/family metadata for any platform: the result is empty,
34+
// which is the signal to hide the filter entirely.
35+
platforms := []romm.Platform{
36+
{Category: "", Family: "", Generation: 3},
37+
{Category: "", Family: "", Generation: 4},
38+
}
39+
40+
if got := distinctPlatformValues(platforms, func(p romm.Platform) string { return p.Category }); len(got) != 0 {
41+
t.Errorf("expected no category values (filter hidden), got %v", got)
42+
}
43+
if got := distinctPlatformValues(platforms, func(p romm.Platform) string { return p.Family }); len(got) != 0 {
44+
t.Errorf("expected no family values (filter hidden), got %v", got)
45+
}
46+
}

0 commit comments

Comments
 (0)