1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 00:47:24 +08:00

Merge pull request #18181 from jai-x/new-chat-visibility-behaviour

Update channel visibilty behaviour in new chat overlay
This commit is contained in:
Dean Herbert 2022-05-12 15:35:48 +09:00 committed by GitHub
commit 26d4237ff4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 65 additions and 89 deletions

View File

@ -25,7 +25,6 @@ namespace osu.Game.Tests.Visual.Online
[Cached]
private readonly Bindable<Channel> selected = new Bindable<Channel>();
private OsuSpriteText selectorText;
private OsuSpriteText selectedText;
private OsuSpriteText leaveText;
private ChannelList channelList;
@ -43,21 +42,12 @@ namespace osu.Game.Tests.Visual.Online
Height = 0.7f,
RowDimensions = new[]
{
new Dimension(GridSizeMode.Absolute, 20),
new Dimension(GridSizeMode.Absolute, 20),
new Dimension(GridSizeMode.Absolute, 20),
new Dimension(),
},
Content = new[]
{
new Drawable[]
{
selectorText = new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
},
},
new Drawable[]
{
selectedText = new OsuSpriteText
@ -89,7 +79,6 @@ namespace osu.Game.Tests.Visual.Online
channelList.OnRequestSelect += channel =>
{
channelList.SelectorActive.Value = false;
selected.Value = channel;
};
@ -101,12 +90,6 @@ namespace osu.Game.Tests.Visual.Online
channelList.RemoveChannel(channel);
};
channelList.SelectorActive.BindValueChanged(change =>
{
selectorText.Text = $"Channel Selector Active: {change.NewValue}";
selected.Value = null;
}, true);
selected.BindValueChanged(change =>
{
selectedText.Text = $"Selected Channel: {change.NewValue?.Name ?? "[null]"}";

View File

@ -121,6 +121,19 @@ namespace osu.Game.Tests.Visual.Online
});
}
[Test]
public void TestBasic()
{
AddStep("Show overlay with channel", () =>
{
chatOverlay.Show();
Channel joinedChannel = channelManager.JoinChannel(testChannel1);
channelManager.CurrentChannel.Value = joinedChannel;
});
AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible);
AddUntilStep("Channel is visible", () => channelIsVisible && currentDrawableChannel.Channel == testChannel1);
}
[Test]
public void TestShowHide()
{
@ -158,20 +171,17 @@ namespace osu.Game.Tests.Visual.Online
public void TestChannelSelection()
{
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Listing is visible", () => listingVisibility == Visibility.Visible);
AddAssert("Listing is visible", () => listingIsVisible);
AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1));
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddAssert("Listing is hidden", () => listingVisibility == Visibility.Hidden);
AddAssert("Loading is hidden", () => loadingVisibility == Visibility.Hidden);
AddAssert("Current channel is correct", () => channelManager.CurrentChannel.Value == testChannel1);
AddAssert("DrawableChannel is correct", () => currentDrawableChannel.Channel == testChannel1);
AddUntilStep("Channel 1 is visible", () => channelIsVisible && currentDrawableChannel.Channel == testChannel1);
}
[Test]
public void TestSearchInListing()
{
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Listing is visible", () => listingVisibility == Visibility.Visible);
AddAssert("Listing is visible", () => listingIsVisible);
AddStep("Search for 'number 2'", () => chatOverlayTextBox.Text = "number 2");
AddUntilStep("Only channel 2 visibile", () =>
{
@ -263,6 +273,7 @@ namespace osu.Game.Tests.Visual.Online
});
});
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel1));
AddUntilStep("Channel 1 is visible", () => channelIsVisible && currentDrawableChannel.Channel == testChannel1);
}
[Test]
@ -285,8 +296,7 @@ namespace osu.Game.Tests.Visual.Online
});
});
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel2));
AddAssert("Channel 2 is selected", () => channelManager.CurrentChannel.Value == testChannel2);
AddAssert("Channel 2 is visible", () => currentDrawableChannel.Channel == testChannel2);
AddUntilStep("Channel 2 is visible", () => channelIsVisible && currentDrawableChannel.Channel == testChannel2);
}
[Test]
@ -310,8 +320,7 @@ namespace osu.Game.Tests.Visual.Online
});
AddStep("Leave channel 2", () => channelManager.LeaveChannel(testChannel2));
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel2));
AddAssert("Channel 2 is selected", () => channelManager.CurrentChannel.Value == testChannel2);
AddAssert("Channel 2 is visible", () => currentDrawableChannel.Channel == testChannel2);
AddUntilStep("Channel 2 is visible", () => channelIsVisible && currentDrawableChannel.Channel == testChannel2);
}
[Test]
@ -331,6 +340,7 @@ namespace osu.Game.Tests.Visual.Online
});
});
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel1));
AddUntilStep("Channel 1 is visible", () => channelIsVisible && currentDrawableChannel.Channel == testChannel1);
}
[Test]
@ -351,6 +361,7 @@ namespace osu.Game.Tests.Visual.Online
});
AddStep("Set null channel", () => channelManager.CurrentChannel.Value = null);
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel1));
AddUntilStep("Channel 1 is visible", () => channelIsVisible && currentDrawableChannel.Channel == testChannel1);
}
[Test]
@ -365,7 +376,7 @@ namespace osu.Game.Tests.Visual.Online
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click listing", () => clickDrawable(chatOverlay.ChildrenOfType<ChannelListing>().Single()));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click drawable channel", () => clickDrawable(chatOverlay.ChildrenOfType<DrawableChannel>().Single()));
AddStep("Click drawable channel", () => clickDrawable(currentDrawableChannel));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click channel list", () => clickDrawable(chatOverlay.ChildrenOfType<ChannelList>().Single()));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
@ -375,14 +386,17 @@ namespace osu.Game.Tests.Visual.Online
AddAssert("TextBox is not focused", () => InputManager.FocusedDrawable == null);
}
private Visibility listingVisibility =>
chatOverlay.ChildrenOfType<ChannelListing>().Single().State.Value;
private bool listingIsVisible =>
chatOverlay.ChildrenOfType<ChannelListing>().Single().State.Value == Visibility.Visible;
private Visibility loadingVisibility =>
chatOverlay.ChildrenOfType<LoadingLayer>().Single().State.Value;
private bool loadingIsVisible =>
chatOverlay.ChildrenOfType<LoadingLayer>().Single().State.Value == Visibility.Visible;
private bool channelIsVisible =>
!listingIsVisible && !loadingIsVisible;
private DrawableChannel currentDrawableChannel =>
chatOverlay.ChildrenOfType<Container<DrawableChannel>>().Single().Child;
chatOverlay.ChildrenOfType<DrawableChannel>().Single();
private ChannelListItem getChannelListItem(Channel channel) =>
chatOverlay.ChildrenOfType<ChannelListItem>().Single(item => item.Channel == channel);

View File

@ -420,10 +420,11 @@ namespace osu.Game.Online.Chat
/// Joins a channel if it has not already been joined. Must be called from the update thread.
/// </summary>
/// <param name="channel">The channel to join.</param>
/// <param name="setCurrent">Set the channel to join as the current channel if the current channel is null.</param>
/// <returns>The joined channel. Note that this may not match the parameter channel as it is a backed object.</returns>
public Channel JoinChannel(Channel channel) => joinChannel(channel, true);
public Channel JoinChannel(Channel channel, bool setCurrent = true) => joinChannel(channel, true, setCurrent);
private Channel joinChannel(Channel channel, bool fetchInitialMessages = false)
private Channel joinChannel(Channel channel, bool fetchInitialMessages = false, bool setCurrent = true)
{
if (channel == null) return null;
@ -439,7 +440,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);
joinChannel(channel, fetchInitialMessages, setCurrent);
return channel;
case ChannelType.PM:
@ -460,7 +461,7 @@ namespace osu.Game.Online.Chat
default:
var req = new JoinChannelRequest(channel);
req.Success += () => joinChannel(channel, fetchInitialMessages);
req.Success += () => joinChannel(channel, fetchInitialMessages, setCurrent);
req.Failure += ex => LeaveChannel(channel);
api.Queue(req);
return channel;
@ -472,7 +473,8 @@ namespace osu.Game.Online.Chat
this.fetchInitialMessages(channel);
}
CurrentChannel.Value ??= channel;
if (setCurrent)
CurrentChannel.Value ??= channel;
return channel;
}

View File

@ -6,7 +6,6 @@
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;
@ -19,11 +18,9 @@ namespace osu.Game.Overlays.Chat.ChannelList
{
public class ChannelList : Container
{
public Action<Channel>? OnRequestSelect;
public Action<Channel?>? OnRequestSelect;
public Action<Channel>? OnRequestLeave;
public readonly BindableBool SelectorActive = new BindableBool();
private readonly Dictionary<Channel, ChannelListItem> channelMap = new Dictionary<Channel, ChannelListItem>();
private ChannelListItemFlow publicChannelFlow = null!;
@ -56,7 +53,7 @@ namespace osu.Game.Overlays.Chat.ChannelList
new ChannelListSelector
{
Margin = new MarginPadding { Bottom = 10 },
SelectorActive = { BindTarget = SelectorActive },
Action = () => OnRequestSelect?.Invoke(null),
},
privateChannelFlow = new ChannelListItemFlow("DIRECT MESSAGES"),
},
@ -73,7 +70,6 @@ namespace osu.Game.Overlays.Chat.ChannelList
ChannelListItem item = new ChannelListItem(channel);
item.OnRequestSelect += chan => OnRequestSelect?.Invoke(chan);
item.OnRequestLeave += chan => OnRequestLeave?.Invoke(chan);
item.SelectorActive.BindTarget = SelectorActive;
ChannelListItemFlow flow = getFlowForChannel(channel);
channelMap.Add(channel, item);

View File

@ -31,8 +31,6 @@ namespace osu.Game.Overlays.Chat.ChannelList
public readonly BindableBool Unread = new BindableBool();
public readonly BindableBool SelectorActive = new BindableBool();
private Box hoverBox = null!;
private Box selectBox = null!;
private OsuSpriteText text = null!;
@ -127,7 +125,6 @@ namespace osu.Game.Overlays.Chat.ChannelList
base.LoadComplete();
selectedChannel.BindValueChanged(_ => updateState(), true);
SelectorActive.BindValueChanged(_ => updateState(), true);
Unread.BindValueChanged(_ => updateState(), true);
}
@ -163,7 +160,7 @@ namespace osu.Game.Overlays.Chat.ChannelList
private void updateState()
{
bool selected = selectedChannel.Value == Channel && !SelectorActive.Value;
bool selected = selectedChannel.Value == Channel;
if (selected)
selectBox.FadeIn(300, Easing.OutQuint);

View File

@ -12,17 +12,19 @@ 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
{
public readonly BindableBool SelectorActive = new BindableBool();
private Box hoverBox = null!;
private Box selectBox = null!;
private OsuSpriteText text = null!;
[Resolved]
private Bindable<Channel> currentChannel { get; set; } = null!;
[Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!;
@ -69,9 +71,11 @@ namespace osu.Game.Overlays.Chat.ChannelList
{
base.LoadComplete();
SelectorActive.BindValueChanged(selector =>
currentChannel.BindValueChanged(channel =>
{
if (selector.NewValue)
// 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);
@ -82,8 +86,6 @@ namespace osu.Game.Overlays.Chat.ChannelList
selectBox.FadeOut(200, Easing.OutQuint);
}
}, true);
Action = () => SelectorActive.Value = true;
}
protected override bool OnHover(HoverEvent e)

View File

@ -50,8 +50,6 @@ namespace osu.Game.Overlays
private const float side_bar_width = 190;
private const float chat_bar_height = 60;
private readonly BindableBool selectorActive = new BindableBool();
[Resolved]
private OsuConfigManager config { get; set; } = null!;
@ -100,7 +98,6 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.Y,
Width = side_bar_width,
Padding = new MarginPadding { Top = top_bar_height },
SelectorActive = { BindTarget = selectorActive },
},
new Container
{
@ -137,7 +134,6 @@ namespace osu.Game.Overlays
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Padding = new MarginPadding { Left = side_bar_width },
ShowSearch = { BindTarget = selectorActive },
},
};
}
@ -146,8 +142,6 @@ namespace osu.Game.Overlays
{
base.LoadComplete();
loading.Show();
config.BindWith(OsuSetting.ChatDisplayHeight, chatHeight);
chatHeight.BindValueChanged(height => { Height = height.NewValue; }, true);
@ -157,21 +151,14 @@ namespace osu.Game.Overlays
channelManager.JoinedChannels.BindCollectionChanged(joinedChannelsChanged, true);
channelManager.AvailableChannels.BindCollectionChanged(availableChannelsChanged, true);
channelList.OnRequestSelect += channel =>
{
// Manually selecting a channel should dismiss the selector
selectorActive.Value = false;
channelManager.CurrentChannel.Value = channel;
};
channelList.OnRequestSelect += channel => channelManager.CurrentChannel.Value = channel;
channelList.OnRequestLeave += channel => channelManager.LeaveChannel(channel);
channelListing.OnRequestJoin += channel => channelManager.JoinChannel(channel);
channelListing.OnRequestJoin += channel => channelManager.JoinChannel(channel, false);
channelListing.OnRequestLeave += channel => channelManager.LeaveChannel(channel);
textBar.OnSearchTermsChanged += searchTerms => channelListing.SearchTerm = searchTerms;
textBar.OnChatMessageCommitted += handleChatMessage;
selectorActive.BindValueChanged(v => channelListing.State.Value = v.NewValue ? Visibility.Visible : Visibility.Hidden, true);
}
/// <summary>
@ -191,8 +178,6 @@ namespace osu.Game.Overlays
channelManager.CurrentChannel.Value = channel;
}
selectorActive.Value = false;
channel.HighlightedMessage.Value = message;
Show();
@ -252,28 +237,25 @@ namespace osu.Game.Overlays
{
Channel? newChannel = channel.NewValue;
loading.Show();
// Channel is null when leaving the currently selected channel
if (newChannel == null)
{
// Find another channel to switch to
newChannel = channelManager.JoinedChannels.FirstOrDefault(c => c != channel.OldValue);
if (newChannel == null)
selectorActive.Value = true;
else
currentChannel.Value = newChannel;
return;
// null channel denotes that we should be showing the listing.
channelListing.State.Value = Visibility.Visible;
textBar.ShowSearch.Value = true;
}
LoadComponentAsync(new DrawableChannel(newChannel), loaded =>
else
{
currentChannelContainer.Clear();
currentChannelContainer.Add(loaded);
loading.Hide();
});
channelListing.State.Value = Visibility.Hidden;
textBar.ShowSearch.Value = false;
loading.Show();
LoadComponentAsync(new DrawableChannel(newChannel), loaded =>
{
currentChannelContainer.Clear();
currentChannelContainer.Add(loaded);
loading.Hide();
});
}
}
private void joinedChannelsChanged(object sender, NotifyCollectionChangedEventArgs args)