diff --git a/osu.Game/Beatmaps/BeatmapInfoExtensions.cs b/osu.Game/Beatmaps/BeatmapInfoExtensions.cs
index b00d0ba316..a82a288239 100644
--- a/osu.Game/Beatmaps/BeatmapInfoExtensions.cs
+++ b/osu.Game/Beatmaps/BeatmapInfoExtensions.cs
@@ -2,6 +2,8 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Localisation;
+using osu.Game.Online.API;
+using osu.Game.Rulesets;
using osu.Game.Screens.Select;
namespace osu.Game.Beatmaps
@@ -48,5 +50,16 @@ namespace osu.Game.Beatmaps
}
private static string getVersionString(IBeatmapInfo beatmapInfo) => string.IsNullOrEmpty(beatmapInfo.DifficultyName) ? string.Empty : $"[{beatmapInfo.DifficultyName}]";
+
+ ///
+ /// Get the beatmap info page URL, or null if unavailable.
+ ///
+ public static string? GetOnlineURL(this IBeatmapInfo beatmapInfo, IAPIProvider api, IRulesetInfo? ruleset = null)
+ {
+ if (beatmapInfo.OnlineID <= 0 || beatmapInfo.BeatmapSet == null)
+ return null;
+
+ return $@"{api.WebsiteRootUrl}/beatmapsets/{beatmapInfo.BeatmapSet.OnlineID}#{ruleset?.ShortName ?? beatmapInfo.Ruleset.ShortName}/{beatmapInfo.OnlineID}";
+ }
}
}
diff --git a/osu.Game/Beatmaps/BeatmapSetInfoExtensions.cs b/osu.Game/Beatmaps/BeatmapSetInfoExtensions.cs
index 965544da40..8a107ed486 100644
--- a/osu.Game/Beatmaps/BeatmapSetInfoExtensions.cs
+++ b/osu.Game/Beatmaps/BeatmapSetInfoExtensions.cs
@@ -6,6 +6,8 @@ using System.Linq;
using osu.Game.Database;
using osu.Game.Extensions;
using osu.Game.Models;
+using osu.Game.Online.API;
+using osu.Game.Rulesets;
namespace osu.Game.Beatmaps
{
@@ -29,5 +31,19 @@ namespace osu.Game.Beatmaps
/// The name of the file to get the storage path of.
public static RealmNamedFileUsage? GetFile(this IHasRealmFiles model, string filename) =>
model.Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase));
+
+ ///
+ /// Get the beatmapset info page URL, or null if unavailable.
+ ///
+ public static string? GetOnlineURL(this IBeatmapSetInfo beatmapSetInfo, IAPIProvider api, IRulesetInfo? ruleset = null)
+ {
+ if (beatmapSetInfo.OnlineID <= 0)
+ return null;
+
+ if (ruleset != null)
+ return $@"{api.WebsiteRootUrl}/beatmapsets/{beatmapSetInfo.OnlineID}#{ruleset.ShortName}";
+
+ return $@"{api.WebsiteRootUrl}/beatmapsets/{beatmapSetInfo.OnlineID}";
+ }
}
}
diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs
index 7ff8352054..168056ea58 100644
--- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs
+++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs
@@ -200,7 +200,8 @@ namespace osu.Game.Overlays.BeatmapSet
private void updateExternalLink()
{
- if (externalLink != null) externalLink.Link = $@"{api.WebsiteRootUrl}/beatmapsets/{BeatmapSet.Value?.OnlineID}#{Picker.Beatmap.Value?.Ruleset.ShortName}/{Picker.Beatmap.Value?.OnlineID}";
+ if (externalLink != null)
+ externalLink.Link = Picker.Beatmap.Value?.GetOnlineURL(api) ?? BeatmapSet.Value?.GetOnlineURL(api);
}
[BackgroundDependencyLoader]
diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs
index 851446c3e0..dd9f2226e9 100644
--- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs
+++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs
@@ -55,7 +55,6 @@ namespace osu.Game.Screens.Select.Carousel
private Action? selectRequested;
private Action? hideRequested;
- private Action? copyBeatmapSetUrl;
private Triangles triangles = null!;
@@ -82,6 +81,12 @@ namespace osu.Game.Screens.Select.Carousel
[Resolved]
private IBindable> mods { get; set; } = null!;
+ [Resolved]
+ private Clipboard clipboard { get; set; } = null!;
+
+ [Resolved]
+ private IAPIProvider api { get; set; } = null!;
+
private IBindable starDifficultyBindable = null!;
private CancellationTokenSource? starDifficultyCancellationSource;
@@ -92,7 +97,7 @@ namespace osu.Game.Screens.Select.Carousel
}
[BackgroundDependencyLoader]
- private void load(BeatmapManager? manager, SongSelect? songSelect, Clipboard clipboard, IAPIProvider api)
+ private void load(BeatmapManager? manager, SongSelect? songSelect, IAPIProvider api)
{
Header.Height = height;
@@ -105,9 +110,6 @@ namespace osu.Game.Screens.Select.Carousel
if (manager != null)
hideRequested = manager.Hide;
- if (beatmapInfo.BeatmapSet != null)
- copyBeatmapSetUrl += () => clipboard.SetText($@"{api.WebsiteRootUrl}/beatmapsets/{beatmapInfo.BeatmapSet.OnlineID}#{beatmapInfo.Ruleset.ShortName}/{beatmapInfo.OnlineID}");
-
Header.Children = new Drawable[]
{
background = new Box
@@ -294,7 +296,8 @@ namespace osu.Game.Screens.Select.Carousel
items.Add(new OsuMenuItem("Collections") { Items = collectionItems });
- items.Add(new OsuMenuItem("Copy link", MenuItemType.Standard, () => copyBeatmapSetUrl?.Invoke()));
+ if (beatmapInfo.GetOnlineURL(api) is string url)
+ items.Add(new OsuMenuItem("Copy link", MenuItemType.Standard, () => clipboard.SetText(url)));
if (hideRequested != null)
items.Add(new OsuMenuItem(CommonStrings.ButtonsHide.ToSentence(), MenuItemType.Destructive, () => hideRequested(beatmapInfo)));
diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs
index 5f4edaf070..3233347991 100644
--- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs
+++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs
@@ -33,7 +33,6 @@ namespace osu.Game.Screens.Select.Carousel
private Action restoreHiddenRequested = null!;
private Action? viewDetails;
- private Action? copyBeatmapSetUrl;
[Resolved]
private IDialogOverlay? dialogOverlay { get; set; }
@@ -44,6 +43,15 @@ namespace osu.Game.Screens.Select.Carousel
[Resolved]
private RealmAccess realm { get; set; } = null!;
+ [Resolved]
+ private Clipboard clipboard { get; set; } = null!;
+
+ [Resolved]
+ private IAPIProvider api { get; set; } = null!;
+
+ [Resolved]
+ private IBindable ruleset { get; set; } = null!;
+
public IEnumerable DrawableBeatmaps => beatmapContainer?.IsLoaded != true ? Enumerable.Empty() : beatmapContainer.AliveChildren;
private Container? beatmapContainer;
@@ -70,7 +78,7 @@ namespace osu.Game.Screens.Select.Carousel
}
[BackgroundDependencyLoader]
- private void load(BeatmapSetOverlay? beatmapOverlay, SongSelect? songSelect, Clipboard clipboard, IBindable ruleset, IAPIProvider api)
+ private void load(BeatmapSetOverlay? beatmapOverlay, SongSelect? songSelect)
{
if (songSelect != null)
mainMenuItems = songSelect.CreateForwardNavigationMenuItemsForBeatmap(() => (((CarouselBeatmapSet)Item!).GetNextToSelect() as CarouselBeatmap)!.BeatmapInfo);
@@ -83,8 +91,6 @@ namespace osu.Game.Screens.Select.Carousel
if (beatmapOverlay != null)
viewDetails = beatmapOverlay.FetchAndShowBeatmapSet;
-
- copyBeatmapSetUrl += () => clipboard.SetText($@"{api.WebsiteRootUrl}/beatmapsets/{beatmapSet.OnlineID}#{ruleset.Value.ShortName}");
}
protected override void Update()
@@ -294,7 +300,8 @@ namespace osu.Game.Screens.Select.Carousel
if (beatmapSet.Beatmaps.Any(b => b.Hidden))
items.Add(new OsuMenuItem("Restore all hidden", MenuItemType.Standard, () => restoreHiddenRequested(beatmapSet)));
- items.Add(new OsuMenuItem("Copy link", MenuItemType.Standard, () => copyBeatmapSetUrl?.Invoke()));
+ if (beatmapSet.GetOnlineURL(api, ruleset.Value) is string url)
+ items.Add(new OsuMenuItem("Copy link", MenuItemType.Standard, () => clipboard.SetText(url)));
if (dialogOverlay != null)
items.Add(new OsuMenuItem("Delete...", MenuItemType.Destructive, () => dialogOverlay.Push(new BeatmapDeleteDialog(beatmapSet))));