From 3b5d573db1365dd07b335a2f8be5da60e7b9f67a Mon Sep 17 00:00:00 2001 From: Joseph Madamba <madamba.joehu@outlook.com> Date: Tue, 31 Jan 2023 15:02:59 -0800 Subject: [PATCH] Display tournament banner on user profile --- .../Online/TestSceneUserProfileOverlay.cs | 6 ++ .../Online/API/Requests/Responses/APIUser.cs | 4 ++ .../Profile/Header/BannerHeaderContainer.cs | 63 +++++++++++++++++++ .../Components/DrawableTournamentBanner.cs | 46 ++++++++++++++ osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++ osu.Game/Users/TournamentBanner.cs | 23 +++++++ 6 files changed, 146 insertions(+) create mode 100644 osu.Game/Overlays/Profile/Header/BannerHeaderContainer.cs create mode 100644 osu.Game/Overlays/Profile/Header/Components/DrawableTournamentBanner.cs create mode 100644 osu.Game/Users/TournamentBanner.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 91928c1fd2..a97c8aff66 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -121,6 +121,12 @@ namespace osu.Game.Tests.Visual.Online Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() }, }, + TournamentBanner = new TournamentBanner + { + Id = 13926, + TournamentId = 35, + ImageLowRes = "https://assets.ppy.sh/tournament-banners/official/owc2022/profile/winner_US.jpg", + }, Badges = new[] { new Badge diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs index 0e62b03f1a..e63395fe26 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUser.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs @@ -234,6 +234,10 @@ namespace osu.Game.Online.API.Requests.Responses set => Statistics.RankHistory = value; } + [JsonProperty(@"active_tournament_banner")] + [CanBeNull] + public TournamentBanner TournamentBanner; + [JsonProperty("badges")] public Badge[] Badges; diff --git a/osu.Game/Overlays/Profile/Header/BannerHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BannerHeaderContainer.cs new file mode 100644 index 0000000000..8e6648dc4b --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/BannerHeaderContainer.cs @@ -0,0 +1,63 @@ +// 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.Threading; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Profile.Header.Components; + +namespace osu.Game.Overlays.Profile.Header +{ + public partial class BannerHeaderContainer : CompositeDrawable + { + public readonly Bindable<UserProfileData?> User = new Bindable<UserProfileData?>(); + + [BackgroundDependencyLoader] + private void load() + { + Alpha = 0; + RelativeSizeAxes = Axes.Both; + FillMode = FillMode.Fit; + FillAspectRatio = 1000 / 60f; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + User.BindValueChanged(u => updateDisplay(u.NewValue?.User), true); + } + + private CancellationTokenSource? cancellationTokenSource; + + private void updateDisplay(APIUser? user) + { + cancellationTokenSource?.Cancel(); + cancellationTokenSource = new CancellationTokenSource(); + + ClearInternal(); + + var banner = user?.TournamentBanner; + + if (banner != null) + { + Show(); + + LoadComponentAsync(new DrawableTournamentBanner(banner), AddInternal, cancellationTokenSource.Token); + } + else + { + Hide(); + } + } + + protected override void Dispose(bool isDisposing) + { + cancellationTokenSource?.Cancel(); + base.Dispose(isDisposing); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/Components/DrawableTournamentBanner.cs b/osu.Game/Overlays/Profile/Header/Components/DrawableTournamentBanner.cs new file mode 100644 index 0000000000..26d333ff95 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/DrawableTournamentBanner.cs @@ -0,0 +1,46 @@ +// 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 osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.Localisation; +using osu.Game.Graphics.Containers; +using osu.Game.Online.API; +using osu.Game.Users; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + [LongRunningLoad] + public partial class DrawableTournamentBanner : OsuClickableContainer + { + private readonly TournamentBanner banner; + + public DrawableTournamentBanner(TournamentBanner banner) + { + this.banner = banner; + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(LargeTextureStore textures, OsuGame? game, IAPIProvider api) + { + Child = new Sprite + { + RelativeSizeAxes = Axes.Both, + Texture = textures.Get(banner.Image), + }; + + Action = () => game?.OpenUrlExternally($@"{api.WebsiteRootUrl}/community/tournaments/{banner.TournamentId}"); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + this.FadeInFromZero(200); + } + + public override LocalisableString TooltipText => "view in browser"; + } +} diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 5d753dea7d..363eb5d58e 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -47,6 +47,10 @@ namespace osu.Game.Overlays.Profile RelativeSizeAxes = Axes.X, User = { BindTarget = User }, }, + new BannerHeaderContainer + { + User = { BindTarget = User }, + }, new BadgeHeaderContainer { RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Users/TournamentBanner.cs b/osu.Game/Users/TournamentBanner.cs new file mode 100644 index 0000000000..62e1913412 --- /dev/null +++ b/osu.Game/Users/TournamentBanner.cs @@ -0,0 +1,23 @@ +// 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.IO; +using Newtonsoft.Json; + +namespace osu.Game.Users +{ + public class TournamentBanner + { + [JsonProperty("id")] + public int Id; + + [JsonProperty("tournament_id")] + public int TournamentId; + + [JsonProperty("image")] + public string ImageLowRes = null!; + + // TODO: remove when api returns @2x image link: https://github.com/ppy/osu-web/issues/9816 + public string Image => $@"{Path.ChangeExtension(ImageLowRes, null)}@2x{Path.GetExtension(ImageLowRes)}"; + } +}