1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 22:07:25 +08:00

Add iOS URL Scheme support

This commit is contained in:
DTSDAO 2019-08-02 23:34:25 +08:00
parent 7a89476688
commit 1b5a9aecff
5 changed files with 93 additions and 51 deletions

View File

@ -86,52 +86,7 @@ namespace osu.Game.Graphics.Containers
{
RelativeSizeAxes = Axes.Both,
TooltipText = tooltipText ?? (url != text ? url : string.Empty),
Action = action ?? (() =>
{
switch (linkType)
{
case LinkAction.OpenBeatmap:
// TODO: proper query params handling
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.");
}
}),
Action = action ?? (() => LinkUtils.HandleLink(url, linkType, linkArgument, game, channelManager, showNotImplementedError)),
});
return drawables;

View File

@ -3,7 +3,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using osu.Framework.Logging;
namespace osu.Game.Online.Chat
{
@ -98,7 +100,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);
args[0] = args[0].TrimEnd(':');
@ -288,4 +290,54 @@ namespace osu.Game.Online.Chat
public int CompareTo(Link otherLink) => Index > otherLink.Index ? 1 : -1;
}
public static class LinkUtils
{
public static void HandleLink(string url, LinkAction linkType, string linkArgument, OsuGame game, ChannelManager channelManager = null, Action showNotImplementedError = null)
{
switch (linkType)
{
case LinkAction.OpenBeatmap:
// TODO: proper query params handling
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.");
}
}
}
}

View File

@ -43,6 +43,7 @@ using osu.Game.Scoring;
using osu.Game.Screens.Select;
using osu.Game.Utils;
using LogLevel = osu.Framework.Logging.LogLevel;
using static osu.Game.Online.Chat.MessageFormatter;
namespace osu.Game
{
@ -90,6 +91,8 @@ namespace osu.Game
private IntroScreen introScreen;
private bool loaded = false;
private Bindable<int> configRuleset;
private Bindable<int> configSkin;
@ -190,10 +193,29 @@ namespace osu.Game
Audio.AddAdjustment(AdjustableProperty.Volume, inactiveVolumeFade);
Beatmap.BindValueChanged(beatmapChanged, true);
loaded = true;
}
private ExternalLinkOpener externalLinkOpener;
public void HandleUrl(string url)
{
Logger.Log($"Request to handle url: {url}");
if (loaded)
{
Action showNotImplementedError = () => notifications?.Post(new SimpleNotification
{
Text = @"This link type is not yet supported!",
Icon = FontAwesome.Solid.LifeRing,
});
LinkDetails linkDetails = getLinkDetails(url);
Schedule(() => LinkUtils.HandleLink(url, linkDetails.Action, linkDetails.Argument, this, channelManager, showNotImplementedError));
}
else
Scheduler.AddDelayed(() => HandleUrl(url), 1000);
}
public void OpenUrlExternally(string url)
{
if (url.StartsWith("/"))

View File

@ -1,10 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Threading.Tasks;
using Foundation;
using osu.Framework.iOS;
using osu.Game;
using osu.Framework.Threading;
using UIKit;
namespace osu.iOS
@ -16,9 +15,9 @@ namespace osu.iOS
protected override Framework.Game CreateGame() => game = new OsuGameIOS();
public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
Task.Run(() => game.Import(url.Path));
game.HandleUrl(url.AbsoluteString);
return true;
}
}

View File

@ -107,5 +107,19 @@
</array>
</dict>
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>osu</string>
<string>osump</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
</dict>
</plist>