mirror of
https://github.com/ppy/osu.git
synced 2026-05-27 05:01:22 +08:00
Merge pull request #34764 from bdach/pinned-rooms
Add support for pinning multiplayer rooms
This commit is contained in:
@@ -52,25 +52,25 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
[Test]
|
||||
public void TestBasicListChanges()
|
||||
{
|
||||
AddStep("add rooms", () => rooms.AddRange(GenerateRooms(5, withSpotlightRooms: true)));
|
||||
AddStep("add rooms", () => rooms.AddRange(GenerateRooms(5, withPinnedRooms: true)));
|
||||
|
||||
AddAssert("has 5 rooms", () => container.DrawableRooms.Count == 5);
|
||||
|
||||
AddAssert("all spotlights at top", () => container.DrawableRooms
|
||||
.SkipWhile(r => r.Room.Category == RoomCategory.Spotlight)
|
||||
.All(r => r.Room.Category == RoomCategory.Normal));
|
||||
AddAssert("all pinned at top", () => container.DrawableRooms
|
||||
.SkipWhile(r => r.Room.Pinned)
|
||||
.All(r => !r.Room.Pinned));
|
||||
|
||||
AddStep("remove first room", () => rooms.RemoveAt(0));
|
||||
AddAssert("has 4 rooms", () => container.DrawableRooms.Count == 4);
|
||||
AddAssert("first room removed", () => container.DrawableRooms.All(r => r.Room.RoomID != 0));
|
||||
|
||||
AddStep("select first room", () => container.DrawableRooms.First().TriggerClick());
|
||||
AddAssert("first spotlight selected", () => checkRoomSelected(rooms.First(r => r.Category == RoomCategory.Spotlight)));
|
||||
AddAssert("first pinned room selected", () => checkRoomSelected(rooms.First(r => r.Pinned)));
|
||||
|
||||
AddStep("remove last room", () => rooms.RemoveAt(rooms.Count - 1));
|
||||
AddAssert("first spotlight still selected", () => checkRoomSelected(rooms.First(r => r.Category == RoomCategory.Spotlight)));
|
||||
AddAssert("first pinned room selected", () => checkRoomSelected(rooms.First(r => r.Pinned)));
|
||||
|
||||
AddStep("remove spotlight room", () => rooms.RemoveAll(r => r.Category == RoomCategory.Spotlight));
|
||||
AddStep("remove pinned rooms", () => rooms.RemoveAll(r => r.Pinned));
|
||||
AddAssert("selection vacated", () => checkRoomSelected(null));
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +81,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
CurrentPlaylistItem = item1
|
||||
}),
|
||||
createLoungeRoom(new Room
|
||||
{
|
||||
Name = "Pinned room",
|
||||
Pinned = true,
|
||||
EndDate = DateTimeOffset.Now.AddDays(1),
|
||||
Type = MatchType.HeadToHead,
|
||||
Playlist = [item1],
|
||||
CurrentPlaylistItem = item1
|
||||
}),
|
||||
createLoungeRoom(new Room
|
||||
{
|
||||
Name = "Private room",
|
||||
Password = "*",
|
||||
@@ -121,9 +130,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
};
|
||||
});
|
||||
|
||||
AddUntilStep("wait for panel load", () => rooms.Count == 7);
|
||||
AddUntilStep("correct status text", () => rooms.ChildrenOfType<OsuSpriteText>().Count(s => s.Text.ToString().StartsWith("Currently playing", StringComparison.Ordinal)) == 2);
|
||||
AddUntilStep("correct status text", () => rooms.ChildrenOfType<OsuSpriteText>().Count(s => s.Text.ToString().StartsWith("Ready to play", StringComparison.Ordinal)) == 5);
|
||||
AddUntilStep("wait for panel load", () => rooms.Count, () => Is.EqualTo(8));
|
||||
AddUntilStep("\"currently playing\" room count correct", () => rooms.ChildrenOfType<OsuSpriteText>().Count(s => s.Text.ToString().StartsWith("Currently playing", StringComparison.Ordinal)), () => Is.EqualTo(3));
|
||||
AddUntilStep("\"ready to play\" room count correct", () => rooms.ChildrenOfType<OsuSpriteText>().Count(s => s.Text.ToString().StartsWith("Ready to play", StringComparison.Ordinal)), () => Is.EqualTo(4));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -140,13 +149,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
AddUntilStep("wait for panel load", () => panel.ChildrenOfType<DrawableRoomParticipantsList>().Any());
|
||||
|
||||
AddAssert("password icon hidden", () => Precision.AlmostEquals(0, panel.ChildrenOfType<RoomPanel.PasswordProtectedIcon>().Single().Alpha));
|
||||
AddAssert("password icon hidden", () => Precision.AlmostEquals(0, panel.ChildrenOfType<RoomPanel.CornerIcon>().First().Alpha));
|
||||
|
||||
AddStep("set password", () => room.Password = "password");
|
||||
AddAssert("password icon visible", () => Precision.AlmostEquals(1, panel.ChildrenOfType<RoomPanel.PasswordProtectedIcon>().Single().Alpha));
|
||||
AddAssert("password icon visible", () => Precision.AlmostEquals(1, panel.ChildrenOfType<RoomPanel.CornerIcon>().First().Alpha));
|
||||
|
||||
AddStep("unset password", () => room.Password = string.Empty);
|
||||
AddAssert("password icon hidden", () => Precision.AlmostEquals(0, panel.ChildrenOfType<RoomPanel.PasswordProtectedIcon>().Single().Alpha));
|
||||
AddAssert("password icon hidden", () => Precision.AlmostEquals(0, panel.ChildrenOfType<RoomPanel.CornerIcon>().First().Alpha));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -263,6 +263,12 @@ namespace osu.Game.Online.Rooms
|
||||
set => SetField(ref availability, value);
|
||||
}
|
||||
|
||||
public bool Pinned
|
||||
{
|
||||
get => pinned;
|
||||
set => SetField(ref pinned, value);
|
||||
}
|
||||
|
||||
[JsonProperty("id")]
|
||||
private long? roomId;
|
||||
|
||||
@@ -339,6 +345,9 @@ namespace osu.Game.Online.Rooms
|
||||
[JsonConverter(typeof(SnakeCaseStringEnumConverter))]
|
||||
private RoomStatus status;
|
||||
|
||||
[JsonProperty("pinned")]
|
||||
private bool pinned;
|
||||
|
||||
// Not yet serialised (not implemented).
|
||||
private RoomAvailability availability;
|
||||
|
||||
|
||||
@@ -194,8 +194,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
|
||||
roomFlow.Add(drawableRoom);
|
||||
|
||||
// Always show spotlight playlists at the top of the listing.
|
||||
roomFlow.SetLayoutPosition(drawableRoom, room.Category > RoomCategory.Normal ? float.MinValue : -(room.RoomID ?? 0));
|
||||
roomFlow.SetLayoutPosition(drawableRoom, room.Pinned ? float.MinValue : -(room.RoomID ?? 0));
|
||||
}
|
||||
|
||||
applyFilterCriteria(Filter.Value);
|
||||
|
||||
@@ -59,7 +59,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
|
||||
private DrawableRoomParticipantsList? drawableRoomParticipantsList;
|
||||
private RoomSpecialCategoryPill? specialCategoryPill;
|
||||
private PasswordProtectedIcon? passwordIcon;
|
||||
private CornerIcon? passwordIcon;
|
||||
private CornerIcon? pinnedIcon;
|
||||
private EndDateInfo? endDateInfo;
|
||||
private RoomNameLine? roomName;
|
||||
private DelayedLoadWrapper wrapper = null!;
|
||||
@@ -88,7 +89,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colours)
|
||||
private void load(OverlayColourProvider colourProvider, OsuColour colours)
|
||||
{
|
||||
ButtonsContainer = new Container
|
||||
{
|
||||
@@ -104,7 +105,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.Background5,
|
||||
Colour = colourProvider.Background5,
|
||||
},
|
||||
CreateBackground().With(d =>
|
||||
{
|
||||
@@ -128,7 +129,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colours.Background5,
|
||||
Colour = colourProvider.Background5,
|
||||
Width = 0.2f,
|
||||
},
|
||||
new Box
|
||||
@@ -136,7 +137,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(colours.Background5, colours.Background5.Opacity(0.3f)),
|
||||
Colour = ColourInfo.GradientHorizontal(colourProvider.Background5, colourProvider.Background5.Opacity(0.3f)),
|
||||
Width = 0.8f,
|
||||
},
|
||||
new GridContainer
|
||||
@@ -254,7 +255,28 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
}
|
||||
}
|
||||
},
|
||||
passwordIcon = new PasswordProtectedIcon { Alpha = 0 }
|
||||
passwordIcon = new CornerIcon
|
||||
{
|
||||
Alpha = 0,
|
||||
Background = { Colour = colours.Gray8, },
|
||||
Icon =
|
||||
{
|
||||
Icon = FontAwesome.Solid.Lock,
|
||||
Colour = colours.Gray3,
|
||||
Rotation = 45,
|
||||
},
|
||||
},
|
||||
pinnedIcon = new CornerIcon
|
||||
{
|
||||
Alpha = 0,
|
||||
Background = { Colour = colours.Orange2 },
|
||||
Icon =
|
||||
{
|
||||
Icon = FontAwesome.Solid.Thumbtack,
|
||||
Colour = colours.Gray3,
|
||||
Rotation = 45,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}, 0)
|
||||
@@ -283,6 +305,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
updateRoomCategory();
|
||||
updateRoomType();
|
||||
updateRoomHasPassword();
|
||||
updateRoomPinned();
|
||||
};
|
||||
|
||||
SelectedItem.BindValueChanged(onSelectedItemChanged, true);
|
||||
@@ -311,6 +334,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
case nameof(Room.HasPassword):
|
||||
updateRoomHasPassword();
|
||||
break;
|
||||
|
||||
case nameof(Room.Pinned):
|
||||
updateRoomPinned();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,6 +398,12 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
passwordIcon.Alpha = Room.HasPassword ? 1 : 0;
|
||||
}
|
||||
|
||||
private void updateRoomPinned()
|
||||
{
|
||||
if (pinnedIcon != null)
|
||||
pinnedIcon.Alpha = Room.Pinned ? 1 : 0;
|
||||
}
|
||||
|
||||
private int numberOfAvatars = 7;
|
||||
|
||||
public int NumberOfAvatars
|
||||
@@ -534,10 +567,12 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
}
|
||||
}
|
||||
|
||||
public partial class PasswordProtectedIcon : CompositeDrawable
|
||||
public partial class CornerIcon : CompositeDrawable
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
public SpriteIcon Icon { get; }
|
||||
public Box Background { get; }
|
||||
|
||||
public CornerIcon()
|
||||
{
|
||||
Anchor = Anchor.TopRight;
|
||||
Origin = Anchor.TopRight;
|
||||
@@ -546,20 +581,19 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
Background = new Box
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = colours.Gray5,
|
||||
Rotation = 45,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 2,
|
||||
},
|
||||
new SpriteIcon
|
||||
Icon = new SpriteIcon
|
||||
{
|
||||
Icon = FontAwesome.Solid.Lock,
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Origin = Anchor.Centre,
|
||||
Position = new Vector2(-13, 13),
|
||||
Margin = new MarginPadding(6),
|
||||
Size = new Vector2(14),
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace osu.Game.Tests.Visual.OnlinePlay
|
||||
/// </remarks>
|
||||
protected virtual OnlinePlayTestSceneDependencies CreateOnlinePlayDependencies() => new OnlinePlayTestSceneDependencies();
|
||||
|
||||
protected Room[] GenerateRooms(int count, RulesetInfo? ruleset = null, bool withPassword = false, bool withSpotlightRooms = false)
|
||||
protected Room[] GenerateRooms(int count, RulesetInfo? ruleset = null, bool withPassword = false, bool withPinnedRooms = false)
|
||||
{
|
||||
Room[] rooms = new Room[count];
|
||||
|
||||
@@ -110,10 +110,10 @@ namespace osu.Game.Tests.Visual.OnlinePlay
|
||||
Name = $@"Room {currentRoomId}",
|
||||
Host = new APIUser { Username = @"Host" },
|
||||
Duration = TimeSpan.FromSeconds(10),
|
||||
Category = withSpotlightRooms && i % 2 == 0 ? RoomCategory.Spotlight : RoomCategory.Normal,
|
||||
Password = withPassword ? @"password" : null,
|
||||
PlaylistItemStats = new Room.RoomPlaylistItemStats { RulesetIDs = [ruleset.OnlineID] },
|
||||
Playlist = [new PlaylistItem(new BeatmapInfo { Metadata = new BeatmapMetadata() }) { RulesetID = ruleset.OnlineID }]
|
||||
Playlist = [new PlaylistItem(new BeatmapInfo { Metadata = new BeatmapMetadata() }) { RulesetID = ruleset.OnlineID }],
|
||||
Pinned = withPinnedRooms && i % 2 == 0,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user