1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-23 18:19:53 +08:00

Merge pull request #32390 from peppy/fix-online-user-state

Allow spectator button to work without begin play requests
This commit is contained in:
Dean Herbert
2025-03-16 13:24:37 +09:00
committed by GitHub
Unverified
3 changed files with 27 additions and 58 deletions
@@ -47,11 +47,6 @@ namespace osu.Game.Online.Spectator
/// </summary>
public IBindableList<SpectatorUser> WatchingUsers => watchingUsers;
/// <summary>
/// A global list of all players currently playing.
/// </summary>
public IBindableList<int> PlayingUsers => playingUsers;
/// <summary>
/// Whether the local user is playing.
/// </summary>
@@ -91,7 +86,6 @@ namespace osu.Game.Online.Spectator
private readonly BindableDictionary<int, SpectatorState> watchedUserStates = new BindableDictionary<int, SpectatorState>();
private readonly BindableList<SpectatorUser> watchingUsers = new BindableList<SpectatorUser>();
private readonly BindableList<int> playingUsers = new BindableList<int>();
private readonly SpectatorState currentState = new SpectatorState();
private IBeatmap? currentBeatmap;
@@ -134,7 +128,6 @@ namespace osu.Game.Online.Spectator
}
else
{
playingUsers.Clear();
watchedUserStates.Clear();
watchingUsers.Clear();
}
@@ -145,9 +138,6 @@ namespace osu.Game.Online.Spectator
{
Schedule(() =>
{
if (!playingUsers.Contains(userId))
playingUsers.Add(userId);
if (watchedUsersRefCounts.ContainsKey(userId))
watchedUserStates[userId] = state;
@@ -161,8 +151,6 @@ namespace osu.Game.Online.Spectator
{
Schedule(() =>
{
playingUsers.Remove(userId);
if (watchedUsersRefCounts.ContainsKey(userId))
watchedUserStates[userId] = state;
@@ -2,9 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
@@ -16,10 +14,8 @@ using osu.Framework.Localisation;
using osu.Framework.Screens;
using osu.Game.Database;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Metadata;
using osu.Game.Online.Spectator;
using osu.Game.Resources.Localisation.Web;
using osu.Game.Screens;
using osu.Game.Screens.OnlinePlay.Match.Components;
@@ -34,19 +30,12 @@ namespace osu.Game.Overlays.Dashboard
private const float search_textbox_height = 40;
private const float padding = 10;
private readonly IBindableList<int> playingUsers = new BindableList<int>();
private readonly IBindableDictionary<int, UserPresence> onlineUserPresences = new BindableDictionary<int, UserPresence>();
private readonly Dictionary<int, OnlineUserPanel> userPanels = new Dictionary<int, OnlineUserPanel>();
private SearchContainer<OnlineUserPanel> userFlow = null!;
private BasicSearchTextBox searchTextBox = null!;
[Resolved]
private IAPIProvider api { get; set; } = null!;
[Resolved]
private SpectatorClient spectatorClient { get; set; } = null!;
[Resolved]
private MetadataClient metadataClient { get; set; } = null!;
@@ -106,9 +95,6 @@ namespace osu.Game.Overlays.Dashboard
onlineUserPresences.BindTo(metadataClient.UserPresences);
onlineUserPresences.BindCollectionChanged(onUserPresenceUpdated, true);
playingUsers.BindTo(spectatorClient.PlayingUsers);
playingUsers.BindCollectionChanged(onPlayingUsersChanged, true);
}
protected override void OnFocus(FocusEvent e)
@@ -152,53 +138,27 @@ namespace osu.Game.Overlays.Dashboard
}
});
private void onPlayingUsersChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
Debug.Assert(e.NewItems != null);
foreach (int userId in e.NewItems)
{
if (userPanels.TryGetValue(userId, out var panel))
panel.CanSpectate.Value = userId != api.LocalUser.Value.Id;
}
break;
case NotifyCollectionChangedAction.Remove:
Debug.Assert(e.OldItems != null);
foreach (int userId in e.OldItems)
{
if (userPanels.TryGetValue(userId, out var panel))
panel.CanSpectate.Value = false;
}
break;
}
}
private OnlineUserPanel createUserPanel(APIUser user) =>
new OnlineUserPanel(user).With(panel =>
{
panel.Anchor = Anchor.TopCentre;
panel.Origin = Anchor.TopCentre;
panel.CanSpectate.Value = playingUsers.Contains(user.Id);
});
public partial class OnlineUserPanel : CompositeDrawable, IFilterable
{
public readonly APIUser User;
public BindableBool CanSpectate { get; } = new BindableBool();
private PurpleRoundedButton spectateButton = null!;
public IEnumerable<LocalisableString> FilterTerms { get; }
[Resolved]
private IPerformFromScreenRunner? performer { get; set; }
[Resolved]
private MetadataClient? metadataClient { get; set; }
public bool FilteringActive { set; get; }
public bool MatchingFilter
@@ -221,6 +181,27 @@ namespace osu.Game.Overlays.Dashboard
AutoSizeAxes = Axes.Both;
}
protected override void Update()
{
base.Update();
// TODO: we probably don't want to do this every frame.
var activity = metadataClient?.GetPresence(User.Id)?.Activity;
switch (activity)
{
default:
spectateButton.Enabled.Value = false;
break;
case UserActivity.InSoloGame:
case UserActivity.InMultiplayerGame:
case UserActivity.InPlaylistGame:
spectateButton.Enabled.Value = true;
break;
}
}
[BackgroundDependencyLoader]
private void load()
{
@@ -240,14 +221,13 @@ namespace osu.Game.Overlays.Dashboard
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre
},
new PurpleRoundedButton
spectateButton = new PurpleRoundedButton
{
RelativeSizeAxes = Axes.X,
Text = "Spectate",
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Action = () => performer?.PerformFromScreen(s => s.Push(new SoloSpectatorScreen(User))),
Enabled = { BindTarget = CanSpectate }
}
}
},
+1
View File
@@ -90,6 +90,7 @@ namespace osu.Game.Users
private void updatePresence()
{
// TODO: we probably don't want to do this every frame.
UserPresence? presence = metadata?.GetPresence(User.OnlineID);
UserStatus status = presence?.Status ?? UserStatus.Offline;
UserActivity? activity = presence?.Activity;