From f7ec135b9b0a1bf357a3b508fea8b746a52a8c97 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Oct 2021 14:39:21 +0900 Subject: [PATCH 01/18] Fix `TestSceneLoungeRoomsContainer` crashing on selecting a room with a password --- .../Multiplayer/TestSceneLoungeRoomsContainer.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index 99b530c2a2..1bdf3c2750 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -5,6 +5,7 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Testing; using osu.Game.Online.Rooms; using osu.Game.Rulesets.Catch; @@ -25,12 +26,18 @@ namespace osu.Game.Tests.Visual.Multiplayer [SetUp] public new void Setup() => Schedule(() => { - Child = container = new RoomsContainer + Child = new PopoverContainer { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Anchor = Anchor.Centre, Origin = Anchor.Centre, Width = 0.5f, - SelectedRoom = { BindTarget = SelectedRoom } + + Child = container = new RoomsContainer + { + SelectedRoom = { BindTarget = SelectedRoom } + } }; }); From d35fe5493a6638f14795ef033f09dbef7afd1234 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Oct 2021 14:50:19 +0900 Subject: [PATCH 02/18] Change default value of `DrawableLoungeRoom.matchingFilter` so they display by default --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index fe7c7cc364..e787191d5d 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -103,7 +103,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge public IEnumerable FilterTerms => new[] { Room.Name.Value }; - private bool matchingFilter; + private bool matchingFilter = true; public bool MatchingFilter { From 473459d1910b1a164b2784f74531b7beb09d264f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Oct 2021 15:04:14 +0900 Subject: [PATCH 03/18] Add layout duration to `PasswordEntryPopover` to make error text look a bit smoother --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index e787191d5d..79515bf352 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -200,6 +200,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge Spacing = new Vector2(5), AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, + LayoutDuration = 500, + LayoutEasing = Easing.OutQuint, Children = new Drawable[] { new FillFlowContainer From 8944b1dd78cd5daa4b48eb706ae7f1ca2cadd0e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Oct 2021 15:04:32 +0900 Subject: [PATCH 04/18] Add basic test coverage of `DrawableLoungeRoom` --- .../TestSceneDrawableLoungeRoom.cs | 72 +++++++++++++++++++ .../OnlinePlay/Lounge/LoungeSubScreen.cs | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs new file mode 100644 index 0000000000..91c65d14a7 --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs @@ -0,0 +1,72 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Threading; +using System.Threading.Tasks; +using Moq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Testing; +using osu.Game.Online.Rooms; +using osu.Game.Overlays; +using osu.Game.Screens.OnlinePlay.Lounge; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneDrawableLoungeRoom : OsuTestScene + { + private readonly Room room = new Room + { + HasPassword = { Value = true } + }; + + [Cached] + protected readonly OverlayColourProvider ColourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); + + [BackgroundDependencyLoader] + private void load() + { + var mockLounge = new Mock(); + mockLounge + .Setup(l => l.Join(It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny>())) + .Callback, Action>((a, b, c, d) => + { + Task.Run(() => + { + Thread.Sleep(500); + Schedule(() => d?.Invoke("Incorrect password")); + }); + }); + + Dependencies.CacheAs(mockLounge.Object); + } + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("create drawable", () => + { + Child = new PopoverContainer + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new DrawableLoungeRoom(room) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + } + }; + }); + } + + [Test] + public void TestFocus() + { + } + } +} diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 08bdd0487a..f9183ec74a 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -290,7 +290,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge popoverContainer.HidePopover(); } - public void Join(Room room, string password, Action onSuccess = null, Action onFailure = null) => Schedule(() => + public virtual void Join(Room room, string password, Action onSuccess = null, Action onFailure = null) => Schedule(() => { if (joiningRoomOperation != null) return; From 32cbf6e54be7f8cdccc0b78eec7a4f3a175e1b61 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Oct 2021 15:20:30 +0900 Subject: [PATCH 05/18] Add test coverage ensuring password popover keeps focus --- .../TestSceneDrawableLoungeRoom.cs | 103 +++++++++++++++++- 1 file changed, 99 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs index 91c65d14a7..6d969b6a83 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Moq; @@ -10,13 +11,15 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Cursor; using osu.Framework.Testing; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.Rooms; using osu.Game.Overlays; using osu.Game.Screens.OnlinePlay.Lounge; +using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneDrawableLoungeRoom : OsuTestScene + public class TestSceneDrawableLoungeRoom : OsuManualInputManagerTestScene { private readonly Room room = new Room { @@ -26,6 +29,11 @@ namespace osu.Game.Tests.Visual.Multiplayer [Cached] protected readonly OverlayColourProvider ColourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); + private DrawableLoungeRoom drawableRoom; + private SearchTextBox searchTextBox; + + private readonly ManualResetEventSlim allowResponseCallback = new ManualResetEventSlim(); + [BackgroundDependencyLoader] private void load() { @@ -36,7 +44,8 @@ namespace osu.Game.Tests.Visual.Multiplayer { Task.Run(() => { - Thread.Sleep(500); + allowResponseCallback.Wait(); + allowResponseCallback.Reset(); Schedule(() => d?.Invoke("Incorrect password")); }); }); @@ -54,7 +63,16 @@ namespace osu.Game.Tests.Visual.Multiplayer RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - new DrawableLoungeRoom(room) + searchTextBox = new SearchTextBox() + { + HoldFocus = true, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Margin = new MarginPadding(50), + Width = 500, + Depth = float.MaxValue + }, + drawableRoom = new DrawableLoungeRoom(room) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -65,8 +83,85 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] - public void TestFocus() + public void TestFocusViaKeyboardCommit() { + DrawableLoungeRoom.PasswordEntryPopover popover = null; + + AddAssert("search textbox has focus", () => checkFocus(searchTextBox)); + AddStep("click room twice", () => + { + InputManager.MoveMouseTo(drawableRoom); + InputManager.Click(MouseButton.Left); + InputManager.Click(MouseButton.Left); + }); + AddUntilStep("wait for popover", () => (popover = InputManager.ChildrenOfType().SingleOrDefault()) != null); + + AddAssert("textbox has focus", () => checkFocus(popover.ChildrenOfType().Single())); + + AddStep("enter password", () => popover.ChildrenOfType().Single().Text = "password"); + AddStep("commit via enter", () => InputManager.Key(Key.Enter)); + + AddAssert("popover has focus", () => checkFocus(popover)); + + AddStep("attempt another enter", () => InputManager.Key(Key.Enter)); + + AddAssert("popover still has focus", () => checkFocus(popover)); + + AddStep("unblock response", () => allowResponseCallback.Set()); + + AddUntilStep("wait for textbox refocus", () => checkFocus(popover.ChildrenOfType().Single())); + + AddStep("press escape", () => InputManager.Key(Key.Escape)); + AddStep("press escape", () => InputManager.Key(Key.Escape)); + + AddUntilStep("search textbox has focus", () => checkFocus(searchTextBox)); } + + [Test] + public void TestFocusViaMouseCommit() + { + DrawableLoungeRoom.PasswordEntryPopover popover = null; + + AddAssert("search textbox has focus", () => checkFocus(searchTextBox)); + AddStep("click room twice", () => + { + InputManager.MoveMouseTo(drawableRoom); + InputManager.Click(MouseButton.Left); + InputManager.Click(MouseButton.Left); + }); + AddUntilStep("wait for popover", () => (popover = InputManager.ChildrenOfType().SingleOrDefault()) != null); + + AddAssert("textbox has focus", () => checkFocus(popover.ChildrenOfType().Single())); + + AddStep("enter password", () => popover.ChildrenOfType().Single().Text = "password"); + + AddStep("commit via click button", () => + { + var button = popover.ChildrenOfType().Single(); + InputManager.MoveMouseTo(button); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("popover has focus", () => checkFocus(popover)); + + AddStep("attempt another click", () => InputManager.Click(MouseButton.Left)); + + AddAssert("popover still has focus", () => checkFocus(popover)); + + AddStep("unblock response", () => allowResponseCallback.Set()); + + AddUntilStep("wait for textbox refocus", () => checkFocus(popover.ChildrenOfType().Single())); + + AddStep("click away", () => + { + InputManager.MoveMouseTo(searchTextBox); + InputManager.Click(MouseButton.Left); + }); + + AddUntilStep("search textbox has focus", () => checkFocus(searchTextBox)); + } + + private bool checkFocus(Drawable expected) => + InputManager.FocusedDrawable == expected; } } From a589964dc7f50743536b020efe5006900d7f396d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Oct 2021 15:27:51 +0900 Subject: [PATCH 06/18] Centralise join logic --- .../OnlinePlay/Lounge/DrawableLoungeRoom.cs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 79515bf352..64bd61b960 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -232,7 +232,21 @@ namespace osu.Game.Screens.OnlinePlay.Lounge sampleJoinFail = audio.Samples.Get(@"UI/password-fail"); - joinButton.Action = () => lounge?.Join(room, passwordTextbox.Text, null, joinFailed); + joinButton.Action = performJoin; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox)); + passwordTextbox.OnCommit += (_, __) => performJoin(); + } + + private void performJoin() + { + lounge?.Join(room, passwordTextbox.Text, null, joinFailed); + GetContainingInputManager().TriggerFocusContention(passwordTextbox); } private void joinFailed(string error) @@ -252,14 +266,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge sampleJoinFail?.Play(); } - - protected override void LoadComplete() - { - base.LoadComplete(); - - Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox)); - passwordTextbox.OnCommit += (_, __) => lounge?.Join(room, passwordTextbox.Text, null, joinFailed); - } } } } From da524261c076ca844d1f28e611de97d7ffd16c03 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Oct 2021 15:36:15 +0900 Subject: [PATCH 07/18] Fix focus potentially being transferred too far up when password is being verified --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 64bd61b960..2a68b1d9b3 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -181,6 +181,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge [Resolved(canBeNull: true)] private LoungeSubScreen lounge { get; set; } + public override bool HandleNonPositionalInput => true; + + protected override bool BlockNonPositionalInput => true; + public PasswordEntryPopover(Room room) { this.room = room; From 480dc571025924d4b4bf5fadb776d8654eb3abbc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Oct 2021 15:54:10 +0900 Subject: [PATCH 08/18] Schedule `joinFailed` callback for added safety --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 2a68b1d9b3..72574b729a 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -253,7 +253,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge GetContainingInputManager().TriggerFocusContention(passwordTextbox); } - private void joinFailed(string error) + private void joinFailed(string error) => Schedule(() => { passwordTextbox.Text = string.Empty; @@ -269,7 +269,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge Body.Shake(); sampleJoinFail?.Play(); - } + }); } } } From fd01a226db28023a06b578d37b1f3bdd7962b23a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 20 Oct 2021 18:11:33 +0900 Subject: [PATCH 09/18] Remove redundant parenthesis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- .../Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs index 6d969b6a83..ea895a23d2 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual.Multiplayer RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - searchTextBox = new SearchTextBox() + searchTextBox = new SearchTextBox { HoldFocus = true, Anchor = Anchor.TopCentre, From 6dd54a417fbb12ee0ae1fa376e1abdeca39e8103 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 21 Oct 2021 21:32:07 +0900 Subject: [PATCH 10/18] Remove `BeatmapMetadata` base class from `APIBeatmapSet` --- .../API/Requests/Responses/APIBeatmapSet.cs | 62 +++++++++++++++++-- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 47f880cf54..24d0e09649 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -8,12 +8,13 @@ using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Rulesets; +using osu.Game.Users; #nullable enable namespace osu.Game.Online.API.Requests.Responses { - public class APIBeatmapSet : BeatmapMetadata, IBeatmapSetOnlineInfo, IBeatmapSetInfo + public class APIBeatmapSet : IBeatmapSetOnlineInfo, IBeatmapSetInfo { [JsonProperty(@"covers")] public BeatmapSetOnlineCovers Covers { get; set; } @@ -63,10 +64,44 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"track_id")] public int? TrackId { get; set; } + public string Title { get; set; } = string.Empty; + + [JsonProperty("title_unicode")] + public string TitleUnicode { get; set; } = string.Empty; + + public string Artist { get; set; } = string.Empty; + + [JsonProperty("artist_unicode")] + public string ArtistUnicode { get; set; } = string.Empty; + + public User? Author = new User(); + + /// + /// Helper property to deserialize a username to . + /// [JsonProperty(@"user_id")] - private int creatorId + public int AuthorID { - set => Author.Id = value; + get => Author?.Id ?? 1; + set + { + Author ??= new User(); + Author.Id = value; + } + } + + /// + /// Helper property to deserialize a username to . + /// + [JsonProperty(@"creator")] + public string AuthorString + { + get => Author?.Username ?? string.Empty; + set + { + Author ??= new User(); + Author.Username = value; + } } [JsonProperty(@"availability")] @@ -78,6 +113,11 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"language")] public BeatmapSetOnlineLanguage Language { get; set; } + public string Source { get; set; } = string.Empty; + + [JsonProperty(@"tags")] + public string Tags { get; set; } = string.Empty; + [JsonProperty(@"beatmaps")] private IEnumerable beatmaps { get; set; } = Array.Empty(); @@ -86,7 +126,7 @@ namespace osu.Game.Online.API.Requests.Responses var beatmapSet = new BeatmapSetInfo { OnlineBeatmapSetID = OnlineID, - Metadata = this, + Metadata = metadata, Status = Status, Metrics = new BeatmapSetMetrics { Ratings = ratings }, OnlineInfo = this @@ -103,11 +143,23 @@ namespace osu.Game.Online.API.Requests.Responses return beatmapSet; } + private BeatmapMetadata metadata => new BeatmapMetadata + { + Title = Title, + TitleUnicode = TitleUnicode, + Artist = Artist, + ArtistUnicode = ArtistUnicode, + AuthorID = AuthorID, + Author = Author, + Source = Source, + Tags = Tags, + }; + #region Implementation of IBeatmapSetInfo IEnumerable IBeatmapSetInfo.Beatmaps => beatmaps; - IBeatmapMetadataInfo IBeatmapSetInfo.Metadata => this; + IBeatmapMetadataInfo IBeatmapSetInfo.Metadata => metadata; DateTimeOffset IBeatmapSetInfo.DateAdded => throw new NotImplementedException(); IEnumerable IBeatmapSetInfo.Files => throw new NotImplementedException(); From fb7cf3548119221d6e9af4e1778f9b2a96f195e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 21 Oct 2021 21:48:14 +0900 Subject: [PATCH 11/18] Remove `BeatmapMetadata` base class from `APIBeatmap` --- osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index 42e519223b..49124a404d 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests.Responses { - public class APIBeatmap : BeatmapMetadata, IBeatmapInfo + public class APIBeatmap : IBeatmapInfo { [JsonProperty(@"id")] public int OnlineID { get; set; } @@ -24,6 +24,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("checksum")] public string Checksum { get; set; } = string.Empty; + [JsonProperty(@"user_id")] + public int AuthorID { get; set; } + [JsonProperty(@"beatmapset")] public APIBeatmapSet? BeatmapSet { get; set; } @@ -75,7 +78,7 @@ namespace osu.Game.Online.API.Requests.Responses return new BeatmapInfo { - Metadata = set?.Metadata ?? this, + Metadata = set?.Metadata ?? new BeatmapMetadata(), Ruleset = rulesets.GetRuleset(RulesetID), StarDifficulty = StarRating, OnlineBeatmapID = OnlineID, @@ -106,7 +109,7 @@ namespace osu.Game.Online.API.Requests.Responses #region Implementation of IBeatmapInfo - public IBeatmapMetadataInfo Metadata => this; + public IBeatmapMetadataInfo Metadata => new BeatmapMetadata(); public IBeatmapDifficultyInfo Difficulty => new BeatmapDifficulty { From de33b2f45a67d3fd6e503c5886375d7086ba838c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Oct 2021 15:00:31 +0900 Subject: [PATCH 12/18] Return set metadata if available before falling back to empty object --- osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index 49124a404d..7335a1c18d 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -109,7 +109,7 @@ namespace osu.Game.Online.API.Requests.Responses #region Implementation of IBeatmapInfo - public IBeatmapMetadataInfo Metadata => new BeatmapMetadata(); + public IBeatmapMetadataInfo Metadata => (BeatmapSet as IBeatmapSetInfo)?.Metadata ?? new BeatmapMetadata(); public IBeatmapDifficultyInfo Difficulty => new BeatmapDifficulty { From ea473428e84f7adf43f1727eb15281df25b01901 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Oct 2021 15:54:40 +0900 Subject: [PATCH 13/18] Fix incorrect length mapping in `APIBeatmap` --- osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index 42e519223b..6ab1630604 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -51,8 +51,10 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"accuracy")] private float overallDifficulty { get; set; } + public double Length => lengthInSeconds * 1000; + [JsonProperty(@"total_length")] - public double Length { get; set; } + private double lengthInSeconds { get; set; } [JsonProperty(@"count_circles")] private int circleCount { get; set; } From 91cc77407d3ee9e2c03b108217fc90bc5aa2ae26 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Oct 2021 17:02:02 +0900 Subject: [PATCH 14/18] Fix low-pass filter continuing to take effect after fail animation has already ended --- osu.Game/Screens/Play/FailAnimation.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 242d997dd7..edfb8186bb 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -106,6 +106,7 @@ namespace osu.Game.Screens.Play this.TransformBindableTo(trackFreq, 0, duration).OnComplete(_ => { + RemoveFilters(); OnComplete?.Invoke(); }); @@ -137,6 +138,9 @@ namespace osu.Game.Screens.Play public void RemoveFilters() { + if (filters.Parent == null) + return; + RemoveInternal(filters); filters.Dispose(); From cc1d759290552e87cd3452f82290c68718aa5141 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Oct 2021 17:48:09 +0900 Subject: [PATCH 15/18] Remove unnecessary setters from `IBeatmapSetOnlineInfo` interface --- osu.Game/Beatmaps/BeatmapSetInfo.cs | 96 ++++------------------ osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs | 34 ++++---- 2 files changed, 33 insertions(+), 97 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index c3e2399d53..79cd8253f7 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -107,27 +107,15 @@ namespace osu.Game.Beatmaps [NotMapped] [JsonIgnore] - public DateTimeOffset Submitted - { - get => OnlineInfo.Submitted; - set => OnlineInfo.Submitted = value; - } + public DateTimeOffset Submitted => OnlineInfo.Submitted; [NotMapped] [JsonIgnore] - public DateTimeOffset? Ranked - { - get => OnlineInfo.Ranked; - set => OnlineInfo.Ranked = value; - } + public DateTimeOffset? Ranked => OnlineInfo.Ranked; [NotMapped] [JsonIgnore] - public DateTimeOffset? LastUpdated - { - get => OnlineInfo.LastUpdated; - set => OnlineInfo.LastUpdated = value; - } + public DateTimeOffset? LastUpdated => OnlineInfo.LastUpdated; [NotMapped] [JsonIgnore] @@ -135,107 +123,55 @@ namespace osu.Game.Beatmaps [NotMapped] [JsonIgnore] - public bool HasExplicitContent - { - get => OnlineInfo.HasExplicitContent; - set => OnlineInfo.HasExplicitContent = value; - } + public bool HasExplicitContent => OnlineInfo.HasExplicitContent; [NotMapped] [JsonIgnore] - public bool HasVideo - { - get => OnlineInfo.HasVideo; - set => OnlineInfo.HasVideo = value; - } + public bool HasVideo => OnlineInfo.HasVideo; [NotMapped] [JsonIgnore] - public bool HasStoryboard - { - get => OnlineInfo.HasStoryboard; - set => OnlineInfo.HasStoryboard = value; - } + public bool HasStoryboard => OnlineInfo.HasStoryboard; [NotMapped] [JsonIgnore] - public BeatmapSetOnlineCovers Covers - { - get => OnlineInfo.Covers; - set => OnlineInfo.Covers = value; - } + public BeatmapSetOnlineCovers Covers => OnlineInfo.Covers; [NotMapped] [JsonIgnore] - public string Preview - { - get => OnlineInfo.Preview; - set => OnlineInfo.Preview = value; - } + public string Preview => OnlineInfo.Preview; [NotMapped] [JsonIgnore] - public double BPM - { - get => OnlineInfo.BPM; - set => OnlineInfo.BPM = value; - } + public double BPM => OnlineInfo.BPM; [NotMapped] [JsonIgnore] - public int PlayCount - { - get => OnlineInfo.PlayCount; - set => OnlineInfo.PlayCount = value; - } + public int PlayCount => OnlineInfo.PlayCount; [NotMapped] [JsonIgnore] - public int FavouriteCount - { - get => OnlineInfo.FavouriteCount; - set => OnlineInfo.FavouriteCount = value; - } + public int FavouriteCount => OnlineInfo.FavouriteCount; [NotMapped] [JsonIgnore] - public bool HasFavourited - { - get => OnlineInfo.HasFavourited; - set => OnlineInfo.HasFavourited = value; - } + public bool HasFavourited => OnlineInfo.HasFavourited; [NotMapped] [JsonIgnore] - public BeatmapSetOnlineAvailability Availability - { - get => OnlineInfo.Availability; - set => OnlineInfo.Availability = value; - } + public BeatmapSetOnlineAvailability Availability => OnlineInfo.Availability; [NotMapped] [JsonIgnore] - public BeatmapSetOnlineGenre Genre - { - get => OnlineInfo.Genre; - set => OnlineInfo.Genre = value; - } + public BeatmapSetOnlineGenre Genre => OnlineInfo.Genre; [NotMapped] [JsonIgnore] - public BeatmapSetOnlineLanguage Language - { - get => OnlineInfo.Language; - set => OnlineInfo.Language = value; - } + public BeatmapSetOnlineLanguage Language => OnlineInfo.Language; [NotMapped] [JsonIgnore] - public int? TrackId - { - get => OnlineInfo.TrackId; - set => OnlineInfo.TrackId = value; - } + public int? TrackId => OnlineInfo?.TrackId; #endregion } diff --git a/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs index b9800bc2e6..1d2bb46bde 100644 --- a/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs @@ -15,87 +15,87 @@ namespace osu.Game.Beatmaps /// /// The date this beatmap set was submitted to the online listing. /// - DateTimeOffset Submitted { get; set; } + DateTimeOffset Submitted { get; } /// /// The date this beatmap set was ranked. /// - DateTimeOffset? Ranked { get; set; } + DateTimeOffset? Ranked { get; } /// /// The date this beatmap set was last updated. /// - DateTimeOffset? LastUpdated { get; set; } + DateTimeOffset? LastUpdated { get; } /// /// The status of this beatmap set. /// - BeatmapSetOnlineStatus Status { get; set; } + BeatmapSetOnlineStatus Status { get; } /// /// Whether or not this beatmap set has explicit content. /// - bool HasExplicitContent { get; set; } + bool HasExplicitContent { get; } /// /// Whether or not this beatmap set has a background video. /// - bool HasVideo { get; set; } + bool HasVideo { get; } /// /// Whether or not this beatmap set has a storyboard. /// - bool HasStoryboard { get; set; } + bool HasStoryboard { get; } /// /// The different sizes of cover art for this beatmap set. /// - BeatmapSetOnlineCovers Covers { get; set; } + BeatmapSetOnlineCovers Covers { get; } /// /// A small sample clip of this beatmap set's song. /// - string Preview { get; set; } + string Preview { get; } /// /// The beats per minute of this beatmap set's song. /// - double BPM { get; set; } + double BPM { get; } /// /// The amount of plays this beatmap set has. /// - int PlayCount { get; set; } + int PlayCount { get; } /// /// The amount of people who have favourited this beatmap set. /// - int FavouriteCount { get; set; } + int FavouriteCount { get; } /// /// Whether this beatmap set has been favourited by the current user. /// - bool HasFavourited { get; set; } + bool HasFavourited { get; } /// /// The availability of this beatmap set. /// - BeatmapSetOnlineAvailability Availability { get; set; } + BeatmapSetOnlineAvailability Availability { get; } /// /// The song genre of this beatmap set. /// - BeatmapSetOnlineGenre Genre { get; set; } + BeatmapSetOnlineGenre Genre { get; } /// /// The song language of this beatmap set. /// - BeatmapSetOnlineLanguage Language { get; set; } + BeatmapSetOnlineLanguage Language { get; } /// /// The track ID of this beatmap set. /// Non-null only if the track is linked to a featured artist track entry. /// - int? TrackId { get; set; } + int? TrackId { get; } } } From 90477e3788fdeccc88e5181ce7f2851cbebca609 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Oct 2021 19:12:37 +0900 Subject: [PATCH 16/18] Remove unused `BeatmapTypeInfo` class Helps reduce the scope of upcoming changes. --- .../OnlinePlay/Components/BeatmapTypeInfo.cs | 72 ------------------- 1 file changed, 72 deletions(-) delete mode 100644 osu.Game/Screens/OnlinePlay/Components/BeatmapTypeInfo.cs diff --git a/osu.Game/Screens/OnlinePlay/Components/BeatmapTypeInfo.cs b/osu.Game/Screens/OnlinePlay/Components/BeatmapTypeInfo.cs deleted file mode 100644 index 3aa13458a4..0000000000 --- a/osu.Game/Screens/OnlinePlay/Components/BeatmapTypeInfo.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Linq; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osuTK; - -namespace osu.Game.Screens.OnlinePlay.Components -{ - public class BeatmapTypeInfo : OnlinePlayComposite - { - private LinkFlowContainer beatmapAuthor; - - public BeatmapTypeInfo() - { - AutoSizeAxes = Axes.Both; - } - - [BackgroundDependencyLoader] - private void load() - { - InternalChild = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - LayoutDuration = 100, - Spacing = new Vector2(5, 0), - Children = new Drawable[] - { - new ModeTypeInfo(), - new Container - { - AutoSizeAxes = Axes.X, - Height = 30, - Margin = new MarginPadding { Left = 5 }, - Children = new Drawable[] - { - new BeatmapTitle(), - beatmapAuthor = new LinkFlowContainer(s => s.Font = s.Font.With(size: 14)) - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - AutoSizeAxes = Axes.Both - }, - }, - }, - } - }; - - Playlist.CollectionChanged += (_, __) => updateInfo(); - - updateInfo(); - } - - private void updateInfo() - { - beatmapAuthor.Clear(); - - var beatmap = Playlist.FirstOrDefault()?.Beatmap; - - if (beatmap != null) - { - beatmapAuthor.AddText("mapped by ", s => s.Colour = OsuColour.Gray(0.8f)); - beatmapAuthor.AddUserLink(beatmap.Value.Metadata.Author); - } - } - } -} From c701579c693f345d6ea3046d79264949c9f2d57a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Oct 2021 21:25:13 +0900 Subject: [PATCH 17/18] Refactor `BeatmapMetadataContainer` and usages to use interface types --- .../Responses/APIUserMostPlayedBeatmap.cs | 22 +++---- .../Sections/BeatmapMetadataContainer.cs | 11 ++-- .../Historical/DrawableMostPlayedBeatmap.cs | 61 ++++++++++++------- .../PaginatedMostPlayedBeatmapContainer.cs | 4 +- .../Sections/Ranks/DrawableProfileScore.cs | 49 +++++++++------ 5 files changed, 86 insertions(+), 61 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs index 10f7ca6fe2..19c581bf95 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs @@ -2,8 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using Newtonsoft.Json; -using osu.Game.Beatmaps; -using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests.Responses { @@ -16,17 +14,19 @@ namespace osu.Game.Online.API.Requests.Responses public int PlayCount { get; set; } [JsonProperty("beatmap")] - private BeatmapInfo beatmapInfo { get; set; } + private APIBeatmap beatmap { get; set; } - [JsonProperty] - private APIBeatmapSet beatmapSet { get; set; } - - public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets) + public APIBeatmap BeatmapInfo { - BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets); - beatmapInfo.BeatmapSet = setInfo; - beatmapInfo.Metadata = setInfo.Metadata; - return beatmapInfo; + get + { + // old osu-web code doesn't nest set. + beatmap.BeatmapSet = BeatmapSet; + return beatmap; + } } + + [JsonProperty("beatmapset")] + public APIBeatmapSet BeatmapSet { get; set; } } } diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs index 7812a81f30..94ef5e5d86 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs @@ -15,9 +15,9 @@ namespace osu.Game.Overlays.Profile.Sections /// public abstract class BeatmapMetadataContainer : OsuHoverContainer { - private readonly BeatmapInfo beatmapInfo; + private readonly IBeatmapInfo beatmapInfo; - protected BeatmapMetadataContainer(BeatmapInfo beatmapInfo) + protected BeatmapMetadataContainer(IBeatmapInfo beatmapInfo) : base(HoverSampleSet.Submit) { this.beatmapInfo = beatmapInfo; @@ -30,10 +30,7 @@ namespace osu.Game.Overlays.Profile.Sections { Action = () => { - if (beatmapInfo.OnlineBeatmapID != null) - beatmapSetOverlay?.FetchAndShowBeatmap(beatmapInfo.OnlineBeatmapID.Value); - else if (beatmapInfo.BeatmapSet?.OnlineBeatmapSetID != null) - beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmapInfo.BeatmapSet.OnlineBeatmapSetID.Value); + beatmapSetOverlay?.FetchAndShowBeatmap(beatmapInfo.OnlineID); }; Child = new FillFlowContainer @@ -43,6 +40,6 @@ namespace osu.Game.Overlays.Profile.Sections }; } - protected abstract Drawable[] CreateText(BeatmapInfo beatmapInfo); + protected abstract Drawable[] CreateText(IBeatmapInfo beatmapInfo); } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs index 32201e36a9..c4c8bfb84f 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -13,6 +14,7 @@ using osu.Game.Graphics.Sprites; using osuTK; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections.Historical @@ -22,13 +24,11 @@ namespace osu.Game.Overlays.Profile.Sections.Historical private const int cover_width = 100; private const int corner_radius = 6; - private readonly BeatmapInfo beatmapInfo; - private readonly int playCount; + private readonly APIUserMostPlayedBeatmap mostPlayed; - public DrawableMostPlayedBeatmap(BeatmapInfo beatmapInfo, int playCount) + public DrawableMostPlayedBeatmap(APIUserMostPlayedBeatmap mostPlayed) { - this.beatmapInfo = beatmapInfo; - this.playCount = playCount; + this.mostPlayed = mostPlayed; RelativeSizeAxes = Axes.X; Height = 50; @@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { RelativeSizeAxes = Axes.Y, Width = cover_width, - BeatmapSet = beatmapInfo.BeatmapSet, + BeatmapSet = mostPlayed.BeatmapSet, }, new Container { @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical Direction = FillDirection.Vertical, Children = new Drawable[] { - new MostPlayedBeatmapMetadataContainer(beatmapInfo), + new MostPlayedBeatmapMetadataContainer(mostPlayed.BeatmapInfo), new LinkFlowContainer(t => { t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular); @@ -89,11 +89,11 @@ namespace osu.Game.Overlays.Profile.Sections.Historical }.With(d => { d.AddText("mapped by "); - d.AddUserLink(beatmapInfo.Metadata.Author); + d.AddUserLink(mostPlayed.BeatmapSet.Author); }), } }, - new PlayCountText(playCount) + new PlayCountText(mostPlayed.PlayCount) { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight @@ -120,26 +120,41 @@ namespace osu.Game.Overlays.Profile.Sections.Historical private class MostPlayedBeatmapMetadataContainer : BeatmapMetadataContainer { - public MostPlayedBeatmapMetadataContainer(BeatmapInfo beatmapInfo) + public MostPlayedBeatmapMetadataContainer(IBeatmapInfo beatmapInfo) : base(beatmapInfo) { } - protected override Drawable[] CreateText(BeatmapInfo beatmapInfo) => new Drawable[] + protected override Drawable[] CreateText(IBeatmapInfo beatmapInfo) { - new OsuSpriteText + var metadata = beatmapInfo.Metadata; + + Debug.Assert(metadata != null); + + return new Drawable[] { - Text = new RomanisableString( - $"{beatmapInfo.Metadata.TitleUnicode ?? beatmapInfo.Metadata.Title} [{beatmapInfo.Version}] ", - $"{beatmapInfo.Metadata.Title ?? beatmapInfo.Metadata.TitleUnicode} [{beatmapInfo.Version}] "), - Font = OsuFont.GetFont(weight: FontWeight.Bold) - }, - new OsuSpriteText - { - Text = "by " + new RomanisableString(beatmapInfo.Metadata.ArtistUnicode, beatmapInfo.Metadata.Artist), - Font = OsuFont.GetFont(weight: FontWeight.Regular) - }, - }; + new OsuSpriteText + { + Text = new RomanisableString(metadata.TitleUnicode, metadata.Title), + Font = OsuFont.GetFont(weight: FontWeight.Bold) + }, + new OsuSpriteText + { + Text = $" [{beatmapInfo.DifficultyName}]", + Font = OsuFont.GetFont(weight: FontWeight.Bold) + }, + new OsuSpriteText + { + Text = " by ", + Font = OsuFont.GetFont(weight: FontWeight.Regular) + }, + new OsuSpriteText + { + Text = new RomanisableString(metadata.ArtistUnicode, metadata.Artist), + Font = OsuFont.GetFont(weight: FontWeight.Regular) + }, + }; + } } private class PlayCountText : CompositeDrawable, IHasTooltip diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index d0979526da..428d04f985 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override APIRequest> CreateRequest() => new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, ItemsPerPage); - protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap model) => - new DrawableMostPlayedBeatmap(model.GetBeatmapInfo(Rulesets), model.PlayCount); + protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap mostPlayed) => + new DrawableMostPlayedBeatmap(mostPlayed); } } diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 3561e9700e..7bfa2ee51e 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Diagnostics; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; @@ -245,30 +246,42 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks private class ScoreBeatmapMetadataContainer : BeatmapMetadataContainer { - public ScoreBeatmapMetadataContainer(BeatmapInfo beatmapInfo) + public ScoreBeatmapMetadataContainer(IBeatmapInfo beatmapInfo) : base(beatmapInfo) { } - protected override Drawable[] CreateText(BeatmapInfo beatmapInfo) => new Drawable[] + protected override Drawable[] CreateText(IBeatmapInfo beatmapInfo) { - new OsuSpriteText + var metadata = beatmapInfo.Metadata; + + Debug.Assert(metadata != null); + + return new Drawable[] { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Text = new RomanisableString( - $"{beatmapInfo.Metadata.TitleUnicode ?? beatmapInfo.Metadata.Title} ", - $"{beatmapInfo.Metadata.Title ?? beatmapInfo.Metadata.TitleUnicode} "), - Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true) - }, - new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Text = "by " + new RomanisableString(beatmapInfo.Metadata.ArtistUnicode, beatmapInfo.Metadata.Artist), - Font = OsuFont.GetFont(size: 12, italics: true) - }, - }; + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Text = new RomanisableString(metadata.TitleUnicode, metadata.Title), + Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true) + }, + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Text = " by ", + Font = OsuFont.GetFont(size: 12, italics: true) + }, + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Text = new RomanisableString(metadata.ArtistUnicode, metadata.Artist), + Font = OsuFont.GetFont(size: 12, italics: true) + }, + }; + } } } } From 1ae6621c85bd8cb24aed197b114bffab272cf0e0 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 22 Oct 2021 15:45:48 -0700 Subject: [PATCH 18/18] Fix a missed toast shortcut string not localising correctly --- osu.Game/Configuration/OsuConfigManager.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index acb4a9ca02..6d37f68473 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -218,7 +218,9 @@ namespace osu.Game.Configuration rawValue: skinName, name: SkinSettingsStrings.SkinSectionHeader, value: skinName, - shortcut: $"{GlobalActionKeyBindingStrings.RandomSkin}: {LookupKeyBindings(GlobalAction.RandomSkin)}" + shortcut: new TranslatableString(@"_", @"{0}: {1}", + GlobalActionKeyBindingStrings.RandomSkin, + LookupKeyBindings(GlobalAction.RandomSkin)) ); }), new TrackedSetting(OsuSetting.UIScale, scale => new SettingDescription(