diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs
index 94b693363a..6cb171974a 100644
--- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs
@@ -84,20 +84,26 @@ namespace osu.Game.Tests.Visual.Beatmaps
explicitMap.Title = someDifficulties.TitleUnicode = "explicit beatmap";
explicitMap.HasExplicitContent = true;
+ var spotlightMap = CreateAPIBeatmapSet(Ruleset.Value);
+ spotlightMap.Title = someDifficulties.TitleUnicode = "spotlight beatmap";
+ spotlightMap.FeaturedInSpotlight = true;
+
var featuredMap = CreateAPIBeatmapSet(Ruleset.Value);
featuredMap.Title = someDifficulties.TitleUnicode = "featured artist beatmap";
featuredMap.TrackId = 1;
- var explicitFeaturedMap = CreateAPIBeatmapSet(Ruleset.Value);
- explicitFeaturedMap.Title = someDifficulties.TitleUnicode = "explicit featured artist";
- explicitFeaturedMap.HasExplicitContent = true;
- explicitFeaturedMap.TrackId = 2;
+ var allBadgesMap = CreateAPIBeatmapSet(Ruleset.Value);
+ allBadgesMap.Title = someDifficulties.TitleUnicode = "all-badges beatmap";
+ allBadgesMap.HasExplicitContent = true;
+ allBadgesMap.FeaturedInSpotlight = true;
+ allBadgesMap.TrackId = 2;
var longName = CreateAPIBeatmapSet(Ruleset.Value);
longName.Title = longName.TitleUnicode = "this track has an incredibly and implausibly long title";
longName.Artist = longName.ArtistUnicode = "and this artist! who would have thunk it. it's really such a long name.";
longName.Source = "wow. even the source field has an impossibly long string in it. this really takes the cake, doesn't it?";
longName.HasExplicitContent = true;
+ longName.FeaturedInSpotlight = true;
longName.TrackId = 444;
testCases = new[]
@@ -108,8 +114,9 @@ namespace osu.Game.Tests.Visual.Beatmaps
someDifficulties,
manyDifficulties,
explicitMap,
+ spotlightMap,
featuredMap,
- explicitFeaturedMap,
+ allBadgesMap,
longName
};
diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs
index f87cca80b0..859727e632 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs
@@ -165,6 +165,17 @@ namespace osu.Game.Tests.Visual.Online
});
}
+ [Test]
+ public void TestSpotlightBeatmap()
+ {
+ AddStep("show spotlight map", () =>
+ {
+ var beatmapSet = getBeatmapSet();
+ beatmapSet.FeaturedInSpotlight = true;
+ overlay.ShowBeatmapSet(beatmapSet);
+ });
+ }
+
[Test]
public void TestFeaturedBeatmap()
{
@@ -176,6 +187,19 @@ namespace osu.Game.Tests.Visual.Online
});
}
+ [Test]
+ public void TestAllBadgesBeatmap()
+ {
+ AddStep("show map with all badges", () =>
+ {
+ var beatmapSet = getBeatmapSet();
+ beatmapSet.HasExplicitContent = true;
+ beatmapSet.FeaturedInSpotlight = true;
+ beatmapSet.TrackId = 1;
+ overlay.ShowBeatmapSet(beatmapSet);
+ });
+ }
+
[Test]
public void TestHide()
{
diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs
index 535f222228..58c1ebee0f 100644
--- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs
+++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs
@@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Height = height;
FillFlowContainer leftIconArea = null!;
- GridContainer titleContainer = null!;
+ FillFlowContainer titleBadgeArea = null!;
GridContainer artistContainer = null!;
Child = content.With(c =>
@@ -93,7 +93,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
- titleContainer = new GridContainer
+ new GridContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
@@ -108,7 +108,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
},
Content = new[]
{
- new[]
+ new Drawable[]
{
new OsuSpriteText
{
@@ -117,7 +117,13 @@ namespace osu.Game.Beatmaps.Drawables.Cards
RelativeSizeAxes = Axes.X,
Truncate = true
},
- Empty()
+ titleBadgeArea = new FillFlowContainer
+ {
+ Anchor = Anchor.BottomRight,
+ Origin = Anchor.BottomRight,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ }
}
}
},
@@ -244,19 +250,29 @@ namespace osu.Game.Beatmaps.Drawables.Cards
if (BeatmapSet.HasStoryboard)
leftIconArea.Add(new IconPill(FontAwesome.Solid.Image) { IconSize = new Vector2(20) });
- if (BeatmapSet.HasExplicitContent)
+ if (BeatmapSet.FeaturedInSpotlight)
{
- titleContainer.Content[0][1] = new ExplicitContentBeatmapPill
+ titleBadgeArea.Add(new SpotlightBeatmapBadge
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Margin = new MarginPadding { Left = 5 }
- };
+ });
+ }
+
+ if (BeatmapSet.HasExplicitContent)
+ {
+ titleBadgeArea.Add(new ExplicitContentBeatmapBadge
+ {
+ Anchor = Anchor.BottomRight,
+ Origin = Anchor.BottomRight,
+ Margin = new MarginPadding { Left = 5 }
+ });
}
if (BeatmapSet.TrackId != null)
{
- artistContainer.Content[0][1] = new FeaturedArtistBeatmapPill
+ artistContainer.Content[0][1] = new FeaturedArtistBeatmapBadge
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs
index 08befd5340..3d7e81de21 100644
--- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs
+++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs
@@ -55,7 +55,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Height = height;
FillFlowContainer leftIconArea = null!;
- GridContainer titleContainer = null!;
+ FillFlowContainer titleBadgeArea = null!;
GridContainer artistContainer = null!;
Child = content.With(c =>
@@ -94,14 +94,14 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
- titleContainer = new GridContainer
+ new GridContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
ColumnDimensions = new[]
{
new Dimension(),
- new Dimension(GridSizeMode.AutoSize)
+ new Dimension(GridSizeMode.AutoSize),
},
RowDimensions = new[]
{
@@ -109,7 +109,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
},
Content = new[]
{
- new[]
+ new Drawable[]
{
new OsuSpriteText
{
@@ -118,7 +118,13 @@ namespace osu.Game.Beatmaps.Drawables.Cards
RelativeSizeAxes = Axes.X,
Truncate = true
},
- Empty()
+ titleBadgeArea = new FillFlowContainer
+ {
+ Anchor = Anchor.BottomRight,
+ Origin = Anchor.BottomRight,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ }
}
}
},
@@ -225,19 +231,29 @@ namespace osu.Game.Beatmaps.Drawables.Cards
if (BeatmapSet.HasStoryboard)
leftIconArea.Add(new IconPill(FontAwesome.Solid.Image) { IconSize = new Vector2(20) });
- if (BeatmapSet.HasExplicitContent)
+ if (BeatmapSet.FeaturedInSpotlight)
{
- titleContainer.Content[0][1] = new ExplicitContentBeatmapPill
+ titleBadgeArea.Add(new SpotlightBeatmapBadge
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Margin = new MarginPadding { Left = 5 }
- };
+ });
+ }
+
+ if (BeatmapSet.HasExplicitContent)
+ {
+ titleBadgeArea.Add(new ExplicitContentBeatmapBadge
+ {
+ Anchor = Anchor.BottomRight,
+ Origin = Anchor.BottomRight,
+ Margin = new MarginPadding { Left = 5 }
+ });
}
if (BeatmapSet.TrackId != null)
{
- artistContainer.Content[0][1] = new FeaturedArtistBeatmapPill
+ artistContainer.Content[0][1] = new FeaturedArtistBeatmapBadge
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs
index d99c13b977..79c65fa79e 100644
--- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs
+++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs
@@ -42,6 +42,9 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty(@"nsfw")]
public bool HasExplicitContent { get; set; }
+ [JsonProperty(@"spotlight")]
+ public bool FeaturedInSpotlight { get; set; }
+
[JsonProperty(@"video")]
public bool HasVideo { get; set; }
diff --git a/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapPill.cs b/osu.Game/Overlays/BeatmapSet/BeatmapBadge.cs
similarity index 57%
rename from osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapPill.cs
rename to osu.Game/Overlays/BeatmapSet/BeatmapBadge.cs
index 21d1d1172c..a75fc8e888 100644
--- a/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapPill.cs
+++ b/osu.Game/Overlays/BeatmapSet/BeatmapBadge.cs
@@ -6,42 +6,62 @@ using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
+using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
-using osu.Game.Resources.Localisation.Web;
+
+#nullable enable
namespace osu.Game.Overlays.BeatmapSet
{
- public class ExplicitContentBeatmapPill : CompositeDrawable
+ public abstract class BeatmapBadge : CompositeDrawable
{
- public ExplicitContentBeatmapPill()
+ ///
+ /// The text displayed on the badge's label.
+ ///
+ public LocalisableString BadgeText
{
- AutoSizeAxes = Axes.Both;
+ set => badgeLabel.Text = value.ToUpper();
}
- [BackgroundDependencyLoader(true)]
- private void load(OsuColour colours, OverlayColourProvider colourProvider)
+ ///
+ /// The colour of the badge's label.
+ ///
+ public Colour4 BadgeColour
{
+ set => badgeLabel.Colour = value;
+ }
+
+ private readonly Box background;
+ private readonly OsuSpriteText badgeLabel;
+
+ protected BeatmapBadge()
+ {
+ AutoSizeAxes = Axes.Both;
+
InternalChild = new CircularContainer
{
Masking = true,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
- new Box
+ background = new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = colourProvider?.Background5 ?? colours.Gray2,
},
- new OsuSpriteText
+ badgeLabel = new OsuSpriteText
{
- Margin = new MarginPadding { Horizontal = 10f, Vertical = 2f },
- Text = BeatmapsetsStrings.NsfwBadgeLabel.ToUpper(),
Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold),
- Colour = colours.Orange2
+ Margin = new MarginPadding { Horizontal = 10, Vertical = 2 },
}
}
};
}
+
+ [BackgroundDependencyLoader(true)]
+ private void load(OsuColour colours, OverlayColourProvider? colourProvider)
+ {
+ background.Colour = colourProvider?.Background5 ?? colours.Gray2;
+ }
}
}
diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs
index 8f4089c707..56efb725cd 100644
--- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs
+++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs
@@ -39,8 +39,11 @@ namespace osu.Game.Overlays.BeatmapSet
private readonly Box coverGradient;
private readonly OsuSpriteText title, artist;
private readonly AuthorInfo author;
- private readonly ExplicitContentBeatmapPill explicitContentPill;
- private readonly FeaturedArtistBeatmapPill featuredArtistPill;
+
+ private readonly ExplicitContentBeatmapBadge explicitContent;
+ private readonly SpotlightBeatmapBadge spotlight;
+ private readonly FeaturedArtistBeatmapBadge featuredArtist;
+
private readonly FillFlowContainer downloadButtonsContainer;
private readonly BeatmapAvailability beatmapAvailability;
private readonly BeatmapSetOnlineStatusPill onlineStatusPill;
@@ -126,7 +129,14 @@ namespace osu.Game.Overlays.BeatmapSet
Origin = Anchor.BottomLeft,
Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font
},
- explicitContentPill = new ExplicitContentBeatmapPill
+ explicitContent = new ExplicitContentBeatmapBadge
+ {
+ Alpha = 0f,
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ Margin = new MarginPadding { Left = 10, Bottom = 4 },
+ },
+ spotlight = new SpotlightBeatmapBadge
{
Alpha = 0f,
Anchor = Anchor.BottomLeft,
@@ -146,7 +156,7 @@ namespace osu.Game.Overlays.BeatmapSet
{
Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true),
},
- featuredArtistPill = new FeaturedArtistBeatmapPill
+ featuredArtist = new FeaturedArtistBeatmapBadge
{
Alpha = 0f,
Anchor = Anchor.BottomLeft,
@@ -257,8 +267,9 @@ namespace osu.Game.Overlays.BeatmapSet
title.Text = new RomanisableString(setInfo.NewValue.TitleUnicode, setInfo.NewValue.Title);
artist.Text = new RomanisableString(setInfo.NewValue.ArtistUnicode, setInfo.NewValue.Artist);
- explicitContentPill.Alpha = setInfo.NewValue.HasExplicitContent ? 1 : 0;
- featuredArtistPill.Alpha = setInfo.NewValue.TrackId != null ? 1 : 0;
+ explicitContent.Alpha = setInfo.NewValue.HasExplicitContent ? 1 : 0;
+ spotlight.Alpha = setInfo.NewValue.FeaturedInSpotlight ? 1 : 0;
+ featuredArtist.Alpha = setInfo.NewValue.TrackId != null ? 1 : 0;
onlineStatusPill.FadeIn(500, Easing.OutQuint);
onlineStatusPill.Status = setInfo.NewValue.Status;
diff --git a/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapBadge.cs b/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapBadge.cs
new file mode 100644
index 0000000000..2a20d22b61
--- /dev/null
+++ b/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapBadge.cs
@@ -0,0 +1,21 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Game.Graphics;
+using osu.Game.Resources.Localisation.Web;
+
+#nullable enable
+
+namespace osu.Game.Overlays.BeatmapSet
+{
+ public class ExplicitContentBeatmapBadge : BeatmapBadge
+ {
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ BadgeText = BeatmapsetsStrings.NsfwBadgeLabel;
+ BadgeColour = colours.Orange2;
+ }
+ }
+}
diff --git a/osu.Game/Overlays/BeatmapSet/FeaturedArtistBeatmapBadge.cs b/osu.Game/Overlays/BeatmapSet/FeaturedArtistBeatmapBadge.cs
new file mode 100644
index 0000000000..4f336d85fc
--- /dev/null
+++ b/osu.Game/Overlays/BeatmapSet/FeaturedArtistBeatmapBadge.cs
@@ -0,0 +1,22 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Game.Graphics;
+using osu.Game.Resources.Localisation.Web;
+
+#nullable enable
+
+namespace osu.Game.Overlays.BeatmapSet
+{
+ public class FeaturedArtistBeatmapBadge : BeatmapBadge
+ {
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ BadgeText = BeatmapsetsStrings.FeaturedArtistBadgeLabel;
+ BadgeColour = colours.Blue1;
+ // todo: add linking support to allow redirecting featured artist badge to corresponding track.
+ }
+ }
+}
diff --git a/osu.Game/Overlays/BeatmapSet/FeaturedArtistBeatmapPill.cs b/osu.Game/Overlays/BeatmapSet/FeaturedArtistBeatmapPill.cs
deleted file mode 100644
index 1be987cde2..0000000000
--- a/osu.Game/Overlays/BeatmapSet/FeaturedArtistBeatmapPill.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-using osu.Framework.Allocation;
-using osu.Framework.Extensions.LocalisationExtensions;
-using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Shapes;
-using osu.Game.Graphics;
-using osu.Game.Graphics.Sprites;
-using osu.Game.Resources.Localisation.Web;
-
-namespace osu.Game.Overlays.BeatmapSet
-{
- public class FeaturedArtistBeatmapPill : CompositeDrawable
- {
- public FeaturedArtistBeatmapPill()
- {
- AutoSizeAxes = Axes.Both;
- }
-
- [BackgroundDependencyLoader(true)]
- private void load(OsuColour colours, OverlayColourProvider colourProvider)
- {
- InternalChild = new CircularContainer
- {
- Masking = true,
- AutoSizeAxes = Axes.Both,
- Children = new Drawable[]
- {
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- Colour = colourProvider?.Background5 ?? colours.Gray2,
- },
- new OsuSpriteText
- {
- Margin = new MarginPadding { Horizontal = 10f, Vertical = 2f },
- Text = BeatmapsetsStrings.FeaturedArtistBadgeLabel.ToUpper(),
- Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold),
- Colour = colours.Blue1
- }
- }
- };
- }
- }
-}
diff --git a/osu.Game/Overlays/BeatmapSet/SpotlightBeatmapBadge.cs b/osu.Game/Overlays/BeatmapSet/SpotlightBeatmapBadge.cs
new file mode 100644
index 0000000000..3204f79b21
--- /dev/null
+++ b/osu.Game/Overlays/BeatmapSet/SpotlightBeatmapBadge.cs
@@ -0,0 +1,22 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Game.Graphics;
+using osu.Game.Resources.Localisation.Web;
+
+#nullable enable
+
+namespace osu.Game.Overlays.BeatmapSet
+{
+ public class SpotlightBeatmapBadge : BeatmapBadge
+ {
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ BadgeText = BeatmapsetsStrings.SpotlightBadgeLabel;
+ BadgeColour = colours.Pink1;
+ // todo: add linking support to allow redirecting spotlight badge to https://osu.ppy.sh/wiki/en/Beatmap_Spotlights.
+ }
+ }
+}
diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
index 2618e15d31..39853a5c45 100644
--- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
+++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
@@ -78,7 +78,7 @@ namespace osu.Game.Screens.OnlinePlay
private Container difficultyIconContainer;
private LinkFlowContainer beatmapText;
private LinkFlowContainer authorText;
- private ExplicitContentBeatmapPill explicitContentPill;
+ private ExplicitContentBeatmapBadge explicitContent;
private ModDisplay modDisplay;
private FillFlowContainer buttonsFlow;
private UpdateableAvatar ownerAvatar;
@@ -293,7 +293,7 @@ namespace osu.Game.Screens.OnlinePlay
}
bool hasExplicitContent = (beatmap?.BeatmapSet as IBeatmapSetOnlineInfo)?.HasExplicitContent == true;
- explicitContentPill.Alpha = hasExplicitContent ? 1 : 0;
+ explicitContent.Alpha = hasExplicitContent ? 1 : 0;
modDisplay.Current.Value = requiredMods.ToArray();
@@ -380,7 +380,7 @@ namespace osu.Game.Screens.OnlinePlay
Children = new Drawable[]
{
authorText = new LinkFlowContainer(fontParameters) { AutoSizeAxes = Axes.Both },
- explicitContentPill = new ExplicitContentBeatmapPill
+ explicitContent = new ExplicitContentBeatmapBadge
{
Alpha = 0f,
Anchor = Anchor.CentreLeft,