From e81695bcacdde50284133c01db2fd33ecafabac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Sch=C3=BCrz?= Date: Mon, 2 Oct 2023 23:10:51 +0200 Subject: [PATCH] Display avatar in invitation notification --- .../TestSceneNotificationOverlay.cs | 17 ++++ .../Online/Multiplayer/MultiplayerClient.cs | 7 +- osu.Game/Overlays/NotificationOverlay.cs | 2 +- .../Notifications/UserAvatarNotification.cs | 78 +++++++++++++++++++ 4 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 osu.Game/Overlays/Notifications/UserAvatarNotification.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs index 4d3ae079e3..07bd722322 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs @@ -4,13 +4,17 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Testing; using osu.Framework.Utils; +using osu.Game.Database; using osu.Game.Graphics.Sprites; +using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; @@ -31,6 +35,8 @@ public partial class TestSceneNotificationOverlay : OsuManualInputManagerTestSce public double TimeToCompleteProgress { get; set; } = 2000; + private readonly UserLookupCache userLookupCache = new TestUserLookupCache(); + [SetUp] public void SetUp() => Schedule(() => { @@ -60,6 +66,7 @@ public void TestBasicFlow() AddStep(@"simple #2", sendAmazingNotification); AddStep(@"progress #1", sendUploadProgress); AddStep(@"progress #2", sendDownloadProgress); + AddStep(@"User notification", sendUserNotification); checkProgressingCount(2); @@ -537,6 +544,16 @@ private void sendDownloadProgress() progressingNotifications.Add(n); } + private async void sendUserNotification() + { + var user = await userLookupCache.GetUserAsync(0).ConfigureAwait(true); + if (user == null) return; + + var n = new UserAvatarNotification(user, $"{user.Username} is telling you to NOT download Haitai!"); + + notificationOverlay.Post(n); + } + private void sendUploadProgress() { var n = new ProgressNotification diff --git a/osu.Game/Online/Multiplayer/MultiplayerClient.cs b/osu.Game/Online/Multiplayer/MultiplayerClient.cs index e438f9f96d..bb953bae58 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerClient.cs @@ -450,10 +450,9 @@ async Task IMultiplayerClient.Invited(int invitedBy, MultiplayerRoom room) Scheduler.Add(() => { - PostNotification?.Invoke(new SimpleNotification - { - Text = "You got invited into a multiplayer match by " + user.Username + "!", - }); + PostNotification?.Invoke( + new UserAvatarNotification(user, $"{user.Username} invited you to a multiplayer match!") + ); }); } diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 6e0ea23dd1..67cf868fb0 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -113,7 +113,7 @@ private void load() RelativeSizeAxes = Axes.X, Children = new[] { - new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }), + new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification), typeof(UserAvatarNotification) }), new NotificationSection(NotificationsStrings.RunningTasks, new[] { typeof(ProgressNotification) }), } } diff --git a/osu.Game/Overlays/Notifications/UserAvatarNotification.cs b/osu.Game/Overlays/Notifications/UserAvatarNotification.cs new file mode 100644 index 0000000000..191d63a76f --- /dev/null +++ b/osu.Game/Overlays/Notifications/UserAvatarNotification.cs @@ -0,0 +1,78 @@ +// 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.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Users.Drawables; + +namespace osu.Game.Overlays.Notifications +{ + public partial class UserAvatarNotification : Notification + { + private LocalisableString text; + + public override LocalisableString Text + { + get => text; + set + { + text = value; + if (textDrawable != null) + textDrawable.Text = text; + } + } + + private TextFlowContainer? textDrawable; + + private APIUser user; + + public UserAvatarNotification(APIUser user, LocalisableString text) + { + this.user = user; + Text = text; + } + + private DrawableAvatar? avatar; + + protected override IconUsage CloseButtonIcon => FontAwesome.Solid.Times; + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + IconContent.Masking = true; + + // Workaround for the corner radius on parent's mask breaking if we add masking to IconContent + IconContent.CornerRadius = 6; + + IconContent.AddRange(new Drawable[] + { + new Box() + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background5, + }, + }); + + avatar = new DrawableAvatar(user) + { + FillMode = FillMode.Fill, + }; + LoadComponentAsync(avatar, IconContent.Add); + + Content.Add(textDrawable = new OsuTextFlowContainer(t => t.Font = t.Font.With(size: 14, weight: FontWeight.Medium)) + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Text = text + }); + } + } +}