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))));