1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-19 10:52:55 +08:00
osu-lazer/osu.Game/Overlays/MedalOverlay.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

156 lines
5.0 KiB
C#
Raw Normal View History

2024-02-20 19:53:46 +08:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
2024-02-20 19:53:46 +08:00
using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Framework.Logging;
2024-02-20 19:53:46 +08:00
using osu.Game.Graphics.Containers;
using osu.Game.Input.Bindings;
using osu.Game.Online.API;
using osu.Game.Online.Notifications.WebSocket;
using osu.Game.Online.Notifications.WebSocket.Events;
using osu.Game.Users;
namespace osu.Game.Overlays
{
public partial class MedalOverlay : OsuFocusedOverlayContainer
{
protected override string? PopInSampleName => null;
protected override string? PopOutSampleName => null;
public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks;
2024-02-20 19:53:46 +08:00
protected override void PopIn() => this.FadeIn();
protected override void PopOut() => this.FadeOut();
2024-02-20 19:53:46 +08:00
private readonly Queue<MedalAnimation> queuedMedals = new Queue<MedalAnimation>();
2024-02-20 19:53:46 +08:00
[Resolved]
private IAPIProvider api { get; set; } = null!;
private Container<Drawable> medalContainer = null!;
private MedalAnimation? currentMedalDisplay;
2024-02-20 19:53:46 +08:00
[BackgroundDependencyLoader]
private void load()
{
RelativeSizeAxes = Axes.Both;
api.NotificationsClient.MessageReceived += handleMedalMessages;
Add(medalContainer = new Container
{
RelativeSizeAxes = Axes.Both
});
}
protected override void LoadComplete()
{
base.LoadComplete();
OverlayActivationMode.BindValueChanged(_ => showNextMedal(), true);
}
2024-11-26 13:42:30 +08:00
public override void Hide()
{
// don't allow hiding the overlay via any method other than our own.
}
2024-02-20 19:53:46 +08:00
private void handleMedalMessages(SocketMessage obj)
{
if (obj.Event != @"new")
return;
var data = obj.Data?.ToObject<NewPrivateNotificationEvent>();
if (data == null || data.Name != @"user_achievement_unlock")
return;
var details = data.Details?.ToObject<UserAchievementUnlock>();
if (details == null)
return;
var medal = new Medal
{
Name = details.Title,
InternalName = details.Slug,
Description = details.Description,
};
var medalAnimation = new MedalAnimation(medal);
Logger.Log($"Queueing medal unlock for \"{medal.Name}\" ({queuedMedals.Count} to display)");
Schedule(() => LoadComponentAsync(medalAnimation, m =>
{
queuedMedals.Enqueue(m);
showNextMedal();
}));
}
protected override bool OnClick(ClickEvent e)
{
2024-11-26 13:42:30 +08:00
progressDisplayByUser();
return true;
}
public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
{
if (e.Action == GlobalAction.Back)
{
2024-11-26 13:42:30 +08:00
progressDisplayByUser();
return true;
}
return base.OnPressed(e);
2024-02-20 19:53:46 +08:00
}
2024-11-26 13:42:30 +08:00
private void progressDisplayByUser()
2024-02-20 19:53:46 +08:00
{
2024-11-26 13:45:40 +08:00
// Dismissing may sometimes play out the medal animation rather than immediately dismissing.
if (currentMedalDisplay?.Dismiss() == false)
return;
currentMedalDisplay = null;
2024-11-26 13:42:30 +08:00
showNextMedal();
}
2024-02-20 19:53:46 +08:00
private void showNextMedal()
{
// If already displayed, keep displaying medals regardless of activation mode changes.
if (OverlayActivationMode.Value != OverlayActivation.All && State.Value == Visibility.Hidden)
return;
// A medal is already displaying.
if (currentMedalDisplay != null)
return;
2024-11-26 13:42:30 +08:00
if (queuedMedals.TryDequeue(out currentMedalDisplay))
{
Logger.Log($"Displaying \"{currentMedalDisplay.Medal.Name}\"");
medalContainer.Add(currentMedalDisplay);
2024-11-26 13:42:30 +08:00
Show();
2024-02-20 19:53:46 +08:00
}
else if (State.Value == Visibility.Visible)
{
Logger.Log("All queued medals have been displayed, hiding overlay!");
base.Hide();
}
2024-02-20 19:53:46 +08:00
}
protected override void Dispose(bool isDisposing)
{
2024-11-28 17:24:56 +08:00
// this event subscription fires async loads, which hard-fail if `CompositeDrawable.disposalCancellationSource` is canceled, which happens in the base call.
// therefore, unsubscribe from this event early to reduce the chances of a stray event firing at an inconvenient spot.
2024-02-20 19:53:46 +08:00
if (api.IsNotNull())
api.NotificationsClient.MessageReceived -= handleMedalMessages;
2024-11-28 17:24:56 +08:00
base.Dispose(isDisposing);
2024-02-20 19:53:46 +08:00
}
}
}