diff --git a/osu.Android.props b/osu.Android.props index 43c1302e54..8b31be3f12 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -62,6 +62,6 @@ - + diff --git a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs index 39c2fbfcc9..d973799405 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs @@ -7,6 +7,9 @@ using osu.Game.Online.Chat; using osu.Game.Users; using osuTK; using System; +using System.Linq; +using osu.Framework.Graphics.Containers; +using osu.Game.Overlays.Chat; namespace osu.Game.Tests.Visual.Online { @@ -42,14 +45,14 @@ namespace osu.Game.Tests.Visual.Online [Cached] private ChannelManager channelManager = new ChannelManager(); - private readonly StandAloneChatDisplay chatDisplay; - private readonly StandAloneChatDisplay chatDisplay2; + private readonly TestStandAloneChatDisplay chatDisplay; + private readonly TestStandAloneChatDisplay chatDisplay2; public TestSceneStandAloneChatDisplay() { Add(channelManager); - Add(chatDisplay = new StandAloneChatDisplay + Add(chatDisplay = new TestStandAloneChatDisplay { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, @@ -57,7 +60,7 @@ namespace osu.Game.Tests.Visual.Online Size = new Vector2(400, 80) }); - Add(chatDisplay2 = new StandAloneChatDisplay(true) + Add(chatDisplay2 = new TestStandAloneChatDisplay(true) { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -119,6 +122,32 @@ namespace osu.Game.Tests.Visual.Online Content = "Message from the future!", Timestamp = DateTimeOffset.Now })); + + AddUntilStep("ensure still scrolled to bottom", () => chatDisplay.ScrolledToBottom); + + const int messages_per_call = 10; + AddRepeatStep("add many messages", () => + { + for (int i = 0; i < messages_per_call; i++) + testChannel.AddNewMessages(new Message(sequence++) + { + Sender = longUsernameUser, + Content = "Many messages! " + Guid.NewGuid(), + Timestamp = DateTimeOffset.Now + }); + }, Channel.MAX_HISTORY / messages_per_call + 5); + + AddUntilStep("ensure still scrolled to bottom", () => chatDisplay.ScrolledToBottom); + } + + private class TestStandAloneChatDisplay : StandAloneChatDisplay + { + public TestStandAloneChatDisplay(bool textbox = false) + : base(textbox) + { + } + + public bool ScrolledToBottom => ((ScrollContainer)((Container)InternalChildren.OfType().First().Child).Child).IsScrolledToEnd(1); } } } diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 9ec39c5cb1..451174a73c 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -14,7 +14,7 @@ namespace osu.Game.Online.Chat { public class Channel { - public readonly int MaxHistory = 300; + public const int MAX_HISTORY = 300; /// /// Contains every joined user except the current logged in user. Currently only returned for PM channels. @@ -80,8 +80,6 @@ namespace osu.Game.Online.Chat /// public Bindable Joined = new Bindable(); - public const int MAX_HISTORY = 300; - [JsonConstructor] public Channel() { @@ -162,8 +160,8 @@ namespace osu.Game.Online.Chat { // never purge local echos int messageCount = Messages.Count - pendingMessages.Count; - if (messageCount > MaxHistory) - Messages.RemoveRange(0, messageCount - MaxHistory); + if (messageCount > MAX_HISTORY) + Messages.RemoveRange(0, messageCount - MAX_HISTORY); } } } diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 6cdbfabe0f..9301daa9ff 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -89,8 +89,10 @@ namespace osu.Game.Overlays.Chat private void newMessagesArrived(IEnumerable newMessages) { + bool shouldScrollToEnd = scroll.IsScrolledToEnd(10) || !chatLines.Any() || newMessages.Any(m => m is LocalMessage); + // Add up to last Channel.MAX_HISTORY messages - var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MaxHistory)); + var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MAX_HISTORY)); Message lastMessage = chatLines.LastOrDefault()?.Message; @@ -103,19 +105,18 @@ namespace osu.Game.Overlays.Chat lastMessage = message; } - if (scroll.IsScrolledToEnd(10) || !chatLines.Any() || newMessages.Any(m => m is LocalMessage)) - scrollToEnd(); - var staleMessages = chatLines.Where(c => c.LifetimeEnd == double.MaxValue).ToArray(); - int count = staleMessages.Length - Channel.MaxHistory; + int count = staleMessages.Length - Channel.MAX_HISTORY; for (int i = 0; i < count; i++) { var d = staleMessages[i]; - if (!scroll.IsScrolledToEnd(10)) - scroll.OffsetScrollPosition(-d.DrawHeight); + scroll.OffsetScrollPosition(-d.DrawHeight); d.Expire(); } + + if (shouldScrollToEnd) + scrollToEnd(); } private void pendingMessageResolved(Message existing, Message updated) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e898a001de..0cb09d9b14 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -26,7 +26,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 656c60543e..719aced705 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -118,8 +118,8 @@ - - + +