diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index 3a0afcd0ab..9c79927363 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -117,7 +117,21 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"owners")] public BeatmapOwner[] BeatmapOwners { get; set; } = Array.Empty(); - public (APITag Tag, int VoteCount)[] GetTopUserTags() + /// + /// Minimum count of votes required to display a tag on the beatmap's page. + /// Should match value specified web-side as https://github.com/ppy/osu-web/blob/cae2fdf03cfb8c30c8e332cfb142e03188ceffef/config/osu.php#L59. + /// + public const int MINIMUM_USER_TAG_VOTES_FOR_DISPLAY = 5; + + /// + /// 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 = true) { if (TopTags == null || TopTags.Length == 0 || BeatmapSet?.RelatedTags == null) return []; @@ -126,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/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index f75e7b1d3c..3c5f15adde 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -242,12 +242,14 @@ namespace osu.Game.Overlays.BeatmapSet BeatmapSet.BindValueChanged(setInfo => { - Picker.BeatmapSet = rulesetSelector.BeatmapSet = author.BeatmapSet = beatmapAvailability.BeatmapSet = Details.BeatmapSet = setInfo.NewValue; - cover.OnlineInfo = setInfo.NewValue; + var newBeatmapSet = setInfo.NewValue; + + Picker.BeatmapSet = rulesetSelector.BeatmapSet = author.BeatmapSet = beatmapAvailability.BeatmapSet = Details.BeatmapSet = newBeatmapSet; + cover.OnlineInfo = newBeatmapSet; downloadTracker?.RemoveAndDisposeImmediately(); - if (setInfo.NewValue == null) + if (newBeatmapSet == null) { onlineStatusPill.FadeTo(0.5f, 500, Easing.OutQuint); videoIconPill.Hide(); @@ -261,7 +263,10 @@ namespace osu.Game.Overlays.BeatmapSet } else { - downloadTracker = new BeatmapDownloadTracker(setInfo.NewValue); + foreach (var beatmap in newBeatmapSet.Beatmaps) + beatmap.BeatmapSet = newBeatmapSet; + + downloadTracker = new BeatmapDownloadTracker(newBeatmapSet); downloadTracker.State.BindValueChanged(_ => updateDownloadButtons()); AddInternal(downloadTracker); @@ -269,18 +274,18 @@ namespace osu.Game.Overlays.BeatmapSet loading.Hide(); - if (setInfo.NewValue.HasVideo) + if (newBeatmapSet.HasVideo) videoIconPill.Show(); else videoIconPill.Hide(); - if (setInfo.NewValue.HasStoryboard) + if (newBeatmapSet.HasStoryboard) storyboardIconPill.Show(); else storyboardIconPill.Hide(); - var titleText = new RomanisableString(setInfo.NewValue.TitleUnicode, setInfo.NewValue.Title); - var artistText = new RomanisableString(setInfo.NewValue.ArtistUnicode, setInfo.NewValue.Artist); + var titleText = new RomanisableString(newBeatmapSet.TitleUnicode, newBeatmapSet.Title); + var artistText = new RomanisableString(newBeatmapSet.ArtistUnicode, newBeatmapSet.Artist); title.Clear(); artist.Clear(); @@ -290,13 +295,13 @@ namespace osu.Game.Overlays.BeatmapSet title.AddArbitraryDrawable(Empty().With(d => d.Width = 5)); title.AddArbitraryDrawable(externalLink = new ExternalLinkButton()); - if (setInfo.NewValue.HasExplicitContent) + if (newBeatmapSet.HasExplicitContent) { title.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); title.AddArbitraryDrawable(new ExplicitContentBeatmapBadge()); } - if (setInfo.NewValue.FeaturedInSpotlight) + if (newBeatmapSet.FeaturedInSpotlight) { title.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); title.AddArbitraryDrawable(new SpotlightBeatmapBadge()); @@ -304,7 +309,7 @@ namespace osu.Game.Overlays.BeatmapSet artist.AddLink(artistText, LinkAction.SearchBeatmapSet, LocalisableString.Interpolate($@"artist=""""{artistText}""""")); - if (setInfo.NewValue.TrackId != null) + if (newBeatmapSet.TrackId != null) { artist.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); artist.AddArbitraryDrawable(new FeaturedArtistBeatmapBadge()); diff --git a/osu.Game/Screens/Ranking/UserTagControl.DrawableUserTag.cs b/osu.Game/Screens/Ranking/UserTagControl.DrawableUserTag.cs index 09af68a4f7..2a26ebc3c6 100644 --- a/osu.Game/Screens/Ranking/UserTagControl.DrawableUserTag.cs +++ b/osu.Game/Screens/Ranking/UserTagControl.DrawableUserTag.cs @@ -13,6 +13,7 @@ using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Screens.Ranking { @@ -20,12 +21,6 @@ namespace osu.Game.Screens.Ranking { public partial class DrawableUserTag : OsuAnimatedButton { - /// - /// Minimum count of votes required to display a tag on the beatmap's page. - /// Should match value specified web-side as https://github.com/ppy/osu-web/blob/cae2fdf03cfb8c30c8e332cfb142e03188ceffef/config/osu.php#L59. - /// - public const int MIN_VOTES_DISPLAY = 5; - public readonly UserTag UserTag; public Action? OnSelected { get; set; } @@ -160,7 +155,7 @@ namespace osu.Game.Screens.Ranking { voteCount.BindValueChanged(_ => { - confirmed.Value = voteCount.Value >= MIN_VOTES_DISPLAY; + confirmed.Value = voteCount.Value >= APIBeatmap.MINIMUM_USER_TAG_VOTES_FOR_DISPLAY; }, true); voted.BindValueChanged(v => { diff --git a/osu.Game/Screens/Select/RealmPopulatingOnlineLookupSource.cs b/osu.Game/Screens/Select/RealmPopulatingOnlineLookupSource.cs index 132a160106..f94a1822ec 100644 --- a/osu.Game/Screens/Select/RealmPopulatingOnlineLookupSource.cs +++ b/osu.Game/Screens/Select/RealmPopulatingOnlineLookupSource.cs @@ -70,7 +70,6 @@ namespace osu.Game.Screens.Select private static void updateRealmBeatmapSet(Realm r, APIBeatmapSet onlineBeatmapSet) { - var tagsById = (onlineBeatmapSet.RelatedTags ?? []).ToDictionary(t => t.Id); var onlineBeatmaps = onlineBeatmapSet.Beatmaps.ToDictionary(b => b.OnlineID); var dbBeatmapSets = r.All().Where(b => b.OnlineID == onlineBeatmapSet.OnlineID); @@ -101,11 +100,10 @@ namespace osu.Game.Screens.Select if (dbBeatmap.MatchesOnlineVersion && dbBeatmap.Status != onlineBeatmap.Status) dbBeatmap.Status = onlineBeatmap.Status; - HashSet userTags = onlineBeatmap.TopTags? - .Select(t => (topTag: t, relatedTag: tagsById.GetValueOrDefault(t.TagId))) - .Where(t => t.relatedTag != null) - .Select(t => t.relatedTag!.Name) - .ToHashSet() ?? []; + onlineBeatmap.BeatmapSet = onlineBeatmapSet; + HashSet userTags = onlineBeatmap.GetTopUserTags(confirmedOnly: true) + .Select(t => t.Tag.Name) + .ToHashSet(); if (!userTags.SetEquals(dbBeatmap.Metadata.UserTags)) {