diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneFirstRunGame.cs b/osu.Game.Tests/Visual/Navigation/TestSceneFirstRunGame.cs new file mode 100644 index 0000000000..18c6e84950 --- /dev/null +++ b/osu.Game.Tests/Visual/Navigation/TestSceneFirstRunGame.cs @@ -0,0 +1,56 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Graphics.Containers; +using osu.Framework.Platform; +using osu.Game.Configuration; +using osu.Game.Online.API; +using osu.Game.Overlays.Notifications; + +namespace osu.Game.Tests.Visual.Navigation +{ + [System.ComponentModel.Description("game with first-run setup overlay")] + public class TestSceneFirstRunGame : OsuGameTestScene + { + public override void SetUpSteps() + { + base.SetUpSteps(); + + AddUntilStep("Wait for first-run setup", () => Game.FirstRunOverlay.State.Value == Visibility.Visible); + } + + [Test] + public void TestImportantNotificationDoesntInterruptSetup() + { + AddStep("post important notification", () => Game.Notifications.Post(new SimpleNotification { Text = "Important notification" })); + AddAssert("no notification posted", () => Game.Notifications.UnreadCount.Value == 0); + AddAssert("first-run setup still visible", () => Game.FirstRunOverlay.State.Value == Visibility.Visible); + + AddUntilStep("finish first-run setup", () => + { + Game.FirstRunOverlay.NextButton.TriggerClick(); + return Game.FirstRunOverlay.State.Value == Visibility.Hidden; + }); + AddWaitStep("wait for post delay", 5); + AddAssert("notifications shown", () => Game.Notifications.State.Value == Visibility.Visible); + AddAssert("notification posted", () => Game.Notifications.UnreadCount.Value == 1); + } + + protected override TestOsuGame CreateTestGame() => new FirstRunGame(LocalStorage, API); + + private class FirstRunGame : TestOsuGame + { + public FirstRunGame(Storage storage, IAPIProvider api, string[] args = null) + : base(storage, api, args) + { + } + + protected override void LoadComplete() + { + base.LoadComplete(); + LocalConfig.SetValue(OsuSetting.ShowFirstRunSetup, true); + } + } + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 1f9a1ce938..200f7613a1 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -153,7 +153,7 @@ namespace osu.Game protected SettingsOverlay Settings; - private FirstRunSetupOverlay firstRunOverlay; + protected FirstRunSetupOverlay FirstRunOverlay { get; private set; } private VolumeOverlay volume; @@ -845,7 +845,7 @@ namespace osu.Game loadComponentSingleFile(CreateUpdateManager(), Add, true); // overlay elements - loadComponentSingleFile(firstRunOverlay = new FirstRunSetupOverlay(), overlayContent.Add, true); + loadComponentSingleFile(FirstRunOverlay = new FirstRunSetupOverlay(), overlayContent.Add, true); loadComponentSingleFile(new ManageCollectionsDialog(), overlayContent.Add, true); loadComponentSingleFile(beatmapListing = new BeatmapListingOverlay(), overlayContent.Add, true); loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true); @@ -896,7 +896,7 @@ namespace osu.Game Add(new MusicKeyBindingHandler()); // side overlays which cancel each other. - var singleDisplaySideOverlays = new OverlayContainer[] { Settings, Notifications, firstRunOverlay }; + var singleDisplaySideOverlays = new OverlayContainer[] { Settings, Notifications, FirstRunOverlay }; foreach (var overlay in singleDisplaySideOverlays) { @@ -921,7 +921,7 @@ namespace osu.Game } // ensure only one of these overlays are open at once. - var singleDisplayOverlays = new OverlayContainer[] { firstRunOverlay, chatOverlay, news, dashboard, beatmapListing, changelogOverlay, rankingsOverlay, wikiOverlay }; + var singleDisplayOverlays = new OverlayContainer[] { FirstRunOverlay, chatOverlay, news, dashboard, beatmapListing, changelogOverlay, rankingsOverlay, wikiOverlay }; foreach (var overlay in singleDisplayOverlays) { diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index f1ed5c4ba6..d83839fa2c 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -1,20 +1,22 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +#nullable enable + using System.Linq; -using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Overlays.Notifications; -using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics.Containers; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Bindables; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Framework.Logging; using osu.Framework.Threading; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Overlays.Notifications; using osu.Game.Resources.Localisation.Web; using NotificationsStrings = osu.Game.Localisation.NotificationsStrings; @@ -30,13 +32,15 @@ namespace osu.Game.Overlays public const float TRANSITION_LENGTH = 600; - private FlowContainer sections; + private FlowContainer sections = null!; [Resolved] - private AudioManager audio { get; set; } + private AudioManager audio { get; set; } = null!; + + private readonly IBindable firstRunSetupVisibility = new Bindable(); [BackgroundDependencyLoader] - private void load() + private void load(FirstRunSetupOverlay? firstRunSetup) { X = WIDTH; Width = WIDTH; @@ -75,13 +79,16 @@ namespace osu.Game.Overlays } } }; + + if (firstRunSetup != null) + firstRunSetupVisibility.BindTo(firstRunSetup.State); } - private ScheduledDelegate notificationsEnabler; + private ScheduledDelegate? notificationsEnabler; private void updateProcessingMode() { - bool enabled = OverlayActivationMode.Value == OverlayActivation.All || State.Value == Visibility.Visible; + bool enabled = (OverlayActivationMode.Value == OverlayActivation.All && firstRunSetupVisibility.Value != Visibility.Visible) || State.Value == Visibility.Visible; notificationsEnabler?.Cancel(); @@ -96,7 +103,8 @@ namespace osu.Game.Overlays { base.LoadComplete(); - State.ValueChanged += _ => updateProcessingMode(); + State.BindValueChanged(_ => updateProcessingMode()); + firstRunSetupVisibility.BindValueChanged(_ => updateProcessingMode()); OverlayActivationMode.BindValueChanged(_ => updateProcessingMode(), true); } diff --git a/osu.Game/Tests/Visual/OsuGameTestScene.cs b/osu.Game/Tests/Visual/OsuGameTestScene.cs index 6e4adb4d4c..5995b30b60 100644 --- a/osu.Game/Tests/Visual/OsuGameTestScene.cs +++ b/osu.Game/Tests/Visual/OsuGameTestScene.cs @@ -132,6 +132,8 @@ namespace osu.Game.Tests.Visual public new NotificationOverlay Notifications => base.Notifications; + public new FirstRunSetupOverlay FirstRunOverlay => base.FirstRunOverlay; + public new MusicController MusicController => base.MusicController; public new OsuConfigManager LocalConfig => base.LocalConfig;