From a3477c3841d4c85f81a5fe5546e695c8ebbd836c Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Tue, 8 Mar 2022 22:30:58 +0000 Subject: [PATCH 1/7] Implement `ChannelListing` for new chat design Adds components `ChannelListing` and `ChannelListing` item with visual test. Essentially a more simplified version of the existing `ChannelSelectionOverlay` component. Correctly implements `IFilterable` behaviour to filter child channel items. Channel joined state is based on the underlying `Joined` bindable of the `Channel` class. Channel join/leave events are exposed via `OnRequestJoin` and `OnRequestLeave` events which should be handled by parent component. Requires a cached `OverlayColourScheme` instance to be provided by the parent overlay component when added. --- .../Online/NewChat/TestSceneChannelListing.cs | 90 +++++++++ osu.Game/Overlays/NewChat/ChannelListing.cs | 85 +++++++++ .../Overlays/NewChat/ChannelListingItem.cs | 175 ++++++++++++++++++ 3 files changed, 350 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs create mode 100644 osu.Game/Overlays/NewChat/ChannelListing.cs create mode 100644 osu.Game/Overlays/NewChat/ChannelListingItem.cs diff --git a/osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs b/osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs new file mode 100644 index 0000000000..cbec23a305 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs @@ -0,0 +1,90 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Testing; +using osu.Framework.Utils; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Chat; +using osu.Game.Overlays; +using osu.Game.Overlays.NewChat; +using osuTK; + +namespace osu.Game.Tests.Visual.Online.NewChat +{ + [TestFixture] + public class TestSceneChannelListing : OsuTestScene + { + [Cached] + private readonly OverlayColourProvider overlayColours = new OverlayColourProvider(OverlayColourScheme.Pink); + + private SearchTextBox search; + private ChannelListing listing; + + [SetUp] + public void SetUp() + { + Schedule(() => + { + Children = new Drawable[] + { + search = new SearchTextBox + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Width = 300, + Margin = new MarginPadding { Top = 100 }, + }, + listing = new ChannelListing + { + Size = new Vector2(800, 400), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + }; + listing.Show(); + search.Current.ValueChanged += term => listing.SearchTerm = term.NewValue; + }); + } + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("Add Join/Leave callbacks", () => + { + listing.OnRequestJoin += channel => channel.Joined.Value = true; + listing.OnRequestLeave += channel => channel.Joined.Value = false; + }); + } + + [Test] + public void TestAddRandomChannels() + { + AddStep("Add Random Channels", () => + { + listing.UpdateAvailableChannels(createRandomChannels(20)); + }); + } + + private Channel createRandomChannel() + { + var id = RNG.Next(0, 10000); + return new Channel + { + Name = $"#channel-{id}", + Topic = RNG.Next(4) < 3 ? $"We talk about the number {id} here" : null, + Type = ChannelType.Public, + Id = id, + }; + } + + private List createRandomChannels(int num) + => Enumerable.Range(0, num) + .Select(_ => createRandomChannel()) + .ToList(); + } +} diff --git a/osu.Game/Overlays/NewChat/ChannelListing.cs b/osu.Game/Overlays/NewChat/ChannelListing.cs new file mode 100644 index 0000000000..79371d0fed --- /dev/null +++ b/osu.Game/Overlays/NewChat/ChannelListing.cs @@ -0,0 +1,85 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Containers; +using osu.Game.Online.Chat; +using osuTK; + +namespace osu.Game.Overlays.NewChat +{ + public class ChannelListing : VisibilityContainer + { + public event Action? OnRequestJoin; + public event Action? OnRequestLeave; + + public string SearchTerm + { + get => flow.SearchTerm; + set => flow.SearchTerm = value; + } + + private SearchContainer flow = null!; + + [Resolved] + private OverlayColourProvider overlayColours { get; set; } = null!; + + public ChannelListing() + { + Masking = true; + } + + protected override void PopIn() => this.FadeIn(); + protected override void PopOut() => this.FadeOut(); + + public void UpdateAvailableChannels(IEnumerable newChannels) + { + flow.ChildrenEnumerable = newChannels.Where(c => c.Type == ChannelType.Public) + .Select(c => new ChannelListingItem(c)); + + foreach (var item in flow.Children) + { + item.OnRequestJoin += channel => OnRequestJoin?.Invoke(channel); + item.OnRequestLeave += channel => OnRequestLeave?.Invoke(channel); + } + } + + [BackgroundDependencyLoader] + private void load() + { + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = overlayColours.Background4, + }, + new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both, + ScrollbarAnchor = Anchor.TopRight, + Child = flow = new SearchContainer + { + Direction = FillDirection.Vertical, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(3), + Padding = new MarginPadding + { + Vertical = 13, + Horizontal = 15, + }, + }, + }, + }; + } + } +} diff --git a/osu.Game/Overlays/NewChat/ChannelListingItem.cs b/osu.Game/Overlays/NewChat/ChannelListingItem.cs new file mode 100644 index 0000000000..845db4e802 --- /dev/null +++ b/osu.Game/Overlays/NewChat/ChannelListingItem.cs @@ -0,0 +1,175 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable enable + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.Chat; +using osuTK; + +namespace osu.Game.Overlays.NewChat +{ + public class ChannelListingItem : OsuClickableContainer, IFilterable + { + public event Action? OnRequestJoin; + public event Action? OnRequestLeave; + + public bool FilteringActive { get; set; } + public IEnumerable FilterTerms => new[] { channel.Name, channel.Topic ?? string.Empty }; + public bool MatchingFilter + { + set => this.FadeTo(value ? 1f : 0f, 100); + } + + private readonly float TEXT_SIZE = 18; + private readonly float ICON_SIZE = 14; + private readonly Channel channel; + + private Colour4 selectedColour; + private Colour4 normalColour; + + private Box hoverBox = null!; + private SpriteIcon checkbox = null!; + private OsuSpriteText channelText = null!; + private IBindable channelJoined = null!; + + [Resolved] + private OverlayColourProvider overlayColours { get; set; } = null!; + + public ChannelListingItem(Channel channel) + { + this.channel = channel; + + Masking = true; + CornerRadius = 5; + RelativeSizeAxes = Axes.X; + Height = 20; + } + + protected override bool OnHover(HoverEvent e) + { + hoverBox.Show(); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + hoverBox.Hide(); + base.OnHoverLost(e); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + // Set colours + normalColour = overlayColours.Light3; + selectedColour = Colour4.White; + + // Set handlers for state display + channelJoined = channel.Joined.GetBoundCopy(); + channelJoined.BindValueChanged(change => + { + if (change.NewValue) + { + checkbox.Show(); + channelText.Colour = selectedColour; + } + else + { + checkbox.Hide(); + channelText.Colour = normalColour; + } + }, true); + + // Set action on click + Action = () => (channelJoined.Value ? OnRequestLeave : OnRequestJoin)?.Invoke(channel); + } + + [BackgroundDependencyLoader] + private void load() + { + Children = new Drawable[] + { + hoverBox = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = overlayColours.Background3, + Alpha = 0f, + }, + new GridContainer + { + RelativeSizeAxes = Axes.Both, + ColumnDimensions = new Dimension[] + { + new Dimension(GridSizeMode.Absolute, 40), + new Dimension(GridSizeMode.Absolute, 200), + new Dimension(GridSizeMode.Absolute, 400), + new Dimension(GridSizeMode.AutoSize), + new Dimension(), + }, + Content = new[] + { + new Drawable[] + { + checkbox = new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 15 }, + Icon = FontAwesome.Solid.Check, + Size = new Vector2(ICON_SIZE), + }, + channelText = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = $"# {channel.Name.Substring(1)}", + Font = OsuFont.Torus.With(size: TEXT_SIZE, weight: FontWeight.Medium), + Margin = new MarginPadding { Bottom = 2 }, + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = channel.Topic, + Font = OsuFont.Torus.With(size: TEXT_SIZE), + Margin = new MarginPadding { Bottom = 2 }, + Colour = Colour4.White, + }, + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = FontAwesome.Solid.User, + Size = new Vector2(ICON_SIZE), + Margin = new MarginPadding { Right = 5 }, + Colour = overlayColours.Light3, + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = "0", + Font = OsuFont.Numeric.With(size: TEXT_SIZE, weight: FontWeight.Medium), + Margin = new MarginPadding { Bottom = 2 }, + Colour = overlayColours.Light3, + }, + }, + }, + }, + }; + } + } +} From 7dd51a9c4a69ab6b6ef2618bc25c4eec08689002 Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Wed, 9 Mar 2022 00:12:44 +0000 Subject: [PATCH 2/7] Reorder class attributes --- osu.Game/Overlays/NewChat/ChannelListing.cs | 40 +++---- .../Overlays/NewChat/ChannelListingItem.cs | 110 +++++++++--------- 2 files changed, 72 insertions(+), 78 deletions(-) diff --git a/osu.Game/Overlays/NewChat/ChannelListing.cs b/osu.Game/Overlays/NewChat/ChannelListing.cs index 79371d0fed..3de6364303 100644 --- a/osu.Game/Overlays/NewChat/ChannelListing.cs +++ b/osu.Game/Overlays/NewChat/ChannelListing.cs @@ -30,27 +30,7 @@ namespace osu.Game.Overlays.NewChat private SearchContainer flow = null!; [Resolved] - private OverlayColourProvider overlayColours { get; set; } = null!; - - public ChannelListing() - { - Masking = true; - } - - protected override void PopIn() => this.FadeIn(); - protected override void PopOut() => this.FadeOut(); - - public void UpdateAvailableChannels(IEnumerable newChannels) - { - flow.ChildrenEnumerable = newChannels.Where(c => c.Type == ChannelType.Public) - .Select(c => new ChannelListingItem(c)); - - foreach (var item in flow.Children) - { - item.OnRequestJoin += channel => OnRequestJoin?.Invoke(channel); - item.OnRequestLeave += channel => OnRequestLeave?.Invoke(channel); - } - } + private OverlayColourProvider colourProvider { get; set; } = null!; [BackgroundDependencyLoader] private void load() @@ -60,7 +40,7 @@ namespace osu.Game.Overlays.NewChat new Box { RelativeSizeAxes = Axes.Both, - Colour = overlayColours.Background4, + Colour = colourProvider.Background4, }, new OsuScrollContainer { @@ -81,5 +61,21 @@ namespace osu.Game.Overlays.NewChat }, }; } + + public void UpdateAvailableChannels(IEnumerable newChannels) + { + flow.ChildrenEnumerable = newChannels.Where(c => c.Type == ChannelType.Public) + .Select(c => new ChannelListingItem(c)); + + foreach (var item in flow.Children) + { + item.OnRequestJoin += channel => OnRequestJoin?.Invoke(channel); + item.OnRequestLeave += channel => OnRequestLeave?.Invoke(channel); + } + } + + protected override void PopIn() => this.FadeIn(); + + protected override void PopOut() => this.FadeOut(); } } diff --git a/osu.Game/Overlays/NewChat/ChannelListingItem.cs b/osu.Game/Overlays/NewChat/ChannelListingItem.cs index 845db4e802..7e7cf36e91 100644 --- a/osu.Game/Overlays/NewChat/ChannelListingItem.cs +++ b/osu.Game/Overlays/NewChat/ChannelListingItem.cs @@ -27,15 +27,13 @@ namespace osu.Game.Overlays.NewChat public bool FilteringActive { get; set; } public IEnumerable FilterTerms => new[] { channel.Name, channel.Topic ?? string.Empty }; - public bool MatchingFilter - { - set => this.FadeTo(value ? 1f : 0f, 100); - } + public bool MatchingFilter { set => this.FadeTo(value ? 1f : 0f, 100); } - private readonly float TEXT_SIZE = 18; - private readonly float ICON_SIZE = 14; private readonly Channel channel; + private const float TEXT_SIZE = 18; + private const float ICON_SIZE = 14; + private Colour4 selectedColour; private Colour4 normalColour; @@ -45,73 +43,33 @@ namespace osu.Game.Overlays.NewChat private IBindable channelJoined = null!; [Resolved] - private OverlayColourProvider overlayColours { get; set; } = null!; + private OverlayColourProvider colourProvider { get; set; } = null!; public ChannelListingItem(Channel channel) { this.channel = channel; - - Masking = true; - CornerRadius = 5; - RelativeSizeAxes = Axes.X; - Height = 20; - } - - protected override bool OnHover(HoverEvent e) - { - hoverBox.Show(); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - hoverBox.Hide(); - base.OnHoverLost(e); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - // Set colours - normalColour = overlayColours.Light3; - selectedColour = Colour4.White; - - // Set handlers for state display - channelJoined = channel.Joined.GetBoundCopy(); - channelJoined.BindValueChanged(change => - { - if (change.NewValue) - { - checkbox.Show(); - channelText.Colour = selectedColour; - } - else - { - checkbox.Hide(); - channelText.Colour = normalColour; - } - }, true); - - // Set action on click - Action = () => (channelJoined.Value ? OnRequestLeave : OnRequestJoin)?.Invoke(channel); } [BackgroundDependencyLoader] private void load() { + Masking = true; + CornerRadius = 5; + RelativeSizeAxes = Axes.X; + Height = 20; + Children = new Drawable[] { hoverBox = new Box { RelativeSizeAxes = Axes.Both, - Colour = overlayColours.Background3, + Colour = colourProvider.Background3, Alpha = 0f, }, new GridContainer { RelativeSizeAxes = Axes.Both, - ColumnDimensions = new Dimension[] + ColumnDimensions = new[] { new Dimension(GridSizeMode.Absolute, 40), new Dimension(GridSizeMode.Absolute, 200), @@ -155,7 +113,7 @@ namespace osu.Game.Overlays.NewChat Icon = FontAwesome.Solid.User, Size = new Vector2(ICON_SIZE), Margin = new MarginPadding { Right = 5 }, - Colour = overlayColours.Light3, + Colour = colourProvider.Light3, }, new OsuSpriteText { @@ -164,12 +122,52 @@ namespace osu.Game.Overlays.NewChat Text = "0", Font = OsuFont.Numeric.With(size: TEXT_SIZE, weight: FontWeight.Medium), Margin = new MarginPadding { Bottom = 2 }, - Colour = overlayColours.Light3, + Colour = colourProvider.Light3, }, }, }, }, }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + // Set colours + normalColour = colourProvider.Light3; + selectedColour = Colour4.White; + + // Set handlers for state display + channelJoined = channel.Joined.GetBoundCopy(); + channelJoined.BindValueChanged(change => + { + if (change.NewValue) + { + checkbox.Show(); + channelText.Colour = selectedColour; + } + else + { + checkbox.Hide(); + channelText.Colour = normalColour; + } + }, true); + + // Set action on click + Action = () => (channelJoined.Value ? OnRequestLeave : OnRequestJoin)?.Invoke(channel); + } + + protected override bool OnHover(HoverEvent e) + { + hoverBox.Show(); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + hoverBox.Hide(); + base.OnHoverLost(e); + } } } From 7daa2d0ea4dd67f4aea73274ee2db9198f8b1871 Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Wed, 9 Mar 2022 00:33:46 +0000 Subject: [PATCH 3/7] Use correct fonts and colours in ChannelListingItem --- .../Overlays/NewChat/ChannelListingItem.cs | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/NewChat/ChannelListingItem.cs b/osu.Game/Overlays/NewChat/ChannelListingItem.cs index 7e7cf36e91..77d5599c9b 100644 --- a/osu.Game/Overlays/NewChat/ChannelListingItem.cs +++ b/osu.Game/Overlays/NewChat/ChannelListingItem.cs @@ -31,20 +31,18 @@ namespace osu.Game.Overlays.NewChat private readonly Channel channel; - private const float TEXT_SIZE = 18; - private const float ICON_SIZE = 14; - - private Colour4 selectedColour; - private Colour4 normalColour; - private Box hoverBox = null!; private SpriteIcon checkbox = null!; private OsuSpriteText channelText = null!; + private OsuSpriteText topicText = null!; private IBindable channelJoined = null!; [Resolved] private OverlayColourProvider colourProvider { get; set; } = null!; + private const float text_size = 18; + private const float icon_size = 14; + public ChannelListingItem(Channel channel) { this.channel = channel; @@ -87,31 +85,30 @@ namespace osu.Game.Overlays.NewChat Origin = Anchor.CentreLeft, Margin = new MarginPadding { Left = 15 }, Icon = FontAwesome.Solid.Check, - Size = new Vector2(ICON_SIZE), + Size = new Vector2(icon_size), }, channelText = new OsuSpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Text = $"# {channel.Name.Substring(1)}", - Font = OsuFont.Torus.With(size: TEXT_SIZE, weight: FontWeight.Medium), + Text = channel.Name, + Font = OsuFont.Torus.With(size: text_size, weight: FontWeight.SemiBold), Margin = new MarginPadding { Bottom = 2 }, }, - new OsuSpriteText + topicText = new OsuSpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Text = channel.Topic, - Font = OsuFont.Torus.With(size: TEXT_SIZE), + Font = OsuFont.Torus.With(size: text_size), Margin = new MarginPadding { Bottom = 2 }, - Colour = Colour4.White, }, new SpriteIcon { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Icon = FontAwesome.Solid.User, - Size = new Vector2(ICON_SIZE), + Size = new Vector2(icon_size), Margin = new MarginPadding { Right = 5 }, Colour = colourProvider.Light3, }, @@ -120,7 +117,7 @@ namespace osu.Game.Overlays.NewChat Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Text = "0", - Font = OsuFont.Numeric.With(size: TEXT_SIZE, weight: FontWeight.Medium), + Font = OsuFont.Torus.With(size: text_size), Margin = new MarginPadding { Bottom = 2 }, Colour = colourProvider.Light3, }, @@ -134,27 +131,23 @@ namespace osu.Game.Overlays.NewChat { base.LoadComplete(); - // Set colours - normalColour = colourProvider.Light3; - selectedColour = Colour4.White; - - // Set handlers for state display channelJoined = channel.Joined.GetBoundCopy(); channelJoined.BindValueChanged(change => { if (change.NewValue) { checkbox.Show(); - channelText.Colour = selectedColour; + channelText.Colour = Colour4.White; + topicText.Colour = Colour4.White; } else { checkbox.Hide(); - channelText.Colour = normalColour; + channelText.Colour = colourProvider.Light3; + topicText.Colour = colourProvider.Content2; } }, true); - // Set action on click Action = () => (channelJoined.Value ? OnRequestLeave : OnRequestJoin)?.Invoke(channel); } From 9720a06b16105f23fc9f151e67d3af0cce63004d Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Wed, 9 Mar 2022 00:52:33 +0000 Subject: [PATCH 4/7] Use `int` in ChannelListing test --- osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs b/osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs index cbec23a305..8f955c0520 100644 --- a/osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs +++ b/osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.Online.NewChat private Channel createRandomChannel() { - var id = RNG.Next(0, 10000); + int id = RNG.Next(0, 10000); return new Channel { Name = $"#channel-{id}", From b67f9269f919d47647be5a72d71f1667500194bb Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Wed, 9 Mar 2022 18:13:56 +0000 Subject: [PATCH 5/7] Remove `NewChat` namespace --- .../Visual/Online/{NewChat => }/TestSceneChannelListing.cs | 4 ++-- osu.Game/Overlays/{NewChat => Chat/Listing}/ChannelListing.cs | 2 +- .../Overlays/{NewChat => Chat/Listing}/ChannelListingItem.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game.Tests/Visual/Online/{NewChat => }/TestSceneChannelListing.cs (97%) rename osu.Game/Overlays/{NewChat => Chat/Listing}/ChannelListing.cs (98%) rename osu.Game/Overlays/{NewChat => Chat/Listing}/ChannelListingItem.cs (99%) diff --git a/osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs b/osu.Game.Tests/Visual/Online/TestSceneChannelListing.cs similarity index 97% rename from osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs rename to osu.Game.Tests/Visual/Online/TestSceneChannelListing.cs index 8f955c0520..e521db1c9d 100644 --- a/osu.Game.Tests/Visual/Online/NewChat/TestSceneChannelListing.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChannelListing.cs @@ -11,10 +11,10 @@ using osu.Framework.Utils; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Chat; using osu.Game.Overlays; -using osu.Game.Overlays.NewChat; +using osu.Game.Overlays.Chat.Listing; using osuTK; -namespace osu.Game.Tests.Visual.Online.NewChat +namespace osu.Game.Tests.Visual.Online { [TestFixture] public class TestSceneChannelListing : OsuTestScene diff --git a/osu.Game/Overlays/NewChat/ChannelListing.cs b/osu.Game/Overlays/Chat/Listing/ChannelListing.cs similarity index 98% rename from osu.Game/Overlays/NewChat/ChannelListing.cs rename to osu.Game/Overlays/Chat/Listing/ChannelListing.cs index 3de6364303..9b8b45c85f 100644 --- a/osu.Game/Overlays/NewChat/ChannelListing.cs +++ b/osu.Game/Overlays/Chat/Listing/ChannelListing.cs @@ -14,7 +14,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Online.Chat; using osuTK; -namespace osu.Game.Overlays.NewChat +namespace osu.Game.Overlays.Chat.Listing { public class ChannelListing : VisibilityContainer { diff --git a/osu.Game/Overlays/NewChat/ChannelListingItem.cs b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs similarity index 99% rename from osu.Game/Overlays/NewChat/ChannelListingItem.cs rename to osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs index 77d5599c9b..9586730c6b 100644 --- a/osu.Game/Overlays/NewChat/ChannelListingItem.cs +++ b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs @@ -18,7 +18,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Online.Chat; using osuTK; -namespace osu.Game.Overlays.NewChat +namespace osu.Game.Overlays.Chat.Listing { public class ChannelListingItem : OsuClickableContainer, IFilterable { From 1a187d4dec553a0563e6baa75a5c15e282c34a7b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 Mar 2022 15:49:18 +0900 Subject: [PATCH 6/7] Add animation to checkbox when joning/leaving a channel --- .../Overlays/Chat/Listing/ChannelListingItem.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs index 9586730c6b..83362bc79d 100644 --- a/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs +++ b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs @@ -81,9 +81,9 @@ namespace osu.Game.Overlays.Chat.Listing { checkbox = new SpriteIcon { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 15 }, + Alpha = 0, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Icon = FontAwesome.Solid.Check, Size = new Vector2(icon_size), }, @@ -134,15 +134,19 @@ namespace osu.Game.Overlays.Chat.Listing channelJoined = channel.Joined.GetBoundCopy(); channelJoined.BindValueChanged(change => { + const double duration = 500; + if (change.NewValue) { - checkbox.Show(); + checkbox.FadeIn(duration, Easing.OutQuint); + checkbox.ScaleTo(1f, duration, Easing.OutElastic); channelText.Colour = Colour4.White; topicText.Colour = Colour4.White; } else { - checkbox.Hide(); + checkbox.FadeOut(duration, Easing.OutQuint); + checkbox.ScaleTo(0.8f, duration, Easing.OutQuint); channelText.Colour = colourProvider.Light3; topicText.Colour = colourProvider.Content2; } @@ -159,7 +163,7 @@ namespace osu.Game.Overlays.Chat.Listing protected override void OnHoverLost(HoverLostEvent e) { - hoverBox.Hide(); + hoverBox.FadeOut(300, Easing.OutQuint); base.OnHoverLost(e); } } From 46f2db1712beda4ae0a33d2c5fe54b6b10f19b0a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 Mar 2022 15:58:19 +0900 Subject: [PATCH 7/7] Move `ChannelListingItem` spacing into item so input is always handled by an item in the list Without this change, there would be a couple of pixels between each list item where nothing would be hovered. This is a pretty annoying UX which we should be avoiding we possible. --- osu.Game/Overlays/Chat/Listing/ChannelListing.cs | 2 -- osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Chat/Listing/ChannelListing.cs b/osu.Game/Overlays/Chat/Listing/ChannelListing.cs index 9b8b45c85f..732c78de15 100644 --- a/osu.Game/Overlays/Chat/Listing/ChannelListing.cs +++ b/osu.Game/Overlays/Chat/Listing/ChannelListing.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Containers; using osu.Game.Online.Chat; -using osuTK; namespace osu.Game.Overlays.Chat.Listing { @@ -51,7 +50,6 @@ namespace osu.Game.Overlays.Chat.Listing Direction = FillDirection.Vertical, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Spacing = new Vector2(3), Padding = new MarginPadding { Vertical = 13, diff --git a/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs index 83362bc79d..526cbcda87 100644 --- a/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs +++ b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs @@ -43,6 +43,8 @@ namespace osu.Game.Overlays.Chat.Listing private const float text_size = 18; private const float icon_size = 14; + private const float vertical_margin = 1.5f; + public ChannelListingItem(Channel channel) { this.channel = channel; @@ -54,7 +56,7 @@ namespace osu.Game.Overlays.Chat.Listing Masking = true; CornerRadius = 5; RelativeSizeAxes = Axes.X; - Height = 20; + Height = 20 + (vertical_margin * 2); Children = new Drawable[] { @@ -62,6 +64,7 @@ namespace osu.Game.Overlays.Chat.Listing { RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background3, + Margin = new MarginPadding { Vertical = vertical_margin }, Alpha = 0f, }, new GridContainer