1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-24 18:20:12 +08:00

Merge pull request #33858 from frenzibyte/multiplayer-match-link

Add external link button to multiplayer/playlists room panels
This commit is contained in:
Dan Balasescu
2025-06-26 23:16:05 +09:00
committed by GitHub
Unverified
4 changed files with 163 additions and 13 deletions
@@ -165,23 +165,75 @@ namespace osu.Game.Tests.Visual.Multiplayer
Name = "A host-only room",
QueueMode = QueueMode.HostOnly,
Type = MatchType.HeadToHead,
RoomID = 1337,
}),
new MultiplayerRoomPanel(new Room
{
Name = "An all-players, team-versus room",
QueueMode = QueueMode.AllPlayers,
Type = MatchType.TeamVersus
Type = MatchType.TeamVersus,
RoomID = 1338,
}),
new MultiplayerRoomPanel(new Room
{
Name = "A round-robin room",
QueueMode = QueueMode.AllPlayersRoundRobin,
Type = MatchType.HeadToHead
Type = MatchType.HeadToHead,
RoomID = 1339,
}),
}
});
}
[Test]
public void TestRoomWithLongTitle()
{
AddStep("create rooms", () => Child = new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Spacing = new Vector2(5),
Children = new[]
{
new MultiplayerRoomPanel(new Room
{
Name = "This room has a very very long title enough to make the external link button reach the participants list on the right side unless the test window is very wide, at which point I don't know, hi.",
QueueMode = QueueMode.HostOnly,
Type = MatchType.HeadToHead,
RoomID = 1337,
}),
}
});
}
[Test]
public void TestRoomWithUpdatedRoomID()
{
Room room = null!;
AddStep("create rooms", () => Child = new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Spacing = new Vector2(5),
Children = new[]
{
new MultiplayerRoomPanel(room = new Room
{
Name = "This room has a very very long title enough to make the external link button reach the participants list on the right side unless the test window is very wide, at which point I don't know, hi.",
QueueMode = QueueMode.HostOnly,
Type = MatchType.HeadToHead,
}),
}
});
AddWaitStep("wait", 3);
AddStep("set room ID", () => room.RoomID = 1337);
AddWaitStep("wait", 3);
AddStep("clear room ID", () => room.RoomID = null);
}
private RoomPanel createLoungeRoom(Room room)
{
room.Host ??= new APIUser { Username = "peppy", Id = 2 };
+21
View File
@@ -0,0 +1,21 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Online.API;
namespace osu.Game.Online.Rooms
{
public static class RoomExtensions
{
/// <summary>
/// Get the room page URL, or <c>null</c> if unavailable.
/// </summary>
public static string? GetOnlineURL(this Room room, IAPIProvider api)
{
if (!room.RoomID.HasValue)
return null;
return $@"{api.Endpoints.WebsiteUrl}/multiplayer/rooms/{room.RoomID.Value}";
}
}
}
@@ -17,6 +17,7 @@ using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Database;
@@ -54,11 +55,13 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
protected readonly Bindable<PlaylistItem?> SelectedItem = new Bindable<PlaylistItem?>();
protected Container ButtonsContainer { get; private set; } = null!;
protected bool ShowExternalLink { get; init; } = true;
private DrawableRoomParticipantsList? drawableRoomParticipantsList;
private RoomSpecialCategoryPill? specialCategoryPill;
private PasswordProtectedIcon? passwordIcon;
private EndDateInfo? endDateInfo;
private SpriteText? roomName;
private RoomNameLine? roomName;
private DelayedLoadWrapper wrapper = null!;
private CancellationTokenSource? beatmapLookupCancellation;
@@ -204,11 +207,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
roomName = new TruncatingSpriteText
{
RelativeSizeAxes = Axes.X,
Font = OsuFont.GetFont(size: 28)
},
roomName = new RoomNameLine(),
new RoomStatusText(Room)
{
Beatmap = { BindTarget = currentBeatmap }
@@ -279,6 +278,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
wrapper.FadeInFromZero(200);
updateRoomID();
updateRoomName();
updateRoomCategory();
updateRoomType();
@@ -292,6 +292,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
{
switch (e.PropertyName)
{
case nameof(Room.RoomID):
updateRoomID();
break;
case nameof(Room.Name):
updateRoomName();
break;
@@ -335,6 +339,12 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
}), cancellationSource.Token);
}
private void updateRoomID()
{
if (roomName != null && ShowExternalLink)
roomName.Link = Room.GetOnlineURL(api);
}
private void updateRoomName()
{
if (roomName != null)
@@ -381,17 +391,17 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
{
var items = new List<MenuItem>();
if (Room.RoomID.HasValue)
string? url = Room.GetOnlineURL(api);
if (url != null)
{
items.AddRange([
new OsuMenuItem("View in browser", MenuItemType.Standard, () => game?.OpenUrlExternally(formatRoomUrl(Room.RoomID.Value))),
new OsuMenuItem("Copy link", MenuItemType.Standard, () => game?.CopyToClipboard(formatRoomUrl(Room.RoomID.Value)))
new OsuMenuItem("View in browser", MenuItemType.Standard, () => game?.OpenUrlExternally(url)),
new OsuMenuItem("Copy link", MenuItemType.Standard, () => game?.CopyToClipboard(url))
]);
}
return items.ToArray();
string formatRoomUrl(long id) => $@"{api.Endpoints.WebsiteUrl}/multiplayer/rooms/{id}";
}
}
@@ -556,5 +566,71 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
};
}
}
public partial class RoomNameLine : FillFlowContainer
{
private TruncatingSpriteText spriteText = null!;
private ExternalLinkButton linkButton = null!;
public LocalisableString Text
{
get => spriteText.Text;
set => spriteText.Text = value;
}
private string? link;
public string? Link
{
get => link;
set
{
link = value;
updateLink();
}
}
[BackgroundDependencyLoader]
private void load()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Direction = FillDirection.Horizontal;
Children = new Drawable[]
{
spriteText = new TruncatingSpriteText
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Font = OsuFont.GetFont(size: 28),
},
linkButton = new ExternalLinkButton
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Margin = new MarginPadding { Horizontal = 6, Bottom = 4 },
Alpha = 0f,
},
};
}
private void updateLink()
{
if (link == null)
linkButton.Hide();
else
{
linkButton.Show();
linkButton.Link = link;
}
}
protected override void Update()
{
base.Update();
spriteText.MaxWidth = DrawWidth - linkButton.LayoutSize.X;
}
}
}
}
@@ -67,6 +67,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
public LoungeRoomPanel(Room room)
: base(room)
{
ShowExternalLink = false;
}
[BackgroundDependencyLoader]