2017-12-02 03:32:08 +08:00
|
|
|
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
|
|
|
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
|
|
|
|
|
|
|
|
using OpenTK.Graphics;
|
|
|
|
|
using osu.Framework.Allocation;
|
|
|
|
|
using osu.Framework.Graphics;
|
|
|
|
|
using osu.Framework.Graphics.Containers;
|
|
|
|
|
using osu.Framework.Input;
|
2017-12-03 13:52:57 +08:00
|
|
|
|
using osu.Game.Beatmaps;
|
2017-12-02 03:32:08 +08:00
|
|
|
|
using osu.Game.Graphics.Containers;
|
2017-12-02 16:48:55 +08:00
|
|
|
|
using osu.Game.Overlays;
|
2017-12-02 03:32:08 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace osu.Game.Graphics.Sprites
|
|
|
|
|
{
|
|
|
|
|
public class OsuLinkSpriteText : OsuSpriteText
|
|
|
|
|
{
|
2017-12-04 03:45:30 +08:00
|
|
|
|
private ChatOverlay chat;
|
|
|
|
|
|
2017-12-02 03:32:08 +08:00
|
|
|
|
private readonly OsuHoverContainer content;
|
|
|
|
|
|
2017-12-02 16:48:55 +08:00
|
|
|
|
private BeatmapSetOverlay beatmapSetOverlay;
|
|
|
|
|
|
2017-12-02 03:32:08 +08:00
|
|
|
|
public override bool HandleInput => content.Action != null;
|
|
|
|
|
|
|
|
|
|
protected override Container<Drawable> Content => content ?? (Container<Drawable>)this;
|
|
|
|
|
|
|
|
|
|
protected override IEnumerable<Drawable> FlowingChildren => Children;
|
|
|
|
|
|
|
|
|
|
private string url;
|
|
|
|
|
|
|
|
|
|
public string Url
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (value != null)
|
|
|
|
|
{
|
|
|
|
|
url = value;
|
2017-12-02 16:48:55 +08:00
|
|
|
|
loadAction();
|
2017-12-02 03:32:08 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public OsuLinkSpriteText()
|
|
|
|
|
{
|
|
|
|
|
AddInternal(content = new OsuHoverContainer
|
|
|
|
|
{
|
|
|
|
|
AutoSizeAxes = Axes.Both,
|
|
|
|
|
});
|
|
|
|
|
}
|
2017-12-02 16:48:55 +08:00
|
|
|
|
|
|
|
|
|
[BackgroundDependencyLoader]
|
2017-12-04 03:45:30 +08:00
|
|
|
|
private void load(BeatmapSetOverlay beatmapSetOverlay, ChatOverlay chat)
|
2017-12-02 16:48:55 +08:00
|
|
|
|
{
|
|
|
|
|
this.beatmapSetOverlay = beatmapSetOverlay;
|
2017-12-04 03:45:30 +08:00
|
|
|
|
this.chat = chat;
|
2017-12-02 16:48:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void loadAction()
|
|
|
|
|
{
|
|
|
|
|
if (Url == null || String.IsNullOrEmpty(Url))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var url = Url;
|
|
|
|
|
|
2017-12-04 03:45:30 +08:00
|
|
|
|
// Client-internal stuff
|
|
|
|
|
if (url.StartsWith("osu://"))
|
|
|
|
|
{
|
|
|
|
|
var firstPath = url.Substring(6, 5);
|
|
|
|
|
url = url.Substring(11);
|
|
|
|
|
|
|
|
|
|
if (firstPath == "chan/")
|
|
|
|
|
{
|
|
|
|
|
var nextSlashIndex = url.IndexOf('/');
|
2017-12-04 04:02:05 +08:00
|
|
|
|
var channelName = nextSlashIndex != -1 ? url.Remove(nextSlashIndex) : url;
|
2017-12-04 03:45:30 +08:00
|
|
|
|
|
|
|
|
|
var foundChannel = chat.AvailableChannels.Find(channel => channel.Name == channelName);
|
|
|
|
|
|
|
|
|
|
if (foundChannel != null)
|
2017-12-04 04:02:05 +08:00
|
|
|
|
content.Action = () => chat.OpenChannel(foundChannel);
|
2017-12-04 03:45:30 +08:00
|
|
|
|
}
|
|
|
|
|
else if (firstPath == "edit/")
|
|
|
|
|
{
|
|
|
|
|
// Open editor here, then goto specified time
|
|
|
|
|
// how to push new screen from here? we'll see
|
2017-12-04 04:02:05 +08:00
|
|
|
|
content.Action = () => new Framework.Screens.Screen().Push(new Screens.Edit.Editor());
|
2017-12-04 03:45:30 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw new ArgumentException($"Unknown osu:// link at {nameof(OsuLinkSpriteText)} ({firstPath}).");
|
|
|
|
|
}
|
|
|
|
|
else if (url.StartsWith("http://") || url.StartsWith("https://"))
|
2017-12-02 16:48:55 +08:00
|
|
|
|
{
|
2017-12-03 13:52:57 +08:00
|
|
|
|
var osuUrlIndex = url.IndexOf("osu.ppy.sh/");
|
|
|
|
|
if (osuUrlIndex == -1)
|
|
|
|
|
{
|
|
|
|
|
content.Action = () => Process.Start(url);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
url = url.Substring(osuUrlIndex + 11);
|
|
|
|
|
if (url.StartsWith("s/") || url.StartsWith("beatmapsets/") || url.StartsWith("d/"))
|
2017-12-02 16:48:55 +08:00
|
|
|
|
content.Action = () => beatmapSetOverlay.ShowBeatmapSet(getIdFromUrl(url));
|
2017-12-03 13:52:57 +08:00
|
|
|
|
else if (url.StartsWith("b/") || url.StartsWith("beatmaps/"))
|
2017-12-02 16:48:55 +08:00
|
|
|
|
content.Action = () => beatmapSetOverlay.ShowBeatmap(getIdFromUrl(url));
|
|
|
|
|
}
|
2017-12-03 13:52:57 +08:00
|
|
|
|
else
|
|
|
|
|
content.Action = () => Process.Start(url);
|
2017-12-02 16:48:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int getIdFromUrl(string url)
|
|
|
|
|
{
|
|
|
|
|
var lastSlashIndex = url.LastIndexOf('/');
|
2017-12-03 13:52:57 +08:00
|
|
|
|
// Remove possible trailing slash
|
2017-12-02 16:48:55 +08:00
|
|
|
|
if (lastSlashIndex == url.Length)
|
|
|
|
|
{
|
2017-12-04 04:02:05 +08:00
|
|
|
|
url = url.Remove(url.Length - 1);
|
2017-12-02 16:48:55 +08:00
|
|
|
|
lastSlashIndex = url.LastIndexOf('/');
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-03 13:52:57 +08:00
|
|
|
|
var lastQuestionMarkIndex = url.LastIndexOf('?');
|
|
|
|
|
// Filter out possible queries like mode specifications (e.g. /b/252238?m=0)
|
|
|
|
|
if (lastQuestionMarkIndex > lastSlashIndex)
|
2017-12-04 04:02:05 +08:00
|
|
|
|
url = url.Remove(lastQuestionMarkIndex);
|
2017-12-03 13:52:57 +08:00
|
|
|
|
|
2017-12-02 16:48:55 +08:00
|
|
|
|
return int.Parse(url.Substring(lastSlashIndex + 1));
|
|
|
|
|
}
|
2017-12-02 03:32:08 +08:00
|
|
|
|
}
|
|
|
|
|
}
|