mirror of
https://github.com/ppy/osu
synced 2024-12-19 21:32:57 +00:00
Merge pull request #29537 from normalid-awa/feature/song-select/allow-copy-url-from-context-menu
Allow copying beatmap link in song select carousel context menu
This commit is contained in:
commit
bd6943ebc2
@ -2,6 +2,8 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
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}]";
|
private static string getVersionString(IBeatmapInfo beatmapInfo) => string.IsNullOrEmpty(beatmapInfo.DifficultyName) ? string.Empty : $"[{beatmapInfo.DifficultyName}]";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the beatmap info page URL, or <c>null</c> if unavailable.
|
||||||
|
/// </summary>
|
||||||
|
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}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ using System.Linq;
|
|||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Models;
|
using osu.Game.Models;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
namespace osu.Game.Beatmaps
|
||||||
{
|
{
|
||||||
@ -29,5 +31,19 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <param name="filename">The name of the file to get the storage path of.</param>
|
/// <param name="filename">The name of the file to get the storage path of.</param>
|
||||||
public static RealmNamedFileUsage? GetFile(this IHasRealmFiles model, string filename) =>
|
public static RealmNamedFileUsage? GetFile(this IHasRealmFiles model, string filename) =>
|
||||||
model.Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase));
|
model.Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the beatmapset info page URL, or <c>null</c> if unavailable.
|
||||||
|
/// </summary>
|
||||||
|
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}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,6 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Platform;
|
|
||||||
using osu.Game.Overlays;
|
|
||||||
using osu.Game.Overlays.OSD;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -25,13 +22,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
private Color4 hoverColour;
|
private Color4 hoverColour;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private GameHost host { get; set; } = null!;
|
private OsuGame? game { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private Clipboard clipboard { get; set; } = null!;
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OnScreenDisplay? onScreenDisplay { get; set; }
|
|
||||||
|
|
||||||
private readonly SpriteIcon linkIcon;
|
private readonly SpriteIcon linkIcon;
|
||||||
|
|
||||||
@ -71,7 +62,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
protected override bool OnClick(ClickEvent e)
|
protected override bool OnClick(ClickEvent e)
|
||||||
{
|
{
|
||||||
if (Link != null)
|
if (Link != null)
|
||||||
host.OpenUrlExternally(Link);
|
game?.OpenUrlExternally(Link);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,8 +76,8 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
if (Link != null)
|
if (Link != null)
|
||||||
{
|
{
|
||||||
items.Add(new OsuMenuItem("Open", MenuItemType.Highlighted, () => host.OpenUrlExternally(Link)));
|
items.Add(new OsuMenuItem("Open", MenuItemType.Highlighted, () => game?.OpenUrlExternally(Link)));
|
||||||
items.Add(new OsuMenuItem("Copy URL", MenuItemType.Standard, copyUrl));
|
items.Add(new OsuMenuItem("Copy link", MenuItemType.Standard, copyUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
return items.ToArray();
|
return items.ToArray();
|
||||||
@ -95,11 +86,9 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
private void copyUrl()
|
private void copyUrl()
|
||||||
{
|
{
|
||||||
if (Link != null)
|
if (Link == null) return;
|
||||||
{
|
|
||||||
clipboard.SetText(Link);
|
game?.CopyUrlToClipboard(Link);
|
||||||
onScreenDisplay?.Display(new CopyUrlToast());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,9 @@ namespace osu.Game.Localisation
|
|||||||
public static LocalisableString SkinSaved => new TranslatableString(getKey(@"skin_saved"), @"Skin saved");
|
public static LocalisableString SkinSaved => new TranslatableString(getKey(@"skin_saved"), @"Skin saved");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "URL copied"
|
/// "Link copied to clipboard"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString UrlCopied => new TranslatableString(getKey(@"url_copied"), @"URL copied");
|
public static LocalisableString UrlCopied => new TranslatableString(getKey(@"url_copied"), @"Link copied to clipboard");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Speed changed to {0:N2}x"
|
/// "Speed changed to {0:N2}x"
|
||||||
|
@ -60,7 +60,7 @@ namespace osu.Game.Online.Chat
|
|||||||
},
|
},
|
||||||
new PopupDialogCancelButton
|
new PopupDialogCancelButton
|
||||||
{
|
{
|
||||||
Text = @"Copy URL to the clipboard",
|
Text = @"Copy link",
|
||||||
Action = copyExternalLinkAction
|
Action = copyExternalLinkAction
|
||||||
},
|
},
|
||||||
new PopupDialogCancelButton
|
new PopupDialogCancelButton
|
||||||
|
@ -54,6 +54,7 @@ using osu.Game.Overlays.BeatmapListing;
|
|||||||
using osu.Game.Overlays.Mods;
|
using osu.Game.Overlays.Mods;
|
||||||
using osu.Game.Overlays.Music;
|
using osu.Game.Overlays.Music;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
|
using osu.Game.Overlays.OSD;
|
||||||
using osu.Game.Overlays.SkinEditor;
|
using osu.Game.Overlays.SkinEditor;
|
||||||
using osu.Game.Overlays.Toolbar;
|
using osu.Game.Overlays.Toolbar;
|
||||||
using osu.Game.Overlays.Volume;
|
using osu.Game.Overlays.Volume;
|
||||||
@ -142,6 +143,8 @@ namespace osu.Game
|
|||||||
|
|
||||||
private Container overlayOffsetContainer;
|
private Container overlayOffsetContainer;
|
||||||
|
|
||||||
|
private OnScreenDisplay onScreenDisplay;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private FrameworkConfigManager frameworkConfig { get; set; }
|
private FrameworkConfigManager frameworkConfig { get; set; }
|
||||||
|
|
||||||
@ -497,6 +500,12 @@ namespace osu.Game
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
public void CopyUrlToClipboard(string url) => waitForReady(() => onScreenDisplay, _ =>
|
||||||
|
{
|
||||||
|
dependencies.Get<Clipboard>().SetText(url);
|
||||||
|
onScreenDisplay.Display(new CopyUrlToast());
|
||||||
|
});
|
||||||
|
|
||||||
public void OpenUrlExternally(string url, bool forceBypassExternalUrlWarning = false) => waitForReady(() => externalLinkOpener, _ =>
|
public void OpenUrlExternally(string url, bool forceBypassExternalUrlWarning = false) => waitForReady(() => externalLinkOpener, _ =>
|
||||||
{
|
{
|
||||||
bool isTrustedDomain;
|
bool isTrustedDomain;
|
||||||
@ -1078,7 +1087,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add, true);
|
loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add, true);
|
||||||
|
|
||||||
var onScreenDisplay = new OnScreenDisplay();
|
onScreenDisplay = new OnScreenDisplay();
|
||||||
|
|
||||||
onScreenDisplay.BeginTracking(this, frameworkConfig);
|
onScreenDisplay.BeginTracking(this, frameworkConfig);
|
||||||
onScreenDisplay.BeginTracking(this, LocalConfig);
|
onScreenDisplay.BeginTracking(this, LocalConfig);
|
||||||
|
@ -200,7 +200,8 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
|
|
||||||
private void updateExternalLink()
|
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]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -25,6 +25,7 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Resources.Localisation.Web;
|
using osu.Game.Resources.Localisation.Web;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -79,6 +80,12 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IBindable<IReadOnlyList<Mod>> mods { get; set; } = null!;
|
private IBindable<IReadOnlyList<Mod>> mods { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IAPIProvider api { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuGame? game { get; set; }
|
||||||
|
|
||||||
private IBindable<StarDifficulty?> starDifficultyBindable = null!;
|
private IBindable<StarDifficulty?> starDifficultyBindable = null!;
|
||||||
private CancellationTokenSource? starDifficultyCancellationSource;
|
private CancellationTokenSource? starDifficultyCancellationSource;
|
||||||
|
|
||||||
@ -288,6 +295,9 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
|
|
||||||
items.Add(new OsuMenuItem("Collections") { Items = collectionItems });
|
items.Add(new OsuMenuItem("Collections") { Items = collectionItems });
|
||||||
|
|
||||||
|
if (beatmapInfo.GetOnlineURL(api, ruleset.Value) is string url)
|
||||||
|
items.Add(new OsuMenuItem("Copy link", MenuItemType.Standard, () => game?.CopyUrlToClipboard(url)));
|
||||||
|
|
||||||
if (hideRequested != null)
|
if (hideRequested != null)
|
||||||
items.Add(new OsuMenuItem(CommonStrings.ButtonsHide.ToSentence(), MenuItemType.Destructive, () => hideRequested(beatmapInfo)));
|
items.Add(new OsuMenuItem(CommonStrings.ButtonsHide.ToSentence(), MenuItemType.Destructive, () => hideRequested(beatmapInfo)));
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -19,7 +20,9 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Collections;
|
using osu.Game.Collections;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Carousel
|
namespace osu.Game.Screens.Select.Carousel
|
||||||
{
|
{
|
||||||
@ -39,6 +42,15 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private RealmAccess realm { get; set; } = null!;
|
private RealmAccess realm { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IAPIProvider api { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuGame? game { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IBindable<RulesetInfo> ruleset { get; set; } = null!;
|
||||||
|
|
||||||
public IEnumerable<DrawableCarouselItem> DrawableBeatmaps => beatmapContainer?.IsLoaded != true ? Enumerable.Empty<DrawableCarouselItem>() : beatmapContainer.AliveChildren;
|
public IEnumerable<DrawableCarouselItem> DrawableBeatmaps => beatmapContainer?.IsLoaded != true ? Enumerable.Empty<DrawableCarouselItem>() : beatmapContainer.AliveChildren;
|
||||||
|
|
||||||
private Container<DrawableCarouselItem>? beatmapContainer;
|
private Container<DrawableCarouselItem>? beatmapContainer;
|
||||||
@ -287,6 +299,9 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
if (beatmapSet.Beatmaps.Any(b => b.Hidden))
|
if (beatmapSet.Beatmaps.Any(b => b.Hidden))
|
||||||
items.Add(new OsuMenuItem("Restore all hidden", MenuItemType.Standard, () => restoreHiddenRequested(beatmapSet)));
|
items.Add(new OsuMenuItem("Restore all hidden", MenuItemType.Standard, () => restoreHiddenRequested(beatmapSet)));
|
||||||
|
|
||||||
|
if (beatmapSet.GetOnlineURL(api, ruleset.Value) is string url)
|
||||||
|
items.Add(new OsuMenuItem("Copy link", MenuItemType.Standard, () => game?.CopyUrlToClipboard(url)));
|
||||||
|
|
||||||
if (dialogOverlay != null)
|
if (dialogOverlay != null)
|
||||||
items.Add(new OsuMenuItem("Delete...", MenuItemType.Destructive, () => dialogOverlay.Push(new BeatmapDeleteDialog(beatmapSet))));
|
items.Add(new OsuMenuItem("Delete...", MenuItemType.Destructive, () => dialogOverlay.Push(new BeatmapDeleteDialog(beatmapSet))));
|
||||||
return items.ToArray();
|
return items.ToArray();
|
||||||
|
Loading…
Reference in New Issue
Block a user