diff --git a/osu.Game/Localisation/SongSelectStrings.cs b/osu.Game/Localisation/SongSelectStrings.cs
index 002bc16bcdd8..362edeb7f2fc 100644
--- a/osu.Game/Localisation/SongSelectStrings.cs
+++ b/osu.Game/Localisation/SongSelectStrings.cs
@@ -114,6 +114,16 @@ public static class SongSelectStrings
///
public static LocalisableString WatchReplay => new TranslatableString(getKey(@"watch_replay"), @"Watch replay");
+ ///
+ /// "Download replay"
+ ///
+ public static LocalisableString DownloadReplay => new TranslatableString(getKey(@"download_replay"), @"Download replay");
+
+ ///
+ /// "Replay downloading"
+ ///
+ public static LocalisableString ReplayDownloading => new TranslatableString(getKey(@"replay_downloading"), @"Replay downloading");
+
///
/// "For all difficulties"
///
diff --git a/osu.Game/Screens/Select/BeatmapLeaderboardScore.cs b/osu.Game/Screens/Select/BeatmapLeaderboardScore.cs
index bb96c97d520a..689cf4b1f40e 100644
--- a/osu.Game/Screens/Select/BeatmapLeaderboardScore.cs
+++ b/osu.Game/Screens/Select/BeatmapLeaderboardScore.cs
@@ -81,6 +81,9 @@ public sealed partial class BeatmapLeaderboardScore : OsuClickableContainer, IHa
[Resolved]
private IAPIProvider api { get; set; } = null!;
+ [Resolved]
+ private ScoreModelDownloader scoreDownloader { get; set; } = null!;
+
private const float expanded_right_content_width = 200;
private const float grade_width = 35;
private const float username_min_width = 120;
@@ -620,13 +623,25 @@ MenuItem[] IHasContextMenu.ContextMenuItems
// system mods should never be copied across regardless of anything.
var copyableMods = Score.Mods.Where(m => IsValidMod.Invoke(m) && m.Type != ModType.System).ToArray();
+ bool replayAvailableLocally = scoreManager.IsAvailableLocally(Score);
+ bool replayDownloading = scoreDownloader.GetExistingDownload(Score) != null;
+
if (copyableMods.Length > 0)
items.Add(new OsuMenuItem(SongSelectStrings.UseTheseMods, MenuItemType.Highlighted, () => SelectedMods.Value = copyableMods));
if (Score.OnlineID > 0)
items.Add(new OsuMenuItem(CommonStrings.CopyLink, MenuItemType.Standard, () => game?.CopyToClipboard($@"{api.Endpoints.WebsiteUrl}/scores/{Score.OnlineID}")));
- if (Score.Files.Count <= 0) return items.ToArray();
+ if (!replayAvailableLocally)
+ {
+ if (replayDownloading)
+ items.Add(new OsuMenuItem(SongSelectStrings.ReplayDownloading));
+ else if (Score.HasOnlineReplay)
+ items.Add(new OsuMenuItem(SongSelectStrings.DownloadReplay, MenuItemType.Standard, () => scoreDownloader.Download(Score)));
+ }
+
+ if (Score.Files.Count <= 0)
+ return items.ToArray();
if (items.Count > 0)
items.Add(new OsuMenuItemSpacer());