2018-01-09 13:34:52 +08:00
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
2017-12-07 20:17:51 +08:00
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
2017-12-28 08:12:13 +08:00
using OpenTK.Graphics ;
2017-12-07 20:17:51 +08:00
using osu.Framework.Allocation ;
2017-12-07 17:29:33 +08:00
using osu.Framework.Graphics ;
2017-12-28 08:12:13 +08:00
using osu.Framework.Graphics.Colour ;
2017-12-07 17:29:33 +08:00
using osu.Framework.Graphics.Containers ;
2017-12-31 07:51:47 +08:00
using osu.Game.Graphics ;
2017-12-29 03:11:21 +08:00
using osu.Game.Graphics.Containers ;
2017-12-07 17:29:33 +08:00
using osu.Game.Online.Chat ;
using osu.Game.Overlays ;
using osu.Game.Overlays.Chat ;
using osu.Game.Users ;
using System ;
using System.Linq ;
2018-01-09 19:22:23 +08:00
using osu.Game.Graphics.Sprites ;
2017-12-07 17:29:33 +08:00
namespace osu.Game.Tests.Visual
{
2017-12-26 02:43:35 +08:00
public class TestCaseChatLink : OsuTestCase
2017-12-07 17:29:33 +08:00
{
private readonly BeatmapSetOverlay beatmapSetOverlay ;
private readonly ChatOverlay chat ;
private DependencyContainer dependencies ;
2017-12-07 18:11:43 +08:00
private readonly TestChatLineContainer textContainer ;
2017-12-07 17:29:33 +08:00
protected override IReadOnlyDependencyContainer CreateLocalDependencies ( IReadOnlyDependencyContainer parent ) = > dependencies = new DependencyContainer ( parent ) ;
public TestCaseChatLink ( )
{
chat = new ChatOverlay ( ) ;
2017-12-07 18:11:43 +08:00
Add ( beatmapSetOverlay = new BeatmapSetOverlay { Depth = float . MinValue } ) ;
2017-12-07 17:29:33 +08:00
2017-12-07 18:11:43 +08:00
Add ( textContainer = new TestChatLineContainer
2017-12-07 17:29:33 +08:00
{
Padding = new MarginPadding { Left = 20 , Right = 20 } ,
RelativeSizeAxes = Axes . X ,
AutoSizeAxes = Axes . Y ,
Direction = FillDirection . Vertical ,
} ) ;
2017-12-28 08:12:13 +08:00
testLinksGeneral ( ) ;
testAddingLinks ( ) ;
testEcho ( ) ;
2017-12-28 00:14:08 +08:00
}
2017-12-28 08:12:13 +08:00
private void clear ( ) = > AddStep ( "clear messages" , textContainer . Clear ) ;
2017-12-31 07:51:47 +08:00
private void addMessageWithChecks ( string text , int linkAmount = 0 , bool isAction = false , bool isImportant = false )
2017-12-28 08:12:13 +08:00
{
2017-12-31 07:51:47 +08:00
var newLine = new ChatLine ( new DummyMessage ( text , isAction , isImportant ) ) ;
2017-12-28 08:12:13 +08:00
textContainer . Add ( newLine ) ;
2017-12-29 03:11:21 +08:00
AddAssert ( $"msg #{textContainer.Count} has {linkAmount} link(s)" , ( ) = > newLine . Message . Links . Count = = linkAmount ) ;
2017-12-29 04:45:58 +08:00
AddAssert ( $"msg #{textContainer.Count} is " + ( isAction ? "italic" : "not italic" ) , ( ) = > newLine . ContentFlow . Any ( ) & & isAction = = isItalic ( newLine . ContentFlow ) ) ;
2017-12-31 07:51:47 +08:00
AddAssert ( $"msg #{textContainer.Count} shows link(s)" , isShowingLinks ) ;
2017-12-29 04:45:58 +08:00
2018-01-09 19:22:23 +08:00
bool isItalic ( LinkFlowContainer c ) = > c . Cast < OsuSpriteText > ( ) . All ( sprite = > sprite . Font = = @"Exo2.0-MediumItalic" ) ;
2017-12-29 03:11:21 +08:00
2017-12-31 07:51:47 +08:00
bool isShowingLinks ( )
{
SRGBColour textColour = Color4 . White ;
bool hasBackground = ! string . IsNullOrEmpty ( newLine . Message . Sender . Colour ) ;
if ( isAction & & hasBackground )
textColour = OsuColour . FromHex ( newLine . Message . Sender . Colour ) ;
return newLine . ContentFlow
2018-01-09 19:22:23 +08:00
. Cast < OsuSpriteText > ( )
. All ( sprite = > sprite . HandleInput & & ! sprite . Colour . Equals ( textColour )
| | ! sprite . HandleInput & & sprite . Colour . Equals ( textColour )
2017-12-31 07:51:47 +08:00
// if someone with a background uses /me with a link, the usual link colour is overridden
2018-01-09 19:22:23 +08:00
| | isAction & & hasBackground & & sprite . HandleInput & & ! sprite . Colour . Equals ( ( ColourInfo ) Color4 . White ) ) ;
2017-12-31 07:51:47 +08:00
}
2017-12-28 08:12:13 +08:00
}
private void testLinksGeneral ( )
2017-12-28 00:14:08 +08:00
{
2017-12-28 08:12:13 +08:00
addMessageWithChecks ( "test!" ) ;
addMessageWithChecks ( "osu.ppy.sh!" ) ;
addMessageWithChecks ( "https://osu.ppy.sh!" , 1 ) ;
addMessageWithChecks ( "00:12:345 (1,2) - Test?" , 1 ) ;
addMessageWithChecks ( "Wiki link for tasty [[Performance Points]]" , 1 ) ;
addMessageWithChecks ( "(osu forums)[https://osu.ppy.sh/forum] (old link format)" , 1 ) ;
addMessageWithChecks ( "[https://osu.ppy.sh/home New site] (new link format)" , 1 ) ;
addMessageWithChecks ( "[https://osu.ppy.sh/home This is only a link to the new osu webpage but this is supposed to test word wrap.]" , 1 ) ;
addMessageWithChecks ( "is now listening to [https://osu.ppy.sh/s/93523 IMAGE -MATERIAL- <Version 0>]" , 1 , true ) ;
addMessageWithChecks ( "is now playing [https://osu.ppy.sh/b/252238 IMAGE -MATERIAL- <Version 0>]" , 1 , true ) ;
addMessageWithChecks ( "Let's (try)[https://osu.ppy.sh/home] [https://osu.ppy.sh/home multiple links] https://osu.ppy.sh/home" , 3 ) ;
// note that there's 0 links here (they get removed if a channel is not found)
addMessageWithChecks ( "#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present)." ) ;
2017-12-31 07:51:47 +08:00
addMessageWithChecks ( "I am important!" , 0 , false , true ) ;
addMessageWithChecks ( "feels important" , 0 , true , true ) ;
addMessageWithChecks ( "likes to post this [https://osu.ppy.sh/home link]." , 1 , true , true ) ;
2017-12-28 08:12:13 +08:00
}
private void testAddingLinks ( )
{
const int count = 5 ;
for ( int i = 1 ; i < = count ; i + + )
AddStep ( $"add long msg #{i}" , ( ) = > textContainer . Add ( new ChatLine ( new DummyMessage ( "alright let's just put a really long text here to see if it loads in correctly rather than adding the text sprites individually after the chat line appearing!" ) ) ) ) ;
clear ( ) ;
}
private void testEcho ( )
{
int echoCounter = 0 ;
addEchoWithWait ( "sent!" , "received!" ) ;
addEchoWithWait ( "https://osu.ppy.sh/home" , null , 500 ) ;
addEchoWithWait ( "[https://osu.ppy.sh/forum let's try multiple words too!]" ) ;
addEchoWithWait ( "(long loading times! clickable while loading?)[https://osu.ppy.sh/home]" , null , 5000 ) ;
void addEchoWithWait ( string text , string completeText = null , double delay = 250 )
{
var newLine = new ChatLine ( new DummyEchoMessage ( text ) ) ;
AddStep ( $"send msg #{++echoCounter} after {delay}ms" , ( ) = >
{
textContainer . Add ( newLine ) ;
Scheduler . AddDelayed ( ( ) = > newLine . Message = new DummyMessage ( completeText ? ? text ) , delay ) ;
} ) ;
AddUntilStep ( ( ) = > textContainer . All ( line = > line . Message is DummyMessage ) , $"wait for msg #{echoCounter}" ) ;
}
2017-12-07 17:29:33 +08:00
}
[BackgroundDependencyLoader]
private void load ( )
{
dependencies . Cache ( chat ) ;
dependencies . Cache ( beatmapSetOverlay ) ;
}
2017-12-28 08:12:13 +08:00
private class DummyEchoMessage : LocalEchoMessage
{
public DummyEchoMessage ( string text )
{
Content = text ;
Timestamp = DateTimeOffset . Now ;
Sender = DummyMessage . TEST_SENDER ;
}
}
2017-12-07 17:29:33 +08:00
private class DummyMessage : Message
{
2017-12-07 23:41:46 +08:00
private static long messageCounter ;
2017-12-31 07:51:47 +08:00
internal static readonly User TEST_SENDER_BACKGROUND = new User
{
Username = @"i-am-important" ,
Id = 42 ,
Colour = "#250cc9" ,
} ;
2017-12-28 08:12:13 +08:00
internal static readonly User TEST_SENDER = new User
2017-12-07 17:29:33 +08:00
{
Username = @"Somebody" ,
Id = 1 ,
} ;
2017-12-07 20:17:51 +08:00
2017-12-07 17:29:33 +08:00
public new DateTimeOffset Timestamp = DateTimeOffset . Now ;
2017-12-31 07:51:47 +08:00
public DummyMessage ( string text , bool isAction = false , bool isImportant = false )
2017-12-07 17:29:33 +08:00
: base ( messageCounter + + )
{
Content = text ;
IsAction = isAction ;
2017-12-31 07:51:47 +08:00
Sender = isImportant ? TEST_SENDER_BACKGROUND : TEST_SENDER ;
2017-12-07 17:29:33 +08:00
}
}
2017-12-07 18:11:43 +08:00
private class TestChatLineContainer : FillFlowContainer < ChatLine >
2017-12-07 17:29:33 +08:00
{
protected override int Compare ( Drawable x , Drawable y )
{
var xC = ( ChatLine ) x ;
var yC = ( ChatLine ) y ;
return xC . Message . CompareTo ( yC . Message ) ;
}
}
}
}