diff --git a/osu.Game/Online/Metadata/MetadataClient.cs b/osu.Game/Online/Metadata/MetadataClient.cs index 6578f70f74..507f43467c 100644 --- a/osu.Game/Online/Metadata/MetadataClient.cs +++ b/osu.Game/Online/Metadata/MetadataClient.cs @@ -37,6 +37,11 @@ namespace osu.Game.Online.Metadata /// public abstract IBindable IsWatchingUserPresence { get; } + /// + /// The information about the current user. + /// + public abstract UserPresence LocalUserState { get; } + /// /// Dictionary keyed by user ID containing all of the information about currently online users received from the server. /// diff --git a/osu.Game/Online/Metadata/OnlineMetadataClient.cs b/osu.Game/Online/Metadata/OnlineMetadataClient.cs index 01d7a564fa..04abca1e9b 100644 --- a/osu.Game/Online/Metadata/OnlineMetadataClient.cs +++ b/osu.Game/Online/Metadata/OnlineMetadataClient.cs @@ -23,6 +23,9 @@ namespace osu.Game.Online.Metadata public override IBindable IsWatchingUserPresence => isWatchingUserPresence; private readonly BindableBool isWatchingUserPresence = new BindableBool(); + public override UserPresence LocalUserState => localUserState; + private UserPresence localUserState; + public override IBindableDictionary UserStates => userStates; private readonly BindableDictionary userStates = new BindableDictionary(); @@ -110,6 +113,7 @@ namespace osu.Game.Online.Metadata userStates.Clear(); friendStates.Clear(); dailyChallengeInfo.Value = null; + localUserState = default; }); return; } @@ -202,9 +206,19 @@ namespace osu.Game.Online.Metadata Schedule(() => { if (presence?.Status != null) - userStates[userId] = presence.Value; + { + if (userId == api.LocalUser.Value.OnlineID) + localUserState = presence.Value; + else + userStates[userId] = presence.Value; + } else - userStates.Remove(userId); + { + if (userId == api.LocalUser.Value.OnlineID) + localUserState = default; + else + userStates.Remove(userId); + } }); return Task.CompletedTask; @@ -242,14 +256,7 @@ namespace osu.Game.Online.Metadata throw new OperationCanceledException(); // must be scheduled before any remote calls to avoid mis-ordering. - Schedule(() => - { - bool hadLocalUserState = userStates.TryGetValue(api.LocalUser.Value.OnlineID, out var presence); - userStates.Clear(); - if (hadLocalUserState) - userStates[api.LocalUser.Value.OnlineID] = presence; - }); - + Schedule(() => userStates.Clear()); Debug.Assert(connection != null); await connection.InvokeAsync(nameof(IMetadataServer.EndWatchingUserPresence)).ConfigureAwait(false); Logger.Log($@"{nameof(OnlineMetadataClient)} stopped watching user presence", LoggingTarget.Network); diff --git a/osu.Game/Tests/Visual/Metadata/TestMetadataClient.cs b/osu.Game/Tests/Visual/Metadata/TestMetadataClient.cs index 36f79a5adc..d32d49b55e 100644 --- a/osu.Game/Tests/Visual/Metadata/TestMetadataClient.cs +++ b/osu.Game/Tests/Visual/Metadata/TestMetadataClient.cs @@ -19,6 +19,9 @@ namespace osu.Game.Tests.Visual.Metadata public override IBindable IsWatchingUserPresence => isWatchingUserPresence; private readonly BindableBool isWatchingUserPresence = new BindableBool(); + public override UserPresence LocalUserState => localUserState; + private UserPresence localUserState; + public override IBindableDictionary UserStates => userStates; private readonly BindableDictionary userStates = new BindableDictionary(); @@ -71,10 +74,20 @@ namespace osu.Game.Tests.Visual.Metadata { if (isWatchingUserPresence.Value) { - if (presence.HasValue) - userStates[userId] = presence.Value; + if (presence?.Status != null) + { + if (userId == api.LocalUser.Value.OnlineID) + localUserState = presence.Value; + else + userStates[userId] = presence.Value; + } else - userStates.Remove(userId); + { + if (userId == api.LocalUser.Value.OnlineID) + localUserState = default; + else + userStates.Remove(userId); + } } return Task.CompletedTask;