mirror of
https://github.com/ppy/osu
synced 2025-01-19 04:20:59 +00:00
Move link handling code to OsuGame
This allows for future calls from arguments / associations
This commit is contained in:
parent
c18cb354fd
commit
898520935e
@ -8,9 +8,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Logging;
|
|
||||||
using osu.Game.Overlays;
|
|
||||||
using osu.Game.Overlays.Notifications;
|
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.Containers
|
namespace osu.Game.Graphics.Containers
|
||||||
@ -23,21 +20,12 @@ namespace osu.Game.Graphics.Containers
|
|||||||
}
|
}
|
||||||
|
|
||||||
private OsuGame game;
|
private OsuGame game;
|
||||||
private ChannelManager channelManager;
|
|
||||||
private Action showNotImplementedError;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuGame game, NotificationOverlay notifications, ChannelManager channelManager)
|
private void load(OsuGame game)
|
||||||
{
|
{
|
||||||
// will be null in tests
|
// will be null in tests
|
||||||
this.game = game;
|
this.game = game;
|
||||||
this.channelManager = channelManager;
|
|
||||||
|
|
||||||
showNotImplementedError = () => notifications?.Post(new SimpleNotification
|
|
||||||
{
|
|
||||||
Text = @"This link type is not yet supported!",
|
|
||||||
Icon = FontAwesome.Solid.LifeRing,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddLinks(string text, List<Link> links)
|
public void AddLinks(string text, List<Link> links)
|
||||||
@ -56,85 +44,47 @@ namespace osu.Game.Graphics.Containers
|
|||||||
foreach (var link in links)
|
foreach (var link in links)
|
||||||
{
|
{
|
||||||
AddText(text.Substring(previousLinkEnd, link.Index - previousLinkEnd));
|
AddText(text.Substring(previousLinkEnd, link.Index - previousLinkEnd));
|
||||||
AddLink(text.Substring(link.Index, link.Length), link.Url, link.Action, link.Argument);
|
AddLink(text.Substring(link.Index, link.Length), link.Action, link.Argument ?? link.Url);
|
||||||
previousLinkEnd = link.Index + link.Length;
|
previousLinkEnd = link.Index + link.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddText(text.Substring(previousLinkEnd));
|
AddText(text.Substring(previousLinkEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Drawable> AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
public void AddLink(string text, string url, Action<SpriteText> creationParameters = null) =>
|
||||||
=> createLink(AddText(text, creationParameters), text, url, linkType, linkArgument, tooltipText);
|
createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.External, url), url);
|
||||||
|
|
||||||
public IEnumerable<Drawable> AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
public void AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||||
=> createLink(AddText(text, creationParameters), text, tooltipText: tooltipText, action: action);
|
=> createLink(AddText(text, creationParameters), new LinkDetails(LinkAction.Custom, null), tooltipText, action);
|
||||||
|
|
||||||
public IEnumerable<Drawable> AddLink(IEnumerable<SpriteText> text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null)
|
public void AddLink(string text, LinkAction action, string argument, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||||
|
=> createLink(AddText(text, creationParameters), new LinkDetails(action, argument), null);
|
||||||
|
|
||||||
|
public void AddLink(IEnumerable<SpriteText> text, LinkAction action = LinkAction.External, string linkArgument = null, string tooltipText = null)
|
||||||
{
|
{
|
||||||
foreach (var t in text)
|
foreach (var t in text)
|
||||||
AddArbitraryDrawable(t);
|
AddArbitraryDrawable(t);
|
||||||
|
|
||||||
return createLink(text, null, url, linkType, linkArgument, tooltipText);
|
createLink(text, new LinkDetails(action, linkArgument), tooltipText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Drawable> AddUserLink(User user, Action<SpriteText> creationParameters = null)
|
public void AddUserLink(User user, Action<SpriteText> creationParameters = null)
|
||||||
=> createLink(AddText(user.Username, creationParameters), user.Username, null, LinkAction.OpenUserProfile, user.Id.ToString(), "View profile");
|
=> createLink(AddText(user.Username, creationParameters), new LinkDetails(LinkAction.OpenUserProfile, user.Id.ToString()), "View Profile");
|
||||||
|
|
||||||
private IEnumerable<Drawable> createLink(IEnumerable<Drawable> drawables, string text, string url = null, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action action = null)
|
private void createLink(IEnumerable<Drawable> drawables, LinkDetails link, string tooltipText, Action action = null)
|
||||||
{
|
{
|
||||||
AddInternal(new DrawableLinkCompiler(drawables.OfType<SpriteText>().ToList())
|
AddInternal(new DrawableLinkCompiler(drawables.OfType<SpriteText>().ToList())
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
TooltipText = tooltipText ?? (url != text ? url : string.Empty),
|
TooltipText = tooltipText,
|
||||||
Action = action ?? (() =>
|
Action = () =>
|
||||||
{
|
{
|
||||||
switch (linkType)
|
if (action != null)
|
||||||
{
|
action();
|
||||||
case LinkAction.OpenBeatmap:
|
else
|
||||||
// TODO: proper query params handling
|
game.HandleLink(link);
|
||||||
if (linkArgument != null && int.TryParse(linkArgument.Contains('?') ? linkArgument.Split('?')[0] : linkArgument, out int beatmapId))
|
},
|
||||||
game?.ShowBeatmap(beatmapId);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LinkAction.OpenBeatmapSet:
|
|
||||||
if (int.TryParse(linkArgument, out int setId))
|
|
||||||
game?.ShowBeatmapSet(setId);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LinkAction.OpenChannel:
|
|
||||||
try
|
|
||||||
{
|
|
||||||
channelManager?.OpenChannel(linkArgument);
|
|
||||||
}
|
|
||||||
catch (ChannelNotFoundException)
|
|
||||||
{
|
|
||||||
Logger.Log($"The requested channel \"{linkArgument}\" does not exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LinkAction.OpenEditorTimestamp:
|
|
||||||
case LinkAction.JoinMultiplayerMatch:
|
|
||||||
case LinkAction.Spectate:
|
|
||||||
showNotImplementedError?.Invoke();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LinkAction.External:
|
|
||||||
game?.OpenUrlExternally(url);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LinkAction.OpenUserProfile:
|
|
||||||
if (long.TryParse(linkArgument, out long userId))
|
|
||||||
game?.ShowUser(userId);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action.");
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return drawables;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want the compilers to always be visible no matter where they are, so RelativeSizeAxes is used.
|
// We want the compilers to always be visible no matter where they are, so RelativeSizeAxes is used.
|
||||||
|
@ -81,7 +81,7 @@ namespace osu.Game.Online.Chat
|
|||||||
//since we just changed the line display text, offset any already processed links.
|
//since we just changed the line display text, offset any already processed links.
|
||||||
result.Links.ForEach(l => l.Index -= l.Index > index ? m.Length - displayText.Length : 0);
|
result.Links.ForEach(l => l.Index -= l.Index > index ? m.Length - displayText.Length : 0);
|
||||||
|
|
||||||
var details = getLinkDetails(linkText);
|
var details = GetLinkDetails(linkText);
|
||||||
result.Links.Add(new Link(linkText, index, displayText.Length, linkActionOverride ?? details.Action, details.Argument));
|
result.Links.Add(new Link(linkText, index, displayText.Length, linkActionOverride ?? details.Action, details.Argument));
|
||||||
|
|
||||||
//adjust the offset for processing the current matches group.
|
//adjust the offset for processing the current matches group.
|
||||||
@ -98,7 +98,7 @@ namespace osu.Game.Online.Chat
|
|||||||
var linkText = m.Groups["link"].Value;
|
var linkText = m.Groups["link"].Value;
|
||||||
var indexLength = linkText.Length;
|
var indexLength = linkText.Length;
|
||||||
|
|
||||||
var details = getLinkDetails(linkText);
|
var details = GetLinkDetails(linkText);
|
||||||
var link = new Link(linkText, index, indexLength, details.Action, details.Argument);
|
var link = new Link(linkText, index, indexLength, details.Action, details.Argument);
|
||||||
|
|
||||||
// sometimes an already-processed formatted link can reduce to a simple URL, too
|
// sometimes an already-processed formatted link can reduce to a simple URL, too
|
||||||
@ -109,7 +109,7 @@ namespace osu.Game.Online.Chat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LinkDetails getLinkDetails(string url)
|
public static LinkDetails GetLinkDetails(string url)
|
||||||
{
|
{
|
||||||
var args = url.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
var args = url.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
args[0] = args[0].TrimEnd(':');
|
args[0] = args[0].TrimEnd(':');
|
||||||
@ -255,17 +255,17 @@ namespace osu.Game.Online.Chat
|
|||||||
OriginalText = Text = text;
|
OriginalText = Text = text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class LinkDetails
|
public class LinkDetails
|
||||||
|
{
|
||||||
|
public LinkAction Action;
|
||||||
|
public string Argument;
|
||||||
|
|
||||||
|
public LinkDetails(LinkAction action, string argument)
|
||||||
{
|
{
|
||||||
public LinkAction Action;
|
Action = action;
|
||||||
public string Argument;
|
Argument = argument;
|
||||||
|
|
||||||
public LinkDetails(LinkAction action, string argument)
|
|
||||||
{
|
|
||||||
Action = action;
|
|
||||||
Argument = argument;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +279,7 @@ namespace osu.Game.Online.Chat
|
|||||||
JoinMultiplayerMatch,
|
JoinMultiplayerMatch,
|
||||||
Spectate,
|
Spectate,
|
||||||
OpenUserProfile,
|
OpenUserProfile,
|
||||||
|
Custom
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Link : IComparable<Link>
|
public class Link : IComparable<Link>
|
||||||
|
@ -215,6 +215,61 @@ namespace osu.Game
|
|||||||
|
|
||||||
private ExternalLinkOpener externalLinkOpener;
|
private ExternalLinkOpener externalLinkOpener;
|
||||||
|
|
||||||
|
public void HandleLink(string url) => HandleLink(MessageFormatter.GetLinkDetails(url));
|
||||||
|
|
||||||
|
public void HandleLink(LinkDetails link)
|
||||||
|
{
|
||||||
|
Action showNotImplementedError = () => notifications?.Post(new SimpleNotification
|
||||||
|
{
|
||||||
|
Text = @"This link type is not yet supported!",
|
||||||
|
Icon = FontAwesome.Solid.LifeRing,
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (link.Action)
|
||||||
|
{
|
||||||
|
case LinkAction.OpenBeatmap:
|
||||||
|
// TODO: proper query params handling
|
||||||
|
if (link.Argument != null && int.TryParse(link.Argument.Contains('?') ? link.Argument.Split('?')[0] : link.Argument, out int beatmapId))
|
||||||
|
ShowBeatmap(beatmapId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LinkAction.OpenBeatmapSet:
|
||||||
|
if (int.TryParse(link.Argument, out int setId))
|
||||||
|
ShowBeatmapSet(setId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LinkAction.OpenChannel:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
channelManager.OpenChannel(link.Argument);
|
||||||
|
}
|
||||||
|
catch (ChannelNotFoundException)
|
||||||
|
{
|
||||||
|
Logger.Log($"The requested channel \"{link.Argument}\" does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LinkAction.OpenEditorTimestamp:
|
||||||
|
case LinkAction.JoinMultiplayerMatch:
|
||||||
|
case LinkAction.Spectate:
|
||||||
|
showNotImplementedError.Invoke();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LinkAction.External:
|
||||||
|
OpenUrlExternally(link.Argument);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LinkAction.OpenUserProfile:
|
||||||
|
if (long.TryParse(link.Argument, out long userId))
|
||||||
|
ShowUser(userId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException($"This {nameof(LinkAction)} ({link.Action.ToString()}) is missing an associated action.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void OpenUrlExternally(string url)
|
public void OpenUrlExternally(string url)
|
||||||
{
|
{
|
||||||
if (url.StartsWith("/"))
|
if (url.StartsWith("/"))
|
||||||
|
@ -110,7 +110,7 @@ namespace osu.Game.Overlays.Changelog
|
|||||||
t.Font = fontLarge;
|
t.Font = fontLarge;
|
||||||
t.Colour = entryColour;
|
t.Colour = entryColour;
|
||||||
});
|
});
|
||||||
title.AddLink($"{entry.Repository.Replace("ppy/", "")}#{entry.GithubPullRequestId}", entry.GithubUrl, Online.Chat.LinkAction.External,
|
title.AddLink($"{entry.Repository.Replace("ppy/", "")}#{entry.GithubPullRequestId}", entry.GithubUrl,
|
||||||
creationParameters: t =>
|
creationParameters: t =>
|
||||||
{
|
{
|
||||||
t.Font = fontLarge;
|
t.Font = fontLarge;
|
||||||
@ -140,7 +140,7 @@ namespace osu.Game.Overlays.Changelog
|
|||||||
t.Colour = entryColour;
|
t.Colour = entryColour;
|
||||||
});
|
});
|
||||||
else if (entry.GithubUser.GithubUrl != null)
|
else if (entry.GithubUser.GithubUrl != null)
|
||||||
title.AddLink(entry.GithubUser.DisplayName, entry.GithubUser.GithubUrl, Online.Chat.LinkAction.External, null, null, t =>
|
title.AddLink(entry.GithubUser.DisplayName, entry.GithubUser.GithubUrl, t =>
|
||||||
{
|
{
|
||||||
t.Font = fontMedium;
|
t.Font = fontMedium;
|
||||||
t.Colour = entryColour;
|
t.Colour = entryColour;
|
||||||
|
@ -81,7 +81,7 @@ namespace osu.Game.Screens.Multi.Components
|
|||||||
Text = new LocalisedString((beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title)),
|
Text = new LocalisedString((beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title)),
|
||||||
Font = OsuFont.GetFont(size: TextSize),
|
Font = OsuFont.GetFont(size: TextSize),
|
||||||
}
|
}
|
||||||
}, null, LinkAction.OpenBeatmap, beatmap.OnlineBeatmapID.ToString(), "Open beatmap");
|
}, LinkAction.OpenBeatmap, beatmap.OnlineBeatmapID.ToString(), "Open beatmap");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user