diff --git a/Content.Client/Replay/ContentReplayPlaybackManager.cs b/Content.Client/Replay/ContentReplayPlaybackManager.cs index f90731bfa7..b96eae44e9 100644 --- a/Content.Client/Replay/ContentReplayPlaybackManager.cs +++ b/Content.Client/Replay/ContentReplayPlaybackManager.cs @@ -1,10 +1,8 @@ -using System.IO.Compression; using Content.Client.Administration.Managers; using Content.Client.Launcher; using Content.Client.MainMenu; using Content.Client.Replay.Spectator; using Content.Client.Replay.UI.Loading; -using Content.Client.Stylesheets; using Content.Client.UserInterface.Systems.Chat; using Content.Shared.Chat; using Content.Shared.Effects; @@ -26,8 +24,6 @@ using Robust.Client.Replays.Playback; using Robust.Client.State; using Robust.Client.Timing; using Robust.Client.UserInterface; -using Robust.Client.UserInterface.Controls; -using Robust.Client.UserInterface.CustomControls; using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.ContentPack; @@ -60,7 +56,7 @@ public sealed class ContentReplayPlaybackManager public bool IsScreenshotMode = false; private bool _initialized; - + /// /// Most recently loaded file, for re-attempting the load with error tolerance. /// Required because the zip reader auto-disposes and I'm too lazy to change it so that @@ -96,32 +92,17 @@ public sealed class ContentReplayPlaybackManager return; } - ReturnToDefaultState(); + if (_client.RunLevel == ClientRunLevel.SinglePlayerGame) + _client.StopSinglePlayer(); - // Show a popup window with the error message - var text = Loc.GetString("replay-loading-failed", ("reason", exception)); - var box = new BoxContainer + Action? retryAction = null; + Action? cancelAction = null; + + if (!_cfg.GetCVar(CVars.ReplayIgnoreErrors) && LastLoad is { } last) { - Orientation = BoxContainer.LayoutOrientation.Vertical, - Children = {new Label {Text = text}} - }; - - var popup = new DefaultWindow { Title = "Error!" }; - popup.Contents.AddChild(box); - - // Add button for attempting to re-load the replay while ignoring some errors. - if (!_cfg.GetCVar(CVars.ReplayIgnoreErrors) && LastLoad is {} last) - { - var button = new Button - { - Text = Loc.GetString("replay-loading-retry"), - StyleClasses = { StyleBase.ButtonCaution } - }; - - button.OnPressed += _ => + retryAction = () => { _cfg.SetCVar(CVars.ReplayIgnoreErrors, true); - popup.Dispose(); IReplayFileReader reader = last.Zip == null ? new ReplayFileReaderResources(_resMan, last.Folder) @@ -129,11 +110,20 @@ public sealed class ContentReplayPlaybackManager _loadMan.LoadAndStartReplay(reader); }; - - box.AddChild(button); } - popup.OpenCentered(); + // If we have an explicit menu to get back to (e.g. replay browser UI), show a cancel button. + if (DefaultState != null) + { + cancelAction = () => + { + _stateMan.RequestStateChange(DefaultState); + }; + } + + // Switch to a new game state to present the error and cancel/retry options. + var state = _stateMan.RequestStateChange(); + state.SetData(exception, cancelAction, retryAction); } public void ReturnToDefaultState() diff --git a/Content.Client/Replay/UI/Loading/ReplayLoadingFailed.cs b/Content.Client/Replay/UI/Loading/ReplayLoadingFailed.cs new file mode 100644 index 0000000000..223895eb29 --- /dev/null +++ b/Content.Client/Replay/UI/Loading/ReplayLoadingFailed.cs @@ -0,0 +1,36 @@ +using Content.Client.Stylesheets; +using Robust.Client.State; +using Robust.Client.UserInterface; +using Robust.Shared.Utility; + +namespace Content.Client.Replay.UI.Loading; + +/// +/// State used to display an error message if a replay failed to load. +/// +/// +/// +public sealed class ReplayLoadingFailed : State +{ + [Dependency] private readonly IStylesheetManager _stylesheetManager = default!; + [Dependency] private readonly IUserInterfaceManager _userInterface = default!; + + private ReplayLoadingFailedControl? _control; + + public void SetData(Exception exception, Action? cancelPressed, Action? retryPressed) + { + DebugTools.Assert(_control != null); + _control.SetData(exception, cancelPressed, retryPressed); + } + + protected override void Startup() + { + _control = new ReplayLoadingFailedControl(_stylesheetManager); + _userInterface.StateRoot.AddChild(_control); + } + + protected override void Shutdown() + { + _control?.Orphan(); + } +} diff --git a/Content.Client/Replay/UI/Loading/ReplayLoadingFailedControl.xaml b/Content.Client/Replay/UI/Loading/ReplayLoadingFailedControl.xaml new file mode 100644 index 0000000000..5f77a66e53 --- /dev/null +++ b/Content.Client/Replay/UI/Loading/ReplayLoadingFailedControl.xaml @@ -0,0 +1,14 @@ + + + + + + + + +