-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove Status
and Activity
bindables from APIUser
#31513
Conversation
As for the tests, I'm (ab)using the `IsOnline` state for the time being to restore functionality.
Status = | ||
{ | ||
Value = UserStatus.Online | ||
}, | ||
IsOnline = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in 20108e3, this is a hack that I expect to go away soon because obviously this has no way to convey user activity & dnd state.
SetDefault<UserStatus?>(OsuSetting.UserOnlineStatus, null); | ||
SetDefault(OsuSetting.UserOnlineStatus, UserStatus.Online); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this will throw a non-fatal runtime error if you have the previous null
default value in the config:
UserOnlineStatus =
However, the value is set to Online
as soon as the user logs in, and never set back to the default value after that.
This is not easy to handle because we don't have a good way to change values from nullable to non-nullable right now (if ever?), so I left it as is and hope this is okay. Adding a migration doesn't help because those are processed after all these defaults are applied.
osu.Game/Online/API/APIAccess.cs
Outdated
@@ -608,7 +591,7 @@ public void Logout() | |||
password = null; | |||
SecondFactorCode = null; | |||
authentication.Clear(); | |||
configStatus.Value = UserStatus.Online; | |||
Status.Value = UserStatus.Online; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dunno about this...
The point of the configStatus
/ localUserStatus
separation was to better control what was getting written to the config. See #26337 and #29186. While this may be functionally equivalent, I find the face-value reading of this of "when the user logs out, their status is set to... online" rather brain-breaky... (Although you could say this was weird to begin with and the value should have been set to null
instead here. Guess I didn't think about that in #29186.)
I think I'd prefer the bindable split to still exist, and for the config status to still be nullable. The absolute bare minimum here for me is an explanatory comment though because at face value this just looks completely bugged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to better control what was getting written to the config
Can you give an example of a scenario where this is important? The way I see it:
- We want the status to be read from config when logged in.
- We want the status to be written to the config when it changes.
So I'm asking for case (3) where the values should deviate. Is it maybe easier to think of this in the context of the other comment, where I allude to this basically being the config value just exposed in an intuitive place?
As far as I can tell, #29186 is going in the same path as I have here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'm asking for case (3) where the values should deviate
Well again I don't think I have any such scenario wherein it functionally matters, but I guess in an idealistic sense, when the user logs out, I'd prefer the "config user status" to be null
over Online
, because there's no user in sight.
The lack of functional difference is why I'm not gonna push for any material changes in code here, but I believe at least an inline comment is warranted, because it's a line of code that looks very odd without knowing the context of this also backing a config bindable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer the "config user status" to be
null
overOnline
I disagree because the config value is really "what does the user want to appear as" instead of "what is the user's current status". I would maybe even go so far as to say the state shouldn't be reset on logout - that is, if the user "wants to appear as" offline, then when they log in again they should still appear as offline.
Would adjusting the xmldoc to the status to be broadcast for the current user
help things?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would maybe even go so far as to say the state shouldn't be reset on logout - that is, if the user "want to appear as" offline, then when they log in again they should still appear as offline
That reset behaviour was intended for cases where multiple users play on a single machine. Whether that is a niche enough use case to not warrant it, I don't know, but it was accepted at review time.
Would adjusting the xmldoc to
the status to be broadcast for the current user
help things?
Not really, because that's not the part I have issue with - it's the "this gets written to config" part in the logout flow that is obscured / non-obvious with these changes to me specifically. Broadcasting for current user doesn't really have anything to do with config storage in my head.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just had a look at this PR, and I think I prefer the solution offered in 52d1842. If APIAccess
can avoid exposing this config setting at all, then that works the best. I don't see an issue with DiscordRichPresence
and OnlineMetadataClient
reading from the config rather than api.State
.
In addition, if Status
is still exposed via IAPIProvider
, it should be an IBindable
. Every write usage should request it from the configuration directly. I've tested and this should work fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've re-applied the change with a few other fixes, exposing it as IBindable
now.
To be perfectly clear, the only solution I'm fine with is the original presented solution - exposing it as a Bindable
directly. I have many reasons for this, which I cannot convey so I'm not going to try anymore.
However, do be aware of one particular footgun. Because there are now two controllers exposing the same thing - one as read-only and one as "write-only", if you ever want to test components that utilise BOTH forms then you will need to both:
- Create your own
OsuConfigManager
(or use the testscene's global one - up to you I guess), and set the config value directly, AND... - Propagate any values you've set also to
DummyAPIAccess.Status
(Bindable<>
) directly.
I do not have a solution for linking the two - given that DummyAPIAccess
is global for the entire test scene, code like:
new DependencyProvidingContainer
{
CachedDependencies =
[
(typeof(OsuConfigManager), new OsuConfigManager(LocalStorage))
]
}
... that intends to isolate the config manager per-test, will not work if I simply resolve an OsuConfigManager
into DummyAPIAccess
like APIAccess
does. For now I've exposed it from DummyAPIAccess
in some usable way just so that if a case comes up then we immediately have something to work with, even if it is hacky imo. I use this in the subsequent PR here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering: can we just remove Status
from IAPIProvider
completely?
diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs
index 6c7e7d393f..cedc34dc56 100644
--- a/osu.Desktop/DiscordRichPresence.cs
+++ b/osu.Desktop/DiscordRichPresence.cs
@@ -54,7 +54,7 @@ internal partial class DiscordRichPresence : Component
[Resolved]
private OsuConfigManager config { get; set; } = null!;
- private readonly IBindable<UserStatus> status = new Bindable<UserStatus>();
+ private readonly Bindable<UserStatus> status = new Bindable<UserStatus>();
private readonly IBindable<UserActivity?> activity = new Bindable<UserActivity?>();
private readonly Bindable<DiscordRichPresenceMode> privacyMode = new Bindable<DiscordRichPresenceMode>();
@@ -106,9 +106,9 @@ protected override void LoadComplete()
base.LoadComplete();
config.BindWith(OsuSetting.DiscordRichPresence, privacyMode);
+ config.BindWith(OsuSetting.UserOnlineStatus, status);
user = api.LocalUser.GetBoundCopy();
- status.BindTo(api.Status);
activity.BindTo(api.Activity);
ruleset.BindValueChanged(_ => schedulePresenceUpdate());
diff --git a/osu.Game/Online/API/DummyAPIAccess.cs b/osu.Game/Online/API/DummyAPIAccess.cs
index 3fef2b59cf..b338f4e8cb 100644
--- a/osu.Game/Online/API/DummyAPIAccess.cs
+++ b/osu.Game/Online/API/DummyAPIAccess.cs
@@ -197,7 +197,6 @@ public void UpdateLocalFriends()
IBindable<APIUser> IAPIProvider.LocalUser => LocalUser;
IBindableList<APIRelation> IAPIProvider.Friends => Friends;
- IBindable<UserStatus> IAPIProvider.Status => Status;
IBindable<UserActivity?> IAPIProvider.Activity => Activity;
/// <summary>
diff --git a/osu.Game/Online/API/IAPIProvider.cs b/osu.Game/Online/API/IAPIProvider.cs
index 9ac7343885..4b87db4ecc 100644
--- a/osu.Game/Online/API/IAPIProvider.cs
+++ b/osu.Game/Online/API/IAPIProvider.cs
@@ -24,11 +24,6 @@ public interface IAPIProvider
/// </summary>
IBindableList<APIRelation> Friends { get; }
- /// <summary>
- /// The status for the current user that's broadcast to other players.
- /// </summary>
- IBindable<UserStatus> Status { get; }
-
/// <summary>
/// The activity for the current user that's broadcast to other players.
/// </summary>
diff --git a/osu.Game/Online/Metadata/OnlineMetadataClient.cs b/osu.Game/Online/Metadata/OnlineMetadataClient.cs
index 101307636a..26367c9c5c 100644
--- a/osu.Game/Online/Metadata/OnlineMetadataClient.cs
+++ b/osu.Game/Online/Metadata/OnlineMetadataClient.cs
@@ -73,9 +73,9 @@ private void load(IAPIProvider api, OsuConfigManager config)
}
lastQueueId = config.GetBindable<int>(OsuSetting.LastProcessedMetadataId);
+ userStatus = config.GetBindable<UserStatus>(OsuSetting.UserOnlineStatus);
localUser = api.LocalUser.GetBoundCopy();
- userStatus = api.Status.GetBoundCopy();
userActivity = api.Activity.GetBoundCopy()!;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
52d1842 originally did remove the status from IAPIProvider
completely, for whatever it's worth.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I've done this now, along with the suggestion from #31524
UserStatus
moved toOsuConfigManager
.UserActivity
moved toSessionStatics
, as I proposed above.
52d1842
to
7ca3a6f
Compare
osu.Game/Online/API/APIAccess.cs
Outdated
@@ -608,7 +591,7 @@ public void Logout() | |||
password = null; | |||
SecondFactorCode = null; | |||
authentication.Clear(); | |||
configStatus.Value = UserStatus.Online; | |||
Status.Value = UserStatus.Online; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just had a look at this PR, and I think I prefer the solution offered in 52d1842. If APIAccess
can avoid exposing this config setting at all, then that works the best. I don't see an issue with DiscordRichPresence
and OnlineMetadataClient
reading from the config rather than api.State
.
In addition, if Status
is still exposed via IAPIProvider
, it should be an IBindable
. Every write usage should request it from the configuration directly. I've tested and this should work fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good apart from a small concern.
if (hadLocalUserState) | ||
userStates[api.LocalUser.Value.OnlineID] = presence; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned IRL, let's keep the local user state as a separate field to simplify this.
@smoogipoo can you check 311f08b is in line with expectations? |
Seems okay. |
Prereqs:
First step towards a resolution for #13604.