Improve splitting out of link handling

This commit is contained in:
Dean Herbert 2019-10-31 18:34:41 +09:00
parent 83abb845b6
commit 11447023eb
6 changed files with 40 additions and 46 deletions

View File

@ -44,46 +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), text);
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 = () =>
{ {
if (action != null) if (action != null)
action(); action();
else else
game.HandleLink(url, linkType, linkArgument); game.HandleLink(link);
}, },
}); });
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.

View File

@ -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>

View File

@ -43,7 +43,6 @@ using osu.Game.Scoring;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
using osu.Game.Utils; using osu.Game.Utils;
using LogLevel = osu.Framework.Logging.LogLevel; using LogLevel = osu.Framework.Logging.LogLevel;
using static osu.Game.Online.Chat.MessageFormatter;
namespace osu.Game namespace osu.Game
{ {
@ -216,7 +215,9 @@ namespace osu.Game
private ExternalLinkOpener externalLinkOpener; private ExternalLinkOpener externalLinkOpener;
public void HandleLink(string url, LinkAction linkType, string linkArgument) public void HandleLink(string url) => HandleLink(MessageFormatter.GetLinkDetails(url));
public void HandleLink(LinkDetails link)
{ {
Action showNotImplementedError = () => notifications?.Post(new SimpleNotification Action showNotImplementedError = () => notifications?.Post(new SimpleNotification
{ {
@ -224,27 +225,27 @@ namespace osu.Game
Icon = FontAwesome.Solid.LifeRing, Icon = FontAwesome.Solid.LifeRing,
}); });
switch (linkType) switch (link.Action)
{ {
case LinkAction.OpenBeatmap: case LinkAction.OpenBeatmap:
// TODO: proper query params handling // TODO: proper query params handling
if (linkArgument != null && int.TryParse(linkArgument.Contains('?') ? linkArgument.Split('?')[0] : linkArgument, out int beatmapId)) if (link.Argument != null && int.TryParse(link.Argument.Contains('?') ? link.Argument.Split('?')[0] : link.Argument, out int beatmapId))
ShowBeatmap(beatmapId); ShowBeatmap(beatmapId);
break; break;
case LinkAction.OpenBeatmapSet: case LinkAction.OpenBeatmapSet:
if (int.TryParse(linkArgument, out int setId)) if (int.TryParse(link.Argument, out int setId))
ShowBeatmapSet(setId); ShowBeatmapSet(setId);
break; break;
case LinkAction.OpenChannel: case LinkAction.OpenChannel:
try try
{ {
channelManager.OpenChannel(linkArgument); channelManager.OpenChannel(link.Argument);
} }
catch (ChannelNotFoundException) catch (ChannelNotFoundException)
{ {
Logger.Log($"The requested channel \"{linkArgument}\" does not exist"); Logger.Log($"The requested channel \"{link.Argument}\" does not exist");
} }
break; break;
@ -256,28 +257,19 @@ namespace osu.Game
break; break;
case LinkAction.External: case LinkAction.External:
OpenUrlExternally(url); OpenUrlExternally(link.Argument);
break; break;
case LinkAction.OpenUserProfile: case LinkAction.OpenUserProfile:
if (long.TryParse(linkArgument, out long userId)) if (long.TryParse(link.Argument, out long userId))
ShowUser(userId); ShowUser(userId);
break; break;
default: default:
throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action."); throw new NotImplementedException($"This {nameof(LinkAction)} ({link.Action.ToString()}) is missing an associated action.");
} }
} }
public void HandleUrl(string url)
{
Logger.Log($"Request to handle url: {url}");
LinkDetails linkDetails = GetLinkDetails(url);
Schedule(() => HandleLink(url, linkDetails.Action, linkDetails.Argument));
}
public void OpenUrlExternally(string url) public void OpenUrlExternally(string url)
{ {
if (url.StartsWith("/")) if (url.StartsWith("/"))

View File

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

View File

@ -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");
} }
} }
} }

View File

@ -21,7 +21,7 @@ namespace osu.iOS
if (url.IsFileUrl) if (url.IsFileUrl)
Task.Run(() => game.Import(url.Path)); Task.Run(() => game.Import(url.Path));
else else
Task.Run(() => game.HandleUrl(url.AbsoluteString)); Task.Run(() => game.HandleLink(url.AbsoluteString));
return true; return true;
} }
} }