diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index c5f075986a85..1a6c23414b9d 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -291,6 +291,16 @@ public void PostCommand(string text, Channel target = null) AddInternal(new NowPlayingCommand(target)); break; + case @"watch": + if (string.IsNullOrWhiteSpace(content)) + { + target.AddNewMessages(new ErrorMessage("Usage: /watch [user]")); + break; + } + + AddInternal(new WatchCommand(target, content)); + break; + case @"me": if (string.IsNullOrWhiteSpace(content)) { @@ -411,7 +421,7 @@ public void PostCommand(string text, Channel target = null) break; case @"help": - target.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action], /join [channel], /chat [user], /np, /savelog, /roll [2-100] (multiplayer only)")); + target.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action], /join [channel], /chat [user], /np, /watch [user], /savelog, /roll [2-100] (multiplayer only)")); break; default: diff --git a/osu.Game/Online/Chat/WatchCommand.cs b/osu.Game/Online/Chat/WatchCommand.cs new file mode 100644 index 000000000000..0b16cc21782c --- /dev/null +++ b/osu.Game/Online/Chat/WatchCommand.cs @@ -0,0 +1,53 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Screens; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Screens; +using osu.Game.Screens.Play; + +namespace osu.Game.Online.Chat +{ + public partial class WatchCommand : Component + { + [Resolved] + private IAPIProvider api { get; set; } = null!; + + [Resolved] + private IPerformFromScreenRunner performer { get; set; } = null!; + + private readonly Channel? target; + private readonly string username; + + public WatchCommand(Channel target, string username) + { + this.target = target; + this.username = username; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + var request = new GetUserRequest(username); + request.Success += user => + { + performer.PerformFromScreen(s => s.Push(new SoloSpectatorScreen(user))); + Expire(); + }; + request.Failure += e => + { + target?.AddNewMessages(new ErrorMessage( + e.InnerException?.Message == @"NotFound" + ? $"User '{username}' was not found." + : $"Could not fetch user '{username}'.")); + Expire(); + }; + + api.Queue(request); + } + } +}