From 1840cfe759d0427c4093683b08d8be485f71fe4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 3 Mar 2026 12:55:14 +0100 Subject: [PATCH] Add bool flag for checking tag vote threshold & utilise as required Closes https://github.com/ppy/osu/issues/36453. My omission was in assuming that web was going to start filtering out the tags below the threshold from API responses, which is not the case. Whether or not the consumers want or not to display tags below threshold is subjective. I figured that the matchmaking card tooltip might want to display below threshold but I dunno. --- osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 12 ++++++++++-- osu.Game/Overlays/BeatmapSet/Info.cs | 2 +- .../MatchmakingSelectPanel.CardContentBeatmap.cs | 4 ++-- .../Select/RealmPopulatingOnlineLookupSource.cs | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index ed2a395fc9..0d3724a769 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -123,7 +123,15 @@ namespace osu.Game.Online.API.Requests.Responses /// public const int MINIMUM_USER_TAG_VOTES_FOR_DISPLAY = 5; - public (APITag Tag, int VoteCount)[] GetTopUserTags() + /// + /// Retrieves top user tags for the beatmap, ordered in a way matching osu!web. + /// Requires to be populated. + /// + /// + /// If , only tags above will be shown. + /// If , all tags regardless of vote count will be shown. + /// + public (APITag Tag, int VoteCount)[] GetTopUserTags(bool confirmedOnly) { if (TopTags == null || TopTags.Length == 0 || BeatmapSet?.RelatedTags == null) return []; @@ -132,7 +140,7 @@ namespace osu.Game.Online.API.Requests.Responses return TopTags .Select(t => (topTag: t, relatedTag: tagsById.GetValueOrDefault(t.TagId))) - .Where(t => t.relatedTag != null) + .Where(t => t.relatedTag != null && (!confirmedOnly || t.topTag.VoteCount >= MINIMUM_USER_TAG_VOTES_FOR_DISPLAY)) // see https://github.com/ppy/osu-web/blob/bb3bd2e7c6f84f26066df5ea20a81c77ec9bb60a/resources/js/beatmapsets-show/controller.ts#L103-L106 for sort criteria .OrderByDescending(t => t.topTag.VoteCount) .ThenBy(t => t.relatedTag!.Name) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index e25c1370c5..ca29724e83 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -129,7 +129,7 @@ namespace osu.Game.Overlays.BeatmapSet private void updateUserTags() { - userTags.Metadata = Beatmap.Value?.GetTopUserTags().Select(t => t.Tag.Name).ToArray(); + userTags.Metadata = Beatmap.Value?.GetTopUserTags(confirmedOnly: true).Select(t => t.Tag.Name).ToArray(); } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/OnlinePlay/Matchmaking/Match/BeatmapSelect/MatchmakingSelectPanel.CardContentBeatmap.cs b/osu.Game/Screens/OnlinePlay/Matchmaking/Match/BeatmapSelect/MatchmakingSelectPanel.CardContentBeatmap.cs index 55418a2eab..abe0b448a2 100644 --- a/osu.Game/Screens/OnlinePlay/Matchmaking/Match/BeatmapSelect/MatchmakingSelectPanel.CardContentBeatmap.cs +++ b/osu.Game/Screens/OnlinePlay/Matchmaking/Match/BeatmapSelect/MatchmakingSelectPanel.CardContentBeatmap.cs @@ -458,7 +458,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.BeatmapSelect new OsuSpriteText { Padding = new MarginPadding { Vertical = 3, Horizontal = 8 }, - Text = beatmap.GetTopUserTags().FirstOrDefault().Tag?.Name ?? string.Empty, + Text = beatmap.GetTopUserTags(confirmedOnly: true).FirstOrDefault().Tag?.Name ?? string.Empty, AlwaysPresent = true, Colour = colourProvider.Content2, Font = OsuFont.Style.Caption2, @@ -468,7 +468,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.BeatmapSelect }; } - public LocalisableString TooltipText => string.Join('\n', beatmap.GetTopUserTags().Select(t => $"{t.Tag.Name} ({t.VoteCount})")); + public LocalisableString TooltipText => string.Join('\n', beatmap.GetTopUserTags(confirmedOnly: false).Select(t => $"{t.Tag.Name} ({t.VoteCount})")); } } } diff --git a/osu.Game/Screens/Select/RealmPopulatingOnlineLookupSource.cs b/osu.Game/Screens/Select/RealmPopulatingOnlineLookupSource.cs index 6f72206e61..312711976d 100644 --- a/osu.Game/Screens/Select/RealmPopulatingOnlineLookupSource.cs +++ b/osu.Game/Screens/Select/RealmPopulatingOnlineLookupSource.cs @@ -102,7 +102,7 @@ namespace osu.Game.Screens.Select dbBeatmap.Status = onlineBeatmap.Status; onlineBeatmap.BeatmapSet = onlineBeatmapSet; - HashSet userTags = onlineBeatmap.GetTopUserTags()? + HashSet userTags = onlineBeatmap.GetTopUserTags(confirmedOnly: true) .Select(t => t.Tag.Name) .ToHashSet() ?? [];