diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 80071db37f..593618ab51 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -68,6 +68,7 @@ namespace osu.Game.Overlays { toastTray = new NotificationOverlayToastTray { + ForwardNotificationToPermanentStore = addPermanently, Origin = Anchor.TopRight, }, mainContent = new Container @@ -157,27 +158,26 @@ namespace osu.Game.Overlays if (notification is IHasCompletionTarget hasCompletionTarget) hasCompletionTarget.CompletionTarget = Post; - var ourType = notification.GetType(); - - int depth = notification.DisplayOnTop ? -runningDepth : runningDepth; - playDebouncedSample(notification.PopInSampleName); if (State.Value == Visibility.Hidden) - toastTray.Post(notification, addPermanently); + toastTray.Post(notification); else - addPermanently(); - - void addPermanently() - { - var section = sections.Children.First(s => s.AcceptedNotificationTypes.Any(accept => accept.IsAssignableFrom(ourType))); - - section.Add(notification, depth); - - updateCounts(); - } + addPermanently(notification); }); + private void addPermanently(Notification notification) + { + var ourType = notification.GetType(); + int depth = notification.DisplayOnTop ? -runningDepth : runningDepth; + + var section = sections.Children.First(s => s.AcceptedNotificationTypes.Any(accept => accept.IsAssignableFrom(ourType))); + + section.Add(notification, depth); + + updateCounts(); + } + protected override void Update() { base.Update(); diff --git a/osu.Game/Overlays/NotificationOverlayToastTray.cs b/osu.Game/Overlays/NotificationOverlayToastTray.cs index 38f790e88e..7017365dbd 100644 --- a/osu.Game/Overlays/NotificationOverlayToastTray.cs +++ b/osu.Game/Overlays/NotificationOverlayToastTray.cs @@ -2,7 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; -using osu.Framework.Threading; using osu.Framework.Utils; using osu.Game.Overlays.Notifications; using osuTK; @@ -25,13 +24,13 @@ namespace osu.Game.Overlays { public bool IsDisplayingToasts => toastFlow.Count > 0; - private FillFlowContainer toastFlow = null!; + private FillFlowContainer toastFlow = null!; private BufferedContainer toastContentBackground = null!; [Resolved] private OverlayColourProvider colourProvider { get; set; } = null!; - private readonly List pendingToastOperations = new List(); + public Action? ForwardNotificationToPermanentStore { get; set; } private int runningDepth; @@ -63,7 +62,7 @@ namespace osu.Game.Overlays postEffectDrawable.AutoSizeAxes = Axes.None; postEffectDrawable.RelativeSizeAxes = Axes.X; })), - toastFlow = new FillFlowContainer + toastFlow = new FillFlowContainer { LayoutDuration = 150, LayoutEasing = Easing.OutQuart, @@ -76,13 +75,13 @@ namespace osu.Game.Overlays public void FlushAllToasts() { - foreach (var d in pendingToastOperations.Where(d => !d.Completed)) - d.RunTask(); - - pendingToastOperations.Clear(); + foreach (var notification in toastFlow.ToArray()) + { + forwardNotification(notification); + } } - public void Post(Notification notification, Action addPermanently) + public void Post(Notification notification) { ++runningDepth; @@ -90,34 +89,47 @@ namespace osu.Game.Overlays toastFlow.Insert(depth, notification); - pendingToastOperations.Add(scheduleDismissal()); + scheduleDismissal(); - ScheduledDelegate scheduleDismissal() => Scheduler.AddDelayed(() => + void scheduleDismissal() => Scheduler.AddDelayed(() => { - // add notification to permanent overlay unless it was already dismissed by the user. + // Notification dismissed by user. if (notification.WasClosed) return; + // Notification forwarded away. + if (notification.Parent != toastFlow) + return; + + // Notification hovered; delay dismissal. if (notification.IsHovered) { - pendingToastOperations.Add(scheduleDismissal()); + scheduleDismissal(); return; } - toastFlow.Remove(notification); - AddInternal(notification); - - notification.MoveToOffset(new Vector2(400, 0), NotificationOverlay.TRANSITION_LENGTH, Easing.OutQuint); - notification.FadeOut(NotificationOverlay.TRANSITION_LENGTH, Easing.OutQuint).OnComplete(_ => - { - RemoveInternal(notification); - addPermanently(); - - notification.FadeIn(300, Easing.OutQuint); - }); + // All looks good, forward away! + forwardNotification(notification); }, notification.IsImportant ? 12000 : 2500); } + private void forwardNotification(Notification notification) + { + Debug.Assert(notification.Parent == toastFlow); + + toastFlow.Remove(notification); + AddInternal(notification); + + notification.MoveToOffset(new Vector2(400, 0), NotificationOverlay.TRANSITION_LENGTH, Easing.OutQuint); + notification.FadeOut(NotificationOverlay.TRANSITION_LENGTH, Easing.OutQuint).OnComplete(_ => + { + RemoveInternal(notification); + ForwardNotificationToPermanentStore?.Invoke(notification); + + notification.FadeIn(300, Easing.OutQuint); + }); + } + protected override void Update() { base.Update();