diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs index 292319171d..8da077cd44 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs @@ -163,6 +163,25 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("second user crown visible", () => this.ChildrenOfType().ElementAt(1).ChildrenOfType().First().Alpha == 1); } + [Test] + public void TestHostGetsPinnedToTop() + { + AddStep("add user", () => MultiplayerClient.AddUser(new APIUser + { + Id = 3, + Username = "Second", + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg", + })); + + AddStep("make second user host", () => MultiplayerClient.TransferHost(3)); + AddAssert("second user above first", () => + { + var first = this.ChildrenOfType().ElementAt(0); + var second = this.ChildrenOfType().ElementAt(1); + return second.Y < first.Y; + }); + } + [Test] public void TestKickButtonOnlyPresentWhenHost() { @@ -202,9 +221,11 @@ namespace osu.Game.Tests.Visual.Multiplayer [Test] public void TestManyUsers() { + const int users_count = 20; + AddStep("add many users", () => { - for (int i = 0; i < 20; i++) + for (int i = 0; i < users_count; i++) { MultiplayerClient.AddUser(new APIUser { @@ -243,6 +264,9 @@ namespace osu.Game.Tests.Visual.Multiplayer } } }); + + AddRepeatStep("switch hosts", () => MultiplayerClient.TransferHost(RNG.Next(0, users_count)), 10); + AddStep("give host back", () => MultiplayerClient.TransferHost(API.LocalUser.Value.Id)); } [Test] diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs index 70f4030b79..7ba0a63856 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs @@ -198,15 +198,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants else userModsDisplay.FadeOut(fade_time); - if (Client.IsHost && !User.Equals(Client.LocalUser)) - kickButton.FadeIn(fade_time); - else - kickButton.FadeOut(fade_time); - - if (Room.Host?.Equals(User) == true) - crown.FadeIn(fade_time); - else - crown.FadeOut(fade_time); + kickButton.Alpha = Client.IsHost && !User.Equals(Client.LocalUser) ? 1 : 0; + crown.Alpha = Room.Host?.Equals(User) == true ? 1 : 0; // If the mods are updated at the end of the frame, the flow container will skip a reflow cycle: https://github.com/ppy/osu-framework/issues/4187 // This looks particularly jarring here, so re-schedule the update to that start of our frame as a fix. diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs index afb2111023..14b930f115 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -15,6 +16,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants { private FillFlowContainer panels; + [CanBeNull] + private ParticipantPanel currentHostPanel; + [BackgroundDependencyLoader] private void load() { @@ -55,6 +59,24 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants // Add panels for all users new to the room. foreach (var user in Room.Users.Except(panels.Select(p => p.User))) panels.Add(new ParticipantPanel(user)); + + if (currentHostPanel == null || !currentHostPanel.User.Equals(Room.Host)) + { + // Reset position of previous host back to normal, if one existing. + if (currentHostPanel != null && panels.Contains(currentHostPanel)) + panels.SetLayoutPosition(currentHostPanel, 0); + + currentHostPanel = null; + + // Change position of new host to display above all participants. + if (Room.Host != null) + { + currentHostPanel = panels.SingleOrDefault(u => u.User.Equals(Room.Host)); + + if (currentHostPanel != null) + panels.SetLayoutPosition(currentHostPanel, -1); + } + } } } }