diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs b/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs index 1e80acd56b..8c5475223c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs @@ -3,11 +3,13 @@ #nullable disable +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; @@ -18,7 +20,7 @@ using osu.Game.Overlays.Chat; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public partial class TestSceneChatTextBox : OsuTestScene + public partial class TestSceneChatTextBox : OsuManualInputManagerTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); @@ -30,6 +32,8 @@ namespace osu.Game.Tests.Visual.Online private OsuSpriteText searchText; private ChatTextBar bar; + private ChatTextBox textBox => bar.ChildrenOfType().Single(); + [SetUp] public void SetUp() { @@ -115,6 +119,36 @@ namespace osu.Game.Tests.Visual.Online AddStep("Chat Mode Search", () => bar.ShowSearch.Value = true); } + [Test] + public void TestLengthLimit() + { + var firstChannel = new Channel + { + Name = "#test1", + Type = ChannelType.Public, + Id = 4567, + MessageLengthLimit = 20 + }; + var secondChannel = new Channel + { + Name = "#test2", + Type = ChannelType.Public, + Id = 5678, + MessageLengthLimit = 5 + }; + + AddStep("switch to channel with 20 char length limit", () => currentChannel.Value = firstChannel); + AddStep("type a message", () => textBox.Current.Value = "abcdefgh"); + + AddStep("switch to channel with 5 char length limit", () => currentChannel.Value = secondChannel); + AddAssert("text box empty", () => textBox.Current.Value, () => Is.Empty); + AddStep("type too much", () => textBox.Current.Value = "123456"); + AddAssert("text box has 5 chars", () => textBox.Current.Value, () => Has.Length.EqualTo(5)); + + AddStep("switch back to channel with 20 char length limit", () => currentChannel.Value = firstChannel); + AddAssert("unsent message preserved without truncation", () => textBox.Current.Value, () => Is.EqualTo("abcdefgh")); + } + private static Channel createPublicChannel(string name) => new Channel { Name = name, Type = ChannelType.Public, Id = 1234 }; diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 761e8aba8d..15ce926039 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -12,6 +12,7 @@ using osu.Framework.Bindables; using osu.Framework.Lists; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Chat; +using osu.Game.Overlays.Chat.Listing; namespace osu.Game.Online.Chat { @@ -86,6 +87,12 @@ namespace osu.Game.Online.Chat [JsonProperty(@"last_read_id")] public long? LastReadId; + /// + /// Purposefully nullable for the sake of . + /// + [JsonProperty(@"message_length_limit")] + public int? MessageLengthLimit; + /// /// Signals if the current user joined this channel or not. Defaults to false. /// Note that this does not guarantee a join has completed. Check Id > 0 for confirmation. diff --git a/osu.Game/Overlays/Chat/ChatTextBar.cs b/osu.Game/Overlays/Chat/ChatTextBar.cs index 87e787fcb8..16a8d14b10 100644 --- a/osu.Game/Overlays/Chat/ChatTextBar.cs +++ b/osu.Game/Overlays/Chat/ChatTextBar.cs @@ -156,7 +156,11 @@ namespace osu.Game.Overlays.Chat chatTextBox.Current.UnbindFrom(change.OldValue.TextBoxMessage); if (newChannel != null) + { + // change length limit first before binding to avoid accidentally truncating pending message from new channel. + chatTextBox.LengthLimit = newChannel.MessageLengthLimit; chatTextBox.Current.BindTo(newChannel.TextBoxMessage); + } }, true); }