From ae5b6c3e1068a130396c3a2f8fab554c362603c5 Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Sun, 15 May 2022 19:38:37 +0100 Subject: [PATCH] Use dummy channel to show selector and remove `ChannelListSelector` Add dummy channel `DummySelectorChannel` which should be set as the current channel in the channel manager when the selector in the chat overlay should be shown. Refactors the `ChannelListItem` to not show mention pill and close button when the channel is the dummy selector channel. Ensure that the `ChannelList` selects the dummy channel on clicking the selector item. Removes `ChannelListSelector` as it is no longer needed. Removes the `setCurrent` parameter from `ChannelManager.JoinChannel` method as it is no longer needed. --- .../Visual/Online/TestSceneChannelList.cs | 12 +- .../Visual/Online/TestSceneChatOverlayV2.cs | 5 +- osu.Game/Online/Chat/ChannelManager.cs | 18 +-- .../Overlays/Chat/ChannelList/ChannelList.cs | 10 +- .../Chat/ChannelList/ChannelListItem.cs | 60 +++++++--- .../Chat/ChannelList/ChannelListSelector.cs | 103 ------------------ osu.Game/Overlays/ChatOverlayV2.cs | 13 ++- 7 files changed, 80 insertions(+), 141 deletions(-) delete mode 100644 osu.Game/Overlays/Chat/ChannelList/ChannelListSelector.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneChannelList.cs b/osu.Game.Tests/Visual/Online/TestSceneChannelList.cs index 9929642539..53a48fcc58 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChannelList.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChannelList.cs @@ -118,35 +118,37 @@ namespace osu.Game.Tests.Visual.Online { AddStep("Unread Selected", () => { - if (selected.Value != null) + if (validItem) channelList.GetItem(selected.Value).Unread.Value = true; }); AddStep("Read Selected", () => { - if (selected.Value != null) + if (validItem) channelList.GetItem(selected.Value).Unread.Value = false; }); AddStep("Add Mention Selected", () => { - if (selected.Value != null) + if (validItem) channelList.GetItem(selected.Value).Mentions.Value++; }); AddStep("Add 98 Mentions Selected", () => { - if (selected.Value != null) + if (validItem) channelList.GetItem(selected.Value).Mentions.Value += 98; }); AddStep("Clear Mentions Selected", () => { - if (selected.Value != null) + if (validItem) channelList.GetItem(selected.Value).Mentions.Value = 0; }); } + private bool validItem => selected.Value != null && !(selected.Value is DummySelectorChannel); + private Channel createRandomPublicChannel() { int id = RNG.Next(0, 10000); diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlayV2.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlayV2.cs index bf1767cc96..48557a4ddb 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlayV2.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlayV2.cs @@ -372,7 +372,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1)); AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1))); AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox); - AddStep("Click selector", () => clickDrawable(chatOverlay.ChildrenOfType().Single())); + AddStep("Click selector", () => clickDrawable(channelSelectorButton)); AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox); AddStep("Click listing", () => clickDrawable(chatOverlay.ChildrenOfType().Single())); AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox); @@ -407,6 +407,9 @@ namespace osu.Game.Tests.Visual.Online private ChatOverlayTopBar chatOverlayTopBar => chatOverlay.ChildrenOfType().Single(); + private ChannelListItem channelSelectorButton => + chatOverlay.ChildrenOfType().Single(item => item.Channel is DummySelectorChannel); + private void clickDrawable(Drawable d) { InputManager.MoveMouseTo(d); diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 1fe784f68b..9524e8c1a7 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -14,6 +14,7 @@ using osu.Game.Input; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays; using osu.Game.Overlays.Chat.Tabs; namespace osu.Game.Online.Chat @@ -133,7 +134,9 @@ namespace osu.Game.Online.Chat private void currentChannelChanged(ValueChangedEvent e) { - if (!(e.NewValue is ChannelSelectorTabItem.ChannelSelectorTabChannel)) + bool isSelectorChannel = e.NewValue is ChannelSelectorTabItem.ChannelSelectorTabChannel || e.NewValue is DummySelectorChannel; + + if (!isSelectorChannel) JoinChannel(e.NewValue); } @@ -194,7 +197,6 @@ namespace osu.Game.Online.Chat createNewPrivateMessageRequest.Failure += exception => { - handlePostException(exception); target.ReplaceMessage(message, null); dequeueAndRun(); }; @@ -420,11 +422,10 @@ namespace osu.Game.Online.Chat /// Joins a channel if it has not already been joined. Must be called from the update thread. /// /// The channel to join. - /// Set the channel to join as the current channel if the current channel is null. /// The joined channel. Note that this may not match the parameter channel as it is a backed object. - public Channel JoinChannel(Channel channel, bool setCurrent = true) => joinChannel(channel, true, setCurrent); + public Channel JoinChannel(Channel channel) => joinChannel(channel, true); - private Channel joinChannel(Channel channel, bool fetchInitialMessages = false, bool setCurrent = true) + private Channel joinChannel(Channel channel, bool fetchInitialMessages = false) { if (channel == null) return null; @@ -440,7 +441,7 @@ namespace osu.Game.Online.Chat case ChannelType.Multiplayer: // join is implicit. happens when you join a multiplayer game. // this will probably change in the future. - joinChannel(channel, fetchInitialMessages, setCurrent); + joinChannel(channel, fetchInitialMessages); return channel; case ChannelType.PM: @@ -461,7 +462,7 @@ namespace osu.Game.Online.Chat default: var req = new JoinChannelRequest(channel); - req.Success += () => joinChannel(channel, fetchInitialMessages, setCurrent); + req.Success += () => joinChannel(channel, fetchInitialMessages); req.Failure += ex => LeaveChannel(channel); api.Queue(req); return channel; @@ -473,8 +474,7 @@ namespace osu.Game.Online.Chat this.fetchInitialMessages(channel); } - if (setCurrent) - CurrentChannel.Value ??= channel; + CurrentChannel.Value ??= channel; return channel; } diff --git a/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs b/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs index 6bdf5ee084..c9f3a4d380 100644 --- a/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs +++ b/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs @@ -18,13 +18,16 @@ namespace osu.Game.Overlays.Chat.ChannelList { public class ChannelList : Container { - public Action? OnRequestSelect; + public Action? OnRequestSelect; public Action? OnRequestLeave; private readonly Dictionary channelMap = new Dictionary(); + private readonly DummySelectorChannel dummySelectorChannel = new DummySelectorChannel(); + private ChannelListItemFlow publicChannelFlow = null!; private ChannelListItemFlow privateChannelFlow = null!; + private ChannelListItem selector = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -50,16 +53,17 @@ namespace osu.Game.Overlays.Chat.ChannelList Children = new Drawable[] { publicChannelFlow = new ChannelListItemFlow("CHANNELS"), - new ChannelListSelector + selector = new ChannelListItem(dummySelectorChannel) { Margin = new MarginPadding { Bottom = 10 }, - Action = () => OnRequestSelect?.Invoke(null), }, privateChannelFlow = new ChannelListItemFlow("DIRECT MESSAGES"), }, }, }, }; + + selector.OnRequestSelect += chan => OnRequestSelect?.Invoke(chan); } public void AddChannel(Channel channel) diff --git a/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs b/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs index dd571c9ad9..dfb0b6d781 100644 --- a/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Chat.ChannelList private Box hoverBox = null!; private Box selectBox = null!; private OsuSpriteText text = null!; - private ChannelListItemCloseButton close = null!; + private Drawable close = null!; [Resolved] private Bindable selectedChannel { get; set; } = null!; @@ -97,20 +97,8 @@ namespace osu.Game.Overlays.Chat.ChannelList RelativeSizeAxes = Axes.X, Truncate = true, }, - new ChannelListItemMentionPill - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Right = 3 }, - Mentions = { BindTarget = Mentions }, - }, - close = new ChannelListItemCloseButton - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Right = 3 }, - Action = () => OnRequestLeave?.Invoke(Channel), - } + createMentionPill(), + close = createCloseButton(), } }, }, @@ -131,14 +119,20 @@ namespace osu.Game.Overlays.Chat.ChannelList protected override bool OnHover(HoverEvent e) { hoverBox.FadeIn(300, Easing.OutQuint); - close.FadeIn(300, Easing.OutQuint); + + if (!isSelector) + close.FadeIn(300, Easing.OutQuint); + return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { hoverBox.FadeOut(200, Easing.OutQuint); - close.FadeOut(200, Easing.OutQuint); + + if (!isSelector) + close.FadeOut(200, Easing.OutQuint); + base.OnHoverLost(e); } @@ -158,9 +152,37 @@ namespace osu.Game.Overlays.Chat.ChannelList }; } + private Drawable createMentionPill() + { + if (isSelector) + return Drawable.Empty(); + + return new ChannelListItemMentionPill + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Right = 3 }, + Mentions = { BindTarget = Mentions }, + }; + } + + private Drawable createCloseButton() + { + if (isSelector) + return Drawable.Empty(); + + return new ChannelListItemCloseButton + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Right = 3 }, + Action = () => OnRequestLeave?.Invoke(Channel), + }; + } + private void updateState() { - bool selected = selectedChannel.Value == Channel; + bool selected = selectedChannel.Value == Channel || (isSelector && selectedChannel.Value == null); if (selected) selectBox.FadeIn(300, Easing.OutQuint); @@ -172,5 +194,7 @@ namespace osu.Game.Overlays.Chat.ChannelList else text.FadeColour(colourProvider.Light3, 200, Easing.OutQuint); } + + private bool isSelector => Channel is DummySelectorChannel; } } diff --git a/osu.Game/Overlays/Chat/ChannelList/ChannelListSelector.cs b/osu.Game/Overlays/Chat/ChannelList/ChannelListSelector.cs deleted file mode 100644 index a07aad2041..0000000000 --- a/osu.Game/Overlays/Chat/ChannelList/ChannelListSelector.cs +++ /dev/null @@ -1,103 +0,0 @@ -// 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 osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Online.Chat; - -namespace osu.Game.Overlays.Chat.ChannelList -{ - public class ChannelListSelector : OsuClickableContainer - { - private Box hoverBox = null!; - private Box selectBox = null!; - private OsuSpriteText text = null!; - - [Resolved] - private Bindable currentChannel { get; set; } = null!; - - [Resolved] - private OverlayColourProvider colourProvider { get; set; } = null!; - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - Height = 30; - RelativeSizeAxes = Axes.X; - - Children = new Drawable[] - { - hoverBox = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background3, - Alpha = 0f, - }, - selectBox = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background4, - Alpha = 0f, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = 18, Right = 10 }, - Child = text = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = "Add more channels", - Font = OsuFont.Torus.With(size: 17, weight: FontWeight.SemiBold), - Colour = colourProvider.Light3, - Margin = new MarginPadding { Bottom = 2 }, - RelativeSizeAxes = Axes.X, - Truncate = true, - }, - }, - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - currentChannel.BindValueChanged(channel => - { - // This logic should be handled by the chat overlay rather than this component. - // Selected state should be moved to an abstract class and shared with ChannelListItem. - if (channel.NewValue == null) - { - text.FadeColour(colourProvider.Content1, 300, Easing.OutQuint); - selectBox.FadeIn(300, Easing.OutQuint); - } - else - { - text.FadeColour(colourProvider.Light3, 200, Easing.OutQuint); - selectBox.FadeOut(200, Easing.OutQuint); - } - }, true); - } - - protected override bool OnHover(HoverEvent e) - { - hoverBox.FadeIn(300, Easing.OutQuint); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - hoverBox.FadeOut(200, Easing.OutQuint); - base.OnHoverLost(e); - } - } -} diff --git a/osu.Game/Overlays/ChatOverlayV2.cs b/osu.Game/Overlays/ChatOverlayV2.cs index 6eec0bbbf4..0307dcfdf3 100644 --- a/osu.Game/Overlays/ChatOverlayV2.cs +++ b/osu.Game/Overlays/ChatOverlayV2.cs @@ -154,7 +154,7 @@ namespace osu.Game.Overlays channelList.OnRequestSelect += channel => channelManager.CurrentChannel.Value = channel; channelList.OnRequestLeave += channel => channelManager.LeaveChannel(channel); - channelListing.OnRequestJoin += channel => channelManager.JoinChannel(channel, false); + channelListing.OnRequestJoin += channel => channelManager.JoinChannel(channel); channelListing.OnRequestLeave += channel => channelManager.LeaveChannel(channel); textBar.OnSearchTermsChanged += searchTerms => channelListing.SearchTerm = searchTerms; @@ -237,7 +237,7 @@ namespace osu.Game.Overlays { Channel? newChannel = channel.NewValue; - if (newChannel == null) + if (newChannel == null || newChannel is DummySelectorChannel) { // null channel denotes that we should be showing the listing. channelListing.State.Value = Visibility.Visible; @@ -293,4 +293,13 @@ namespace osu.Game.Overlays channelManager.PostMessage(message); } } + + public class DummySelectorChannel : Channel + { + public DummySelectorChannel() + { + Name = "Add more channels"; + Type = ChannelType.System; + } + } }