From 0584ee9ce55c5a9e86940c66754f5722ba4d4cd3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 14 Jul 2019 12:34:12 +0300 Subject: [PATCH 01/30] Basic implementation --- .../SongSelect/TestSceneUserTopScore.cs | 97 +++++++++++++++++++ .../Select/Details/UserTopScoreContainer.cs | 79 +++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs create mode 100644 osu.Game/Screens/Select/Details/UserTopScoreContainer.cs diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs new file mode 100644 index 0000000000..f7cfd4156d --- /dev/null +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs @@ -0,0 +1,97 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Screens.Select.Details; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Scoring; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.SongSelect +{ + public class TestSceneUserTopScore : OsuTestScene + { + private readonly UserTopScoreContainer topScoreContainer; + private readonly APILegacyUserTopScoreInfo[] scores; + + public TestSceneUserTopScore() + { + Add(new Container + { + Origin = Anchor.BottomCentre, + Anchor = Anchor.Centre, + AutoSizeAxes = Axes.Y, + Width = 500, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.DarkGreen, + }, + topScoreContainer = new UserTopScoreContainer + { + Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomCentre, + } + } + }); + + AddStep(@"Trigger visibility", topScoreContainer.ToggleVisibility); + AddStep(@"Add score", () => topScoreContainer.TopScore = scores[0]); + AddStep(@"Add another score", () => topScoreContainer.TopScore = scores[1]); + + scores = new APILegacyUserTopScoreInfo[] + { + new APILegacyUserTopScoreInfo + { + Position = 999, + Score = new APILegacyScoreInfo + { + Rank = ScoreRank.XH, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, + User = new User + { + Id = 6602580, + Username = @"waaiiru", + Country = new Country + { + FullName = @"Spain", + FlagName = @"ES", + }, + }, + } + }, + new APILegacyUserTopScoreInfo + { + Position = 110000, + Score = new APILegacyScoreInfo + { + Rank = ScoreRank.X, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + User = new User + { + Id = 4608074, + Username = @"Skycries", + Country = new Country + { + FullName = @"Brazil", + FlagName = @"BR", + }, + }, + } + } + }; + } + } +} diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs new file mode 100644 index 0000000000..05d0930de5 --- /dev/null +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -0,0 +1,79 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Leaderboards; + +namespace osu.Game.Screens.Select.Details +{ + public class UserTopScoreContainer : VisibilityContainer + { + private const int height = 150; + private const int duration = 300; + + private readonly Container contentContainer; + private readonly Container scoreContainer; + + public APILegacyUserTopScoreInfo TopScore + { + set + { + scoreContainer.Clear(); + scoreContainer.Add(new LeaderboardScore(value.Score, value.Position)); + } + } + + protected override bool StartHidden => true; + + public UserTopScoreContainer() + { + RelativeSizeAxes = Axes.X; + Height = height; + Anchor = Anchor.BottomCentre; + Origin = Anchor.BottomCentre; + Children = new Drawable[] + { + contentContainer = new Container + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Height = height, + RelativeSizeAxes = Axes.X, + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = @"your personal best".ToUpper(), + Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold), + }, + scoreContainer = new Container + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + } + } + } + }; + } + + protected override void PopIn() + { + this.ResizeHeightTo(height, duration, Easing.OutQuint); + contentContainer.FadeIn(duration, Easing.OutQuint); + } + + protected override void PopOut() + { + this.ResizeHeightTo(0, duration, Easing.OutQuint); + contentContainer.FadeOut(duration, Easing.OutQuint); + } + } +} From d30ae24f581d14d2068fbec2acf69375f6ff620a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 14 Jul 2019 12:40:54 +0300 Subject: [PATCH 02/30] Use Bindable for setting score --- .../SongSelect/TestSceneUserTopScore.cs | 5 +++-- .../Select/Details/UserTopScoreContainer.cs | 20 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs index f7cfd4156d..3fa85ffca6 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs @@ -43,8 +43,9 @@ namespace osu.Game.Tests.Visual.SongSelect }); AddStep(@"Trigger visibility", topScoreContainer.ToggleVisibility); - AddStep(@"Add score", () => topScoreContainer.TopScore = scores[0]); - AddStep(@"Add another score", () => topScoreContainer.TopScore = scores[1]); + AddStep(@"Add score", () => topScoreContainer.TopScore.Value = scores[0]); + AddStep(@"Add another score", () => topScoreContainer.TopScore.Value = scores[1]); + AddStep(@"Add null score", () => topScoreContainer.TopScore.Value = null); scores = new APILegacyUserTopScoreInfo[] { diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index 05d0930de5..21c16d1d74 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.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 osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -18,14 +19,7 @@ namespace osu.Game.Screens.Select.Details private readonly Container contentContainer; private readonly Container scoreContainer; - public APILegacyUserTopScoreInfo TopScore - { - set - { - scoreContainer.Clear(); - scoreContainer.Add(new LeaderboardScore(value.Score, value.Position)); - } - } + public Bindable TopScore = new Bindable(); protected override bool StartHidden => true; @@ -62,6 +56,16 @@ namespace osu.Game.Screens.Select.Details } } }; + + TopScore.BindValueChanged((score) => onScoreChanged(score.NewValue)); + } + + private void onScoreChanged(APILegacyUserTopScoreInfo score) + { + scoreContainer.Clear(); + + if (score != null) + scoreContainer.Add(new LeaderboardScore(score.Score, score.Position)); } protected override void PopIn() From 922c3c89ae4eb9d89c6e5c90d7af0c2ae7222fd0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 14 Jul 2019 12:47:35 +0300 Subject: [PATCH 03/30] Make leaderboard score use metric system --- .../SongSelect/TestSceneUserTopScore.cs | 26 +++++++++++++++++-- .../Online/Leaderboards/LeaderboardScore.cs | 12 ++++----- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs index 3fa85ffca6..1023294000 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs @@ -43,8 +43,9 @@ namespace osu.Game.Tests.Visual.SongSelect }); AddStep(@"Trigger visibility", topScoreContainer.ToggleVisibility); - AddStep(@"Add score", () => topScoreContainer.TopScore.Value = scores[0]); - AddStep(@"Add another score", () => topScoreContainer.TopScore.Value = scores[1]); + AddStep(@"Add score(rank 999)", () => topScoreContainer.TopScore.Value = scores[0]); + AddStep(@"Add score(rank 110000)", () => topScoreContainer.TopScore.Value = scores[1]); + AddStep(@"Add score(rank 22333)", () => topScoreContainer.TopScore.Value = scores[2]); AddStep(@"Add null score", () => topScoreContainer.TopScore.Value = null); scores = new APILegacyUserTopScoreInfo[] @@ -91,6 +92,27 @@ namespace osu.Game.Tests.Visual.SongSelect }, }, } + }, + new APILegacyUserTopScoreInfo + { + Position = 22333, + Score = new APILegacyScoreInfo + { + Rank = ScoreRank.S, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + User = new User + { + Id = 1541390, + Username = @"Toukai", + Country = new Country + { + FullName = @"Canada", + FlagName = @"CA", + }, + }, + } } }; } diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index 9840b59805..713d4a25f7 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -20,23 +20,23 @@ using osu.Game.Scoring; using osu.Game.Users.Drawables; using osuTK; using osuTK.Graphics; +using Humanizer; namespace osu.Game.Online.Leaderboards { public class LeaderboardScore : OsuClickableContainer { - public readonly int RankPosition; - public const float HEIGHT = 60; private const float corner_radius = 5; private const float edge_margin = 5; private const float background_alpha = 0.25f; - private const float rank_width = 30; + private const float rank_width = 35; protected Container RankContainer { get; private set; } private readonly ScoreInfo score; + private readonly int rank; private Box background; private Container content; @@ -52,7 +52,7 @@ namespace osu.Game.Online.Leaderboards public LeaderboardScore(ScoreInfo score, int rank) { this.score = score; - RankPosition = rank; + this.rank = rank; RelativeSizeAxes = Axes.X; Height = HEIGHT; @@ -79,8 +79,8 @@ namespace osu.Game.Online.Leaderboards { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 22, italics: true), - Text = RankPosition.ToString(), + Font = OsuFont.GetFont(size: 20, italics: true), + Text = rank <= 999 ? rank.ToString() : rank.ToMetric(decimals: rank < 100000 ? 1 : 0), }, }, }, From d1409d4610bbcb4f58c6cc5fb0ee0ea8b8e6f37d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 14 Jul 2019 13:33:47 +0300 Subject: [PATCH 04/30] Add top score section into beatmap detail area --- .../SongSelect/TestSceneBeatmapDetailArea.cs | 1 + osu.Game/Screens/Select/BeatmapDetailArea.cs | 68 +++++++++++-------- .../Select/Details/UserTopScoreContainer.cs | 3 +- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs index 7b97a27732..e9650343af 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs @@ -163,6 +163,7 @@ namespace osu.Game.Tests.Visual.SongSelect }); AddStep("null beatmap", () => detailsArea.Beatmap = null); + AddStep("Toggle top score visibility", () => detailsArea.TopScore.ToggleVisibility()); } } } diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index b66a2ffe0f..678b18e8cf 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -5,19 +5,18 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Screens.Select.Details; using osu.Game.Screens.Select.Leaderboards; namespace osu.Game.Screens.Select { public class BeatmapDetailArea : Container { - private const float details_padding = 10; - - private readonly Container content; - protected override Container Content => content; + private const float padding = 10; public readonly BeatmapDetails Details; public readonly BeatmapLeaderboard Leaderboard; + public readonly UserTopScoreContainer TopScore; private WorkingBeatmap beatmap; @@ -34,7 +33,7 @@ namespace osu.Game.Screens.Select public BeatmapDetailArea() { - AddRangeInternal(new Drawable[] + Children = new Drawable[] { new BeatmapDetailAreaTabControl { @@ -58,33 +57,44 @@ namespace osu.Game.Screens.Select } }, }, - content = new Container + new GridContainer { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = BeatmapDetailAreaTabControl.HEIGHT }, + Margin = new MarginPadding { Top = BeatmapDetailAreaTabControl.HEIGHT }, + RowDimensions = new Dimension[] + { + new Dimension(GridSizeMode.Distributed), + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + Details = new BeatmapDetails + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + Padding = new MarginPadding { Vertical = padding }, + }, + Leaderboard = new BeatmapLeaderboard + { + RelativeSizeAxes = Axes.Both, + } + } + } + }, + new Drawable[] + { + TopScore = new UserTopScoreContainer(), + } + }, }, - }); - - AddRange(new Drawable[] - { - Details = new BeatmapDetails - { - RelativeSizeAxes = Axes.X, - Alpha = 0, - Margin = new MarginPadding { Top = details_padding }, - }, - Leaderboard = new BeatmapLeaderboard - { - RelativeSizeAxes = Axes.Both, - } - }); - } - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - Details.Height = Math.Min(DrawHeight - details_padding * 3 - BeatmapDetailAreaTabControl.HEIGHT, 450); + }; } } } diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index 21c16d1d74..2cc47a7483 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.Select.Details { public class UserTopScoreContainer : VisibilityContainer { - private const int height = 150; + private const int height = 110; private const int duration = 300; private readonly Container contentContainer; @@ -37,6 +37,7 @@ namespace osu.Game.Screens.Select.Details Origin = Anchor.BottomCentre, Height = height, RelativeSizeAxes = Axes.X, + Padding = new MarginPadding { Vertical = 10 }, Children = new Drawable[] { new OsuSpriteText From 963e025bb8882eb94884adbf40bb6b13cc0b298a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 14 Jul 2019 14:03:14 +0300 Subject: [PATCH 05/30] Make it works and some layout adjustments --- .../SongSelect/TestSceneUserTopScore.cs | 8 +-- osu.Game/Screens/Select/BeatmapDetailArea.cs | 60 +++++++++++-------- .../Select/Details/UserTopScoreContainer.cs | 11 ++-- .../Select/Leaderboards/BeatmapLeaderboard.cs | 9 ++- 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs index 1023294000..b33dbddccb 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs @@ -43,10 +43,10 @@ namespace osu.Game.Tests.Visual.SongSelect }); AddStep(@"Trigger visibility", topScoreContainer.ToggleVisibility); - AddStep(@"Add score(rank 999)", () => topScoreContainer.TopScore.Value = scores[0]); - AddStep(@"Add score(rank 110000)", () => topScoreContainer.TopScore.Value = scores[1]); - AddStep(@"Add score(rank 22333)", () => topScoreContainer.TopScore.Value = scores[2]); - AddStep(@"Add null score", () => topScoreContainer.TopScore.Value = null); + AddStep(@"Add score(rank 999)", () => topScoreContainer.Score.Value = scores[0]); + AddStep(@"Add score(rank 110000)", () => topScoreContainer.Score.Value = scores[1]); + AddStep(@"Add score(rank 22333)", () => topScoreContainer.Score.Value = scores[2]); + AddStep(@"Add null score", () => topScoreContainer.Score.Value = null); scores = new APILegacyUserTopScoreInfo[] { diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index 678b18e8cf..cac1281cc2 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -1,10 +1,10 @@ // 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 osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Screens.Select.Details; using osu.Game.Screens.Select.Leaderboards; @@ -28,6 +28,7 @@ namespace osu.Game.Screens.Select beatmap = value; Leaderboard.Beatmap = beatmap?.BeatmapInfo; Details.Beatmap = beatmap?.BeatmapInfo; + TopScore.Hide(); } } @@ -57,43 +58,50 @@ namespace osu.Game.Screens.Select } }, }, - new GridContainer + new Container { + Padding = new MarginPadding { Top = BeatmapDetailAreaTabControl.HEIGHT, Bottom = padding }, RelativeSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = BeatmapDetailAreaTabControl.HEIGHT }, - RowDimensions = new Dimension[] + Child = new GridContainer { - new Dimension(GridSizeMode.Distributed), - new Dimension(GridSizeMode.AutoSize), - }, - Content = new[] - { - new Drawable[] + RelativeSizeAxes = Axes.Both, + RowDimensions = new Dimension[] { - new Container + new Dimension(GridSizeMode.Distributed), + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + new Container { - Details = new BeatmapDetails + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - Padding = new MarginPadding { Vertical = padding }, - }, - Leaderboard = new BeatmapLeaderboard - { - RelativeSizeAxes = Axes.Both, + Details = new BeatmapDetails + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + Padding = new MarginPadding { Top = padding }, + }, + Leaderboard = new BeatmapLeaderboard + { + RelativeSizeAxes = Axes.Both, + } } } + }, + new Drawable[] + { + TopScore = new UserTopScoreContainer + { + Score = { BindTarget = Leaderboard.TopScore } + } } }, - new Drawable[] - { - TopScore = new UserTopScoreContainer(), - } }, - }, + } }; } } diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index 2cc47a7483..0bc30fae6b 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -13,13 +13,13 @@ namespace osu.Game.Screens.Select.Details { public class UserTopScoreContainer : VisibilityContainer { - private const int height = 110; + private const int height = 90; private const int duration = 300; private readonly Container contentContainer; private readonly Container scoreContainer; - public Bindable TopScore = new Bindable(); + public Bindable Score = new Bindable(); protected override bool StartHidden => true; @@ -37,13 +37,13 @@ namespace osu.Game.Screens.Select.Details Origin = Anchor.BottomCentre, Height = height, RelativeSizeAxes = Axes.X, - Padding = new MarginPadding { Vertical = 10 }, Children = new Drawable[] { new OsuSpriteText { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, + Margin = new MarginPadding { Top = 5 }, Text = @"your personal best".ToUpper(), Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold), }, @@ -58,7 +58,7 @@ namespace osu.Game.Screens.Select.Details } }; - TopScore.BindValueChanged((score) => onScoreChanged(score.NewValue)); + Score.BindValueChanged((score) => onScoreChanged(score.NewValue)); } private void onScoreChanged(APILegacyUserTopScoreInfo score) @@ -66,7 +66,10 @@ namespace osu.Game.Screens.Select.Details scoreContainer.Clear(); if (score != null) + { scoreContainer.Add(new LeaderboardScore(score.Score, score.Position)); + Show(); + } } protected override void PopIn() diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 0f6d4f3188..c41bf17685 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -9,6 +9,7 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -18,6 +19,8 @@ namespace osu.Game.Screens.Select.Leaderboards { public class BeatmapLeaderboard : Leaderboard { + public Bindable TopScore = new Bindable(); + public Action ScoreSelected; private BeatmapInfo beatmap; @@ -133,7 +136,11 @@ namespace osu.Game.Screens.Select.Leaderboards var req = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope, requestMods); - req.Success += r => scoresCallback?.Invoke(r.Scores); + req.Success += r => + { + scoresCallback?.Invoke(r.Scores); + TopScore.Value = r.UserScore; + }; return req; } From ecf0e624849901aedcb2eac6008853773ef6aee8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 14 Jul 2019 16:16:21 +0300 Subject: [PATCH 06/30] CI fixes --- .../SongSelect/TestSceneUserTopScore.cs | 19 +++++++++---------- osu.Game/Screens/Select/BeatmapDetailArea.cs | 3 +-- .../Select/Details/UserTopScoreContainer.cs | 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs index b33dbddccb..1de8a5375e 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs @@ -16,11 +16,10 @@ namespace osu.Game.Tests.Visual.SongSelect { public class TestSceneUserTopScore : OsuTestScene { - private readonly UserTopScoreContainer topScoreContainer; - private readonly APILegacyUserTopScoreInfo[] scores; - public TestSceneUserTopScore() { + UserTopScoreContainer topScoreContainer; + Add(new Container { Origin = Anchor.BottomCentre, @@ -42,13 +41,7 @@ namespace osu.Game.Tests.Visual.SongSelect } }); - AddStep(@"Trigger visibility", topScoreContainer.ToggleVisibility); - AddStep(@"Add score(rank 999)", () => topScoreContainer.Score.Value = scores[0]); - AddStep(@"Add score(rank 110000)", () => topScoreContainer.Score.Value = scores[1]); - AddStep(@"Add score(rank 22333)", () => topScoreContainer.Score.Value = scores[2]); - AddStep(@"Add null score", () => topScoreContainer.Score.Value = null); - - scores = new APILegacyUserTopScoreInfo[] + APILegacyUserTopScoreInfo[] scores = new[] { new APILegacyUserTopScoreInfo { @@ -115,6 +108,12 @@ namespace osu.Game.Tests.Visual.SongSelect } } }; + + AddStep(@"Trigger visibility", topScoreContainer.ToggleVisibility); + AddStep(@"Add score(rank 999)", () => topScoreContainer.Score.Value = scores[0]); + AddStep(@"Add score(rank 110000)", () => topScoreContainer.Score.Value = scores[1]); + AddStep(@"Add score(rank 22333)", () => topScoreContainer.Score.Value = scores[2]); + AddStep(@"Add null score", () => topScoreContainer.Score.Value = null); } } } diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index cac1281cc2..6cd6372152 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -4,7 +4,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Screens.Select.Details; using osu.Game.Screens.Select.Leaderboards; @@ -65,7 +64,7 @@ namespace osu.Game.Screens.Select Child = new GridContainer { RelativeSizeAxes = Axes.Both, - RowDimensions = new Dimension[] + RowDimensions = new[] { new Dimension(GridSizeMode.Distributed), new Dimension(GridSizeMode.AutoSize), diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index 0bc30fae6b..0300d14ac1 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -58,7 +58,7 @@ namespace osu.Game.Screens.Select.Details } }; - Score.BindValueChanged((score) => onScoreChanged(score.NewValue)); + Score.BindValueChanged(score => onScoreChanged(score.NewValue)); } private void onScoreChanged(APILegacyUserTopScoreInfo score) From 19680c8df8f7c883df97f600bde0e1f882687758 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 14 Jul 2019 16:37:05 +0300 Subject: [PATCH 07/30] Minor adjustments --- osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs | 2 +- osu.Game/Screens/Select/Details/UserTopScoreContainer.cs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs index 1de8a5375e..5ddccb4c8e 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.SongSelect } }); - APILegacyUserTopScoreInfo[] scores = new[] + var scores = new APILegacyUserTopScoreInfo[] { new APILegacyUserTopScoreInfo { diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index 0300d14ac1..e5e33a47d8 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -63,13 +63,14 @@ namespace osu.Game.Screens.Select.Details private void onScoreChanged(APILegacyUserTopScoreInfo score) { - scoreContainer.Clear(); - if (score != null) { + scoreContainer.Clear(); scoreContainer.Add(new LeaderboardScore(score.Score, score.Position)); Show(); } + else + Hide(); } protected override void PopIn() From a01e7260e06e7b23d6b40d7c54d56bee969eb2cc Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 14 Jul 2019 16:49:46 +0300 Subject: [PATCH 08/30] Testcase fix --- osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs index 5ddccb4c8e..5f3e7d09dd 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.SongSelect } }); - var scores = new APILegacyUserTopScoreInfo[] + var scores = new[] { new APILegacyUserTopScoreInfo { From 27258e3a9b6b16d2ed845b9e65ab63515366a718 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 15 Jul 2019 14:38:05 +0900 Subject: [PATCH 09/30] Rename test scene to match class --- ...SceneUserTopScore.cs => TestSceneUserTopScoreContainer.cs} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename osu.Game.Tests/Visual/SongSelect/{TestSceneUserTopScore.cs => TestSceneUserTopScoreContainer.cs} (97%) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs similarity index 97% rename from osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs rename to osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs index 5f3e7d09dd..38ebb58e76 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScore.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs @@ -14,9 +14,9 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.SongSelect { - public class TestSceneUserTopScore : OsuTestScene + public class TestSceneUserTopScoreContainer : OsuTestScene { - public TestSceneUserTopScore() + public TestSceneUserTopScoreContainer() { UserTopScoreContainer topScoreContainer; From 7e367dc397e9ce17fe089b83df4b324689d5d756 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 15 Jul 2019 12:30:42 +0300 Subject: [PATCH 10/30] Push results screen when clicking on top score --- osu.Game/Screens/Select/Details/UserTopScoreContainer.cs | 9 ++++++++- osu.Game/Screens/Select/SongSelect.cs | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index e5e33a47d8..ba6751475e 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -8,6 +8,8 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; +using osu.Game.Scoring; +using System; namespace osu.Game.Screens.Select.Details { @@ -21,6 +23,8 @@ namespace osu.Game.Screens.Select.Details public Bindable Score = new Bindable(); + public Action ScoreSelected; + protected override bool StartHidden => true; public UserTopScoreContainer() @@ -66,7 +70,10 @@ namespace osu.Game.Screens.Select.Details if (score != null) { scoreContainer.Clear(); - scoreContainer.Add(new LeaderboardScore(score.Score, score.Position)); + scoreContainer.Add(new LeaderboardScore(score.Score, score.Position) + { + Action = () => ScoreSelected?.Invoke(score.Score) + }); Show(); } else diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index b3c3925a26..94b1fedeab 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -216,6 +216,7 @@ namespace osu.Game.Screens.Select } BeatmapDetails.Leaderboard.ScoreSelected += s => this.Push(new SoloResults(s)); + BeatmapDetails.TopScore.ScoreSelected += s => this.Push(new SoloResults(s)); } [BackgroundDependencyLoader(true)] From 764513feea591b2d6e25e378e15913017d525b20 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Jul 2019 23:13:48 +0900 Subject: [PATCH 11/30] Fix code quality --- .../Select/Details/UserTopScoreContainer.cs | 46 ++++++++++--------- osu.Game/Screens/Select/SongSelect.cs | 6 ++- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index ba6751475e..cc2d2a3dae 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -31,30 +31,31 @@ namespace osu.Game.Screens.Select.Details { RelativeSizeAxes = Axes.X; Height = height; - Anchor = Anchor.BottomCentre; - Origin = Anchor.BottomCentre; + + Anchor = Anchor.BottomLeft; + Origin = Anchor.BottomLeft; + Children = new Drawable[] { contentContainer = new Container { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Height = height, - RelativeSizeAxes = Axes.X, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, Children = new Drawable[] { new OsuSpriteText { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, Margin = new MarginPadding { Top = 5 }, Text = @"your personal best".ToUpper(), Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold), }, scoreContainer = new Container { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, } @@ -62,22 +63,25 @@ namespace osu.Game.Screens.Select.Details } }; - Score.BindValueChanged(score => onScoreChanged(score.NewValue)); + Score.BindValueChanged(onScoreChanged); } - private void onScoreChanged(APILegacyUserTopScoreInfo score) + private void onScoreChanged(ValueChangedEvent score) { - if (score != null) + var newScore = score.NewValue; + + if (newScore == null) { - scoreContainer.Clear(); - scoreContainer.Add(new LeaderboardScore(score.Score, score.Position) - { - Action = () => ScoreSelected?.Invoke(score.Score) - }); - Show(); - } - else Hide(); + return; + } + + scoreContainer.Child = new LeaderboardScore(newScore.Score, newScore.Position) + { + Action = () => ScoreSelected?.Invoke(newScore.Score) + }; + + Show(); } protected override void PopIn() diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 209707d8fe..a3b87b5068 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -215,8 +215,10 @@ namespace osu.Game.Screens.Select }); } - BeatmapDetails.Leaderboard.ScoreSelected += s => this.Push(new SoloResults(s)); - BeatmapDetails.TopScore.ScoreSelected += s => this.Push(new SoloResults(s)); + void displayScore(ScoreInfo score) => this.Push(new SoloResults(score)); + + BeatmapDetails.Leaderboard.ScoreSelected += displayScore; + BeatmapDetails.TopScore.ScoreSelected += displayScore; } [BackgroundDependencyLoader(true)] From d83d93ee66fa26b2aabe1678d5c4704f1f74c0d1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Jul 2019 23:21:07 +0900 Subject: [PATCH 12/30] Use asynchronous loading --- .../Select/Details/UserTopScoreContainer.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index cc2d2a3dae..1535aa3df1 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -10,6 +10,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Scoring; using System; +using System.Threading; namespace osu.Game.Screens.Select.Details { @@ -66,6 +67,8 @@ namespace osu.Game.Screens.Select.Details Score.BindValueChanged(onScoreChanged); } + private CancellationTokenSource loadScoreCancellation; + private void onScoreChanged(ValueChangedEvent score) { var newScore = score.NewValue; @@ -76,12 +79,17 @@ namespace osu.Game.Screens.Select.Details return; } - scoreContainer.Child = new LeaderboardScore(newScore.Score, newScore.Position) + scoreContainer.Clear(); + loadScoreCancellation?.Cancel(); + + LoadComponentAsync(new LeaderboardScore(newScore.Score, newScore.Position) { Action = () => ScoreSelected?.Invoke(newScore.Score) - }; - - Show(); + }, drawableScore => + { + scoreContainer.Child = drawableScore; + Show(); + }, (loadScoreCancellation = new CancellationTokenSource()).Token); } protected override void PopIn() From 95241165cce4724758f7267630b1755c748b1dbc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Jul 2019 23:26:11 +0900 Subject: [PATCH 13/30] Fix text alignment --- osu.Game/Screens/Select/Details/UserTopScoreContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index 1535aa3df1..5a224756b9 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// 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.Bindables; @@ -47,8 +47,8 @@ namespace osu.Game.Screens.Select.Details { new OsuSpriteText { - Anchor = Anchor.TopLeft, - Origin = Anchor.TopLeft, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, Margin = new MarginPadding { Top = 5 }, Text = @"your personal best".ToUpper(), Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold), From 5a6c8bfec9ff1563856ecd22936dc396e2360d90 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Jul 2019 23:28:17 +0900 Subject: [PATCH 14/30] Adjust transition to now show janky resize --- .../Select/Details/UserTopScoreContainer.cs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index 5a224756b9..8e9df8bbb1 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// 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.Bindables; @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Select.Details public class UserTopScoreContainer : VisibilityContainer { private const int height = 90; - private const int duration = 300; + private const int duration = 800; private readonly Container contentContainer; private readonly Container scoreContainer; @@ -92,16 +92,8 @@ namespace osu.Game.Screens.Select.Details }, (loadScoreCancellation = new CancellationTokenSource()).Token); } - protected override void PopIn() - { - this.ResizeHeightTo(height, duration, Easing.OutQuint); - contentContainer.FadeIn(duration, Easing.OutQuint); - } + protected override void PopIn() => this.ResizeHeightTo(height, duration / 4f, Easing.OutQuint).OnComplete(_ => contentContainer.FadeIn(duration, Easing.OutQuint)); - protected override void PopOut() - { - this.ResizeHeightTo(0, duration, Easing.OutQuint); - contentContainer.FadeOut(duration, Easing.OutQuint); - } + protected override void PopOut() => contentContainer.FadeOut(duration, Easing.OutQuint).OnComplete(_ => this.ResizeHeightTo(0)); } } From 94ed03548d7a401bc43be3b9ce602412efb6e662 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 22 Jul 2019 18:34:31 +0300 Subject: [PATCH 15/30] Hide top score at every leaderboard change --- osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index ee16123e20..f4a18e3b58 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -86,6 +86,8 @@ namespace osu.Game.Screens.Select.Leaderboards protected override APIRequest FetchScores(Action> scoresCallback) { + TopScore.Value = null; + if (Scope == BeatmapLeaderboardScope.Local) { var scores = scoreManager From 76b79f355443cba1b1f60fea02f24fae764e771d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 23 Jul 2019 01:14:45 +0300 Subject: [PATCH 16/30] Transform adjustments --- osu.Game/Screens/Select/Details/UserTopScoreContainer.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index 8e9df8bbb1..c10f4d4fd4 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -42,7 +42,8 @@ namespace osu.Game.Screens.Select.Details { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + Height = height, Children = new Drawable[] { new OsuSpriteText @@ -94,6 +95,10 @@ namespace osu.Game.Screens.Select.Details protected override void PopIn() => this.ResizeHeightTo(height, duration / 4f, Easing.OutQuint).OnComplete(_ => contentContainer.FadeIn(duration, Easing.OutQuint)); - protected override void PopOut() => contentContainer.FadeOut(duration, Easing.OutQuint).OnComplete(_ => this.ResizeHeightTo(0)); + protected override void PopOut() + { + this.ResizeHeightTo(0); + contentContainer.FadeOut(duration / 4f, Easing.OutQuint); + } } } From e5509cd3908175a866809317576b0d896b53afe8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 13:19:48 +0900 Subject: [PATCH 17/30] Rename test --- ...stSceneLeaderboard.cs => TestSceneBeatmapLeaderboard.cs} | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) rename osu.Game.Tests/Visual/SongSelect/{TestSceneLeaderboard.cs => TestSceneBeatmapLeaderboard.cs} (98%) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs similarity index 98% rename from osu.Game.Tests/Visual/SongSelect/TestSceneLeaderboard.cs rename to osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs index 186f27a8b2..cb4cd63266 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneLeaderboard.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Online.Leaderboards; @@ -14,8 +13,7 @@ using osuTK; namespace osu.Game.Tests.Visual.SongSelect { - [Description("PlaySongSelect leaderboard")] - public class TestSceneLeaderboard : OsuTestScene + public class TestSceneBeatmapLeaderboard : OsuTestScene { public override IReadOnlyList RequiredTypes => new[] { @@ -26,7 +24,7 @@ namespace osu.Game.Tests.Visual.SongSelect private readonly FailableLeaderboard leaderboard; - public TestSceneLeaderboard() + public TestSceneBeatmapLeaderboard() { Add(leaderboard = new FailableLeaderboard { From a7b6895d4c9c79119922792b6d688faa48ee2166 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 14:26:15 +0900 Subject: [PATCH 18/30] Revert changes to BeatmapDetailArea --- .../SongSelect/TestSceneBeatmapDetailArea.cs | 1 - osu.Game/Screens/Select/BeatmapDetailArea.cs | 77 ++++++++----------- osu.Game/Screens/Select/SongSelect.cs | 1 - 3 files changed, 30 insertions(+), 49 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs index ee47888d99..ed9e01a67e 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs @@ -163,7 +163,6 @@ namespace osu.Game.Tests.Visual.SongSelect })); AddStep("null beatmap", () => detailsArea.Beatmap = null); - AddStep("Toggle top score visibility", () => detailsArea.TopScore.ToggleVisibility()); } } } diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index 648dae68bc..5348de68d6 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -1,21 +1,23 @@ // 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 osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; -using osu.Game.Screens.Select.Details; using osu.Game.Screens.Select.Leaderboards; namespace osu.Game.Screens.Select { public class BeatmapDetailArea : Container { - private const float padding = 10; + private const float details_padding = 10; + + private readonly Container content; + protected override Container Content => content; public readonly BeatmapDetails Details; public readonly BeatmapLeaderboard Leaderboard; - public readonly UserTopScoreContainer TopScore; private WorkingBeatmap beatmap; @@ -27,13 +29,12 @@ namespace osu.Game.Screens.Select beatmap = value; Details.Beatmap = beatmap?.BeatmapInfo; Leaderboard.Beatmap = beatmap is DummyWorkingBeatmap ? null : beatmap?.BeatmapInfo; - TopScore.Hide(); } } public BeatmapDetailArea() { - Children = new Drawable[] + AddRangeInternal(new Drawable[] { new BeatmapDetailAreaTabControl { @@ -57,51 +58,33 @@ namespace osu.Game.Screens.Select } }, }, - new Container + content = new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = BeatmapDetailAreaTabControl.HEIGHT }, + }, + }); + + AddRange(new Drawable[] + { + Details = new BeatmapDetails + { + RelativeSizeAxes = Axes.X, + Alpha = 0, + Margin = new MarginPadding { Top = details_padding }, + }, + Leaderboard = new BeatmapLeaderboard { - Padding = new MarginPadding { Top = BeatmapDetailAreaTabControl.HEIGHT, Bottom = padding }, RelativeSizeAxes = Axes.Both, - Child = new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(GridSizeMode.Distributed), - new Dimension(GridSizeMode.AutoSize), - }, - Content = new[] - { - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - Details = new BeatmapDetails - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - Padding = new MarginPadding { Top = padding }, - }, - Leaderboard = new BeatmapLeaderboard - { - RelativeSizeAxes = Axes.Both, - } - } - } - }, - new Drawable[] - { - TopScore = new UserTopScoreContainer - { - Score = { BindTarget = Leaderboard.TopScore } - } - } - }, - }, } - }; + }); + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + Details.Height = Math.Min(DrawHeight - details_padding * 3 - BeatmapDetailAreaTabControl.HEIGHT, 450); } } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 173442384e..7f9804c6a3 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -226,7 +226,6 @@ namespace osu.Game.Screens.Select void displayScore(ScoreInfo score) => this.Push(new SoloResults(score)); BeatmapDetails.Leaderboard.ScoreSelected += displayScore; - BeatmapDetails.TopScore.ScoreSelected += displayScore; } [BackgroundDependencyLoader(true)] From 4967ffd8e557291a261a6b678026a91a2901965f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 14:52:31 +0900 Subject: [PATCH 19/30] Move inside leaderboard --- osu.Game/Online/Leaderboards/Leaderboard.cs | 39 ++++++++++++++++--- .../Select/Leaderboards/BeatmapLeaderboard.cs | 12 ++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index 147556b78b..d66a9a7535 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -35,6 +35,10 @@ namespace osu.Game.Online.Leaderboards private bool scoresLoadedOnce; + private readonly Container content; + + protected override Container Content => content; + private IEnumerable scores; public IEnumerable Scores @@ -60,13 +64,13 @@ namespace osu.Game.Online.Leaderboards // ensure placeholder is hidden when displaying scores PlaceholderState = PlaceholderState.Successful; - var sf = CreateScoreFlow(); - sf.ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1)); + var scoreFlow = CreateScoreFlow(); + scoreFlow.ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1)); // schedule because we may not be loaded yet (LoadComponentAsync complains). - showScoresDelegate = Schedule(() => LoadComponentAsync(sf, _ => + showScoresDelegate = Schedule(() => LoadComponentAsync(scoreFlow, _ => { - scrollContainer.Add(scrollFlow = sf); + scrollContainer.Add(scrollFlow = scoreFlow); int i = 0; @@ -164,10 +168,33 @@ namespace osu.Game.Online.Leaderboards { Children = new Drawable[] { - scrollContainer = new OsuScrollContainer + new GridContainer { RelativeSizeAxes = Axes.Both, - ScrollbarVisible = false, + RowDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] + { + scrollContainer = new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both, + ScrollbarVisible = false, + } + }, + new Drawable[] + { + content = new Container + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + }, + } + }, }, loading = new LoadingAnimation(), placeholderContainer = new Container diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 4e4def4911..0eef784279 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -80,6 +80,18 @@ namespace osu.Game.Screens.Select.Leaderboards if (filterMods) UpdateScores(); }; + + TopScore.BindValueChanged(newTopScore); + } + + private void newTopScore(ValueChangedEvent score) + { + Content.Clear(); + + if (score.NewValue != null) + { + + } } protected override bool IsOnlineScope => Scope != BeatmapLeaderboardScope.Local; From 098e89cb66a2896d673c0cb924eecfc92147ff56 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 15:23:33 +0900 Subject: [PATCH 20/30] Improve state reset flow --- osu.Game/Online/Leaderboards/Leaderboard.cs | 13 ++++--- .../Select/Details/UserTopScoreContainer.cs | 22 ++++++------ .../Select/Leaderboards/BeatmapLeaderboard.cs | 36 ++++++++++++------- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index d66a9a7535..83de0635fb 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -120,9 +120,7 @@ namespace osu.Game.Online.Leaderboards { if (value != PlaceholderState.Successful) { - getScoresRequest?.Cancel(); - getScoresRequest = null; - Scores = null; + Reset(); } if (value == placeholderState) @@ -166,7 +164,7 @@ namespace osu.Game.Online.Leaderboards protected Leaderboard() { - Children = new Drawable[] + InternalChildren = new Drawable[] { new GridContainer { @@ -204,6 +202,13 @@ namespace osu.Game.Online.Leaderboards }; } + protected virtual void Reset() + { + getScoresRequest?.Cancel(); + getScoresRequest = null; + Scores = null; + } + private IAPIProvider api; private ScheduledDelegate pendingUpdateScores; diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index c10f4d4fd4..959fbb927a 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -17,9 +17,8 @@ namespace osu.Game.Screens.Select.Details public class UserTopScoreContainer : VisibilityContainer { private const int height = 90; - private const int duration = 800; + private const int duration = 500; - private readonly Container contentContainer; private readonly Container scoreContainer; public Bindable Score = new Bindable(); @@ -38,7 +37,7 @@ namespace osu.Game.Screens.Select.Details Children = new Drawable[] { - contentContainer = new Container + new Container { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, @@ -74,15 +73,12 @@ namespace osu.Game.Screens.Select.Details { var newScore = score.NewValue; - if (newScore == null) - { - Hide(); - return; - } - scoreContainer.Clear(); loadScoreCancellation?.Cancel(); + if (newScore == null) + return; + LoadComponentAsync(new LeaderboardScore(newScore.Score, newScore.Position) { Action = () => ScoreSelected?.Invoke(newScore.Score) @@ -93,12 +89,14 @@ namespace osu.Game.Screens.Select.Details }, (loadScoreCancellation = new CancellationTokenSource()).Token); } - protected override void PopIn() => this.ResizeHeightTo(height, duration / 4f, Easing.OutQuint).OnComplete(_ => contentContainer.FadeIn(duration, Easing.OutQuint)); + protected override void PopIn() + { + this.FadeIn(duration, Easing.OutQuint); + } protected override void PopOut() { - this.ResizeHeightTo(0); - contentContainer.FadeOut(duration / 4f, Easing.OutQuint); + this.FadeOut(duration, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 0eef784279..d038049504 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -14,13 +14,12 @@ using osu.Game.Online.Leaderboards; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Scoring; +using osu.Game.Screens.Select.Details; namespace osu.Game.Screens.Select.Leaderboards { public class BeatmapLeaderboard : Leaderboard { - public Bindable TopScore = new Bindable(); - public Action ScoreSelected; private BeatmapInfo beatmap; @@ -40,8 +39,25 @@ namespace osu.Game.Screens.Select.Leaderboards } } + public APILegacyUserTopScoreInfo TopScore + { + get => topScoreContainer.Score.Value; + set + { + if (value == null) + topScoreContainer.Hide(); + else + { + topScoreContainer.Show(); + topScoreContainer.Score.Value = value; + } + } + } + private bool filterMods; + private UserTopScoreContainer topScoreContainer; + /// /// Whether to apply the game's currently selected mods as a filter when retrieving scores. /// @@ -81,25 +97,19 @@ namespace osu.Game.Screens.Select.Leaderboards UpdateScores(); }; - TopScore.BindValueChanged(newTopScore); + Content.Add(topScoreContainer = new UserTopScoreContainer()); } - private void newTopScore(ValueChangedEvent score) + protected override void Reset() { - Content.Clear(); - - if (score.NewValue != null) - { - - } + base.Reset(); + TopScore = null; } protected override bool IsOnlineScope => Scope != BeatmapLeaderboardScope.Local; protected override APIRequest FetchScores(Action> scoresCallback) { - TopScore.Value = null; - if (Beatmap == null) { PlaceholderState = PlaceholderState.NoneSelected; @@ -161,7 +171,7 @@ namespace osu.Game.Screens.Select.Leaderboards req.Success += r => { scoresCallback?.Invoke(r.Scores); - TopScore.Value = r.UserScore; + TopScore = r.UserScore; }; return req; From 9b35de9ce17c1fbe85ccabbc4e58bba81bef805f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 15:23:37 +0900 Subject: [PATCH 21/30] Update tests --- .../SongSelect/TestSceneBeatmapLeaderboard.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs index cb4cd63266..bbd874fcd7 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs @@ -5,8 +5,12 @@ using System; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; using osu.Game.Scoring; +using osu.Game.Screens.Select.Details; using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; using osuTK; @@ -20,6 +24,8 @@ namespace osu.Game.Tests.Visual.SongSelect typeof(Placeholder), typeof(MessagePlaceholder), typeof(RetrievalFailurePlaceholder), + typeof(UserTopScoreContainer), + typeof(Leaderboard), }; private readonly FailableLeaderboard leaderboard; @@ -35,6 +41,7 @@ namespace osu.Game.Tests.Visual.SongSelect }); AddStep(@"New Scores", newScores); + AddStep(@"Show personal best", showPersonalBest); AddStep(@"Empty Scores", () => leaderboard.SetRetrievalState(PlaceholderState.NoScores)); AddStep(@"Network failure", () => leaderboard.SetRetrievalState(PlaceholderState.NetworkFailure)); AddStep(@"No supporter", () => leaderboard.SetRetrievalState(PlaceholderState.NotSupporter)); @@ -45,6 +52,32 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep($"{status} beatmap", () => showBeatmapWithStatus(status)); } + private void showPersonalBest() + { + leaderboard.TopScore = new APILegacyUserTopScoreInfo + { + Position = 999, + Score = new APILegacyScoreInfo + { + Rank = ScoreRank.XH, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, + User = new User + { + Id = 6602580, + Username = @"waaiiru", + Country = new Country + { + FullName = @"Spain", + FlagName = @"ES", + }, + }, + } + }; + } + private void newScores() { var scores = new[] From e0fd8609d1f96f5fd0169248a3e6b2d3611097f2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 15:34:46 +0900 Subject: [PATCH 22/30] Fix margins and clean up implementation --- .../Select/Details/UserTopScoreContainer.cs | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs index 959fbb927a..9d03f8439a 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs @@ -16,7 +16,6 @@ namespace osu.Game.Screens.Select.Details { public class UserTopScoreContainer : VisibilityContainer { - private const int height = 90; private const int duration = 500; private readonly Container scoreContainer; @@ -30,33 +29,30 @@ namespace osu.Game.Screens.Select.Details public UserTopScoreContainer() { RelativeSizeAxes = Axes.X; - Height = height; + AutoSizeAxes = Axes.Y; - Anchor = Anchor.BottomLeft; - Origin = Anchor.BottomLeft; + Margin = new MarginPadding { Vertical = 5 }; Children = new Drawable[] { - new Container + new FillFlowContainer { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, RelativeSizeAxes = Axes.X, - Height = height, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, Children = new Drawable[] { new OsuSpriteText { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Margin = new MarginPadding { Top = 5 }, Text = @"your personal best".ToUpper(), Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold), }, scoreContainer = new Container { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, } @@ -89,14 +85,8 @@ namespace osu.Game.Screens.Select.Details }, (loadScoreCancellation = new CancellationTokenSource()).Token); } - protected override void PopIn() - { - this.FadeIn(duration, Easing.OutQuint); - } + protected override void PopIn() => this.FadeIn(duration, Easing.OutQuint); - protected override void PopOut() - { - this.FadeOut(duration, Easing.OutQuint); - } + protected override void PopOut() => this.FadeOut(duration, Easing.OutQuint); } } From 2b6c9aeb266e4f352fddebabb066314527ff658e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 15:38:40 +0900 Subject: [PATCH 23/30] Move top score container to more local namespace --- .../Visual/SongSelect/TestSceneBeatmapLeaderboard.cs | 1 - .../Visual/SongSelect/TestSceneUserTopScoreContainer.cs | 2 +- osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 1 - .../{Details => Leaderboards}/UserTopScoreContainer.cs | 6 +++--- 4 files changed, 4 insertions(+), 6 deletions(-) rename osu.Game/Screens/Select/{Details => Leaderboards}/UserTopScoreContainer.cs (98%) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs index bbd874fcd7..fb27ec7654 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs @@ -10,7 +10,6 @@ using osu.Game.Online.Leaderboards; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Scoring; -using osu.Game.Screens.Select.Details; using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; using osuTK; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs index 38ebb58e76..7fac45e0f1 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Screens.Select.Details; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -10,6 +9,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Scoring; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; namespace osu.Game.Tests.Visual.SongSelect diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index d038049504..71aa8a8a31 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -14,7 +14,6 @@ using osu.Game.Online.Leaderboards; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Scoring; -using osu.Game.Screens.Select.Details; namespace osu.Game.Screens.Select.Leaderboards { diff --git a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs similarity index 98% rename from osu.Game/Screens/Select/Details/UserTopScoreContainer.cs rename to osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs index 9d03f8439a..301b3a6ae1 100644 --- a/osu.Game/Screens/Select/Details/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs @@ -1,6 +1,8 @@ // 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 osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -9,10 +11,8 @@ using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Scoring; -using System; -using System.Threading; -namespace osu.Game.Screens.Select.Details +namespace osu.Game.Screens.Select.Leaderboards { public class UserTopScoreContainer : VisibilityContainer { From 033c68a428bc74c126466d8b39b0bb119e8611dd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 15:44:00 +0900 Subject: [PATCH 24/30] Fade in score, not container --- osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs index 301b3a6ae1..c5872e271d 100644 --- a/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -81,7 +81,7 @@ namespace osu.Game.Screens.Select.Leaderboards }, drawableScore => { scoreContainer.Child = drawableScore; - Show(); + drawableScore.FadeInFromZero(duration, Easing.OutQuint); }, (loadScoreCancellation = new CancellationTokenSource()).Token); } From 36d0695e5c243e2012b2f128364a52574665117b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 15:44:05 +0900 Subject: [PATCH 25/30] Add spacing --- osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs b/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs index c5872e271d..da8f676cd0 100644 --- a/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs +++ b/osu.Game/Screens/Select/Leaderboards/UserTopScoreContainer.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -11,6 +11,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Scoring; +using osuTK; namespace osu.Game.Screens.Select.Leaderboards { @@ -40,6 +41,7 @@ namespace osu.Game.Screens.Select.Leaderboards RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, + Spacing = new Vector2(5), Children = new Drawable[] { new OsuSpriteText From 48ee95955b80ea7a385e55649fcd71e308d2b197 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 15:45:08 +0900 Subject: [PATCH 26/30] Remove unnecessary redirection --- osu.Game/Screens/Select/SongSelect.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 7f9804c6a3..fca801ce78 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -223,9 +223,7 @@ namespace osu.Game.Screens.Select }); } - void displayScore(ScoreInfo score) => this.Push(new SoloResults(score)); - - BeatmapDetails.Leaderboard.ScoreSelected += displayScore; + BeatmapDetails.Leaderboard.ScoreSelected += score => this.Push(new SoloResults(score)); } [BackgroundDependencyLoader(true)] From e2f7d4bc629defae3f03c64040be75857594c27f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 15:45:43 +0900 Subject: [PATCH 27/30] Remove unnecessary ToMetric avoidance --- osu.Game/Online/Leaderboards/LeaderboardScore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index e21ad413b6..9387482f14 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -80,7 +80,7 @@ namespace osu.Game.Online.Leaderboards Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(size: 20, italics: true), - Text = rank <= 999 ? rank.ToString() : rank.ToMetric(decimals: rank < 100000 ? 1 : 0), + Text = rank.ToMetric(decimals: rank < 100000 ? 1 : 0), }, }, }, From ddff9882cf25e447df3e5632b0bc65f65d125d73 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 17:35:45 +0900 Subject: [PATCH 28/30] Fix importing archives which are nested in a single folder within a zip --- .../Beatmaps/IO/ImportBeatmapTest.cs | 50 ++++++++++++++++++- osu.Game/Database/ArchiveModelManager.cs | 7 ++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index ad0ed00989..8b39946ab0 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -15,7 +15,10 @@ using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.IO; using osu.Game.Tests.Resources; +using SharpCompress.Archives; using SharpCompress.Archives.Zip; +using SharpCompress.Common; +using SharpCompress.Writers.Zip; namespace osu.Game.Tests.Beatmaps.IO { @@ -135,7 +138,7 @@ namespace osu.Game.Tests.Beatmaps.IO using (var zip = ZipArchive.Open(brokenOsz)) { zip.AddEntry("broken.osu", brokenOsu, false); - zip.SaveTo(outStream, SharpCompress.Common.CompressionType.Deflate); + zip.SaveTo(outStream, CompressionType.Deflate); } // this will trigger purging of the existing beatmap (online set id match) but should rollback due to broken osu. @@ -366,6 +369,51 @@ namespace osu.Game.Tests.Beatmaps.IO } } + [Test] + public async Task TestImportNestedStructure() + { + using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportNestedStructure")) + { + try + { + var osu = loadOsu(host); + + var temp = TestResources.GetTestBeatmapForImport(); + + string extractedFolder = $"{temp}_extracted"; + string subfolder = Path.Combine(extractedFolder, "subfolder"); + + Directory.CreateDirectory(subfolder); + + try + { + using (var zip = ZipArchive.Open(temp)) + zip.WriteToDirectory(subfolder); + + using (var zip = ZipArchive.Create()) + { + zip.AddAllFromDirectory(extractedFolder); + zip.SaveTo(temp, new ZipWriterOptions(CompressionType.Deflate)); + } + + var imported = await osu.Dependencies.Get().Import(temp); + + ensureLoaded(osu); + + Assert.IsFalse(imported.Files.Any(f => f.Filename.Contains("subfolder")), "Files contain common subfolder"); + } + finally + { + Directory.Delete(extractedFolder, true); + } + } + finally + { + host.Exit(); + } + } + } + public static async Task LoadOszIntoOsu(OsuGameBase osu, string path = null) { var temp = path ?? TestResources.GetTestBeatmapForImport(); diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 52d3f013ce..6c79b0d472 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -11,6 +11,7 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using osu.Framework; using osu.Framework.Extensions; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.IO.File; using osu.Framework.Logging; using osu.Framework.Platform; @@ -481,12 +482,16 @@ namespace osu.Game.Database { var fileInfos = new List(); + string prefix = reader.Filenames.GetCommonPrefix(); + if (!(prefix.EndsWith("/") || prefix.EndsWith("\\"))) + prefix = string.Empty; + // import files to manager foreach (string file in reader.Filenames) using (Stream s = reader.GetStream(file)) fileInfos.Add(new TFileModel { - Filename = FileSafety.PathStandardise(file), + Filename = FileSafety.PathStandardise(file.Substring(prefix.Length)), FileInfo = files.Add(s) }); From cffee1fd5e39c0857d877793be0a5184bce5cc3b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Sep 2019 20:02:45 +0900 Subject: [PATCH 29/30] Fix imported beatmap paths not correctly matching files --- osu.Game/Beatmaps/BeatmapManager.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 02d7b2d98f..55b8b80e44 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -89,7 +89,7 @@ namespace osu.Game.Beatmaps protected override Task Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive, CancellationToken cancellationToken = default) { if (archive != null) - beatmapSet.Beatmaps = createBeatmapDifficulties(archive); + beatmapSet.Beatmaps = createBeatmapDifficulties(beatmapSet.Files); foreach (BeatmapInfo b in beatmapSet.Beatmaps) { @@ -279,13 +279,13 @@ namespace osu.Game.Beatmaps /// /// Create all required s for the provided archive. /// - private List createBeatmapDifficulties(ArchiveReader reader) + private List createBeatmapDifficulties(List files) { var beatmapInfos = new List(); - foreach (var name in reader.Filenames.Where(f => f.EndsWith(".osu"))) + foreach (var file in files.Where(f => f.Filename.EndsWith(".osu"))) { - using (var raw = reader.GetStream(name)) + using (var raw = Files.Store.GetStream(file.FileInfo.StoragePath)) using (var ms = new MemoryStream()) //we need a memory stream so we can seek using (var sr = new StreamReader(ms)) { @@ -295,7 +295,7 @@ namespace osu.Game.Beatmaps var decoder = Decoder.GetDecoder(sr); IBeatmap beatmap = decoder.Decode(sr); - beatmap.BeatmapInfo.Path = name; + beatmap.BeatmapInfo.Path = file.Filename; beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash(); beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash(); From 94d3bcc612b96c63814e6fb5523f3b794ee12877 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Sep 2019 20:47:33 +0900 Subject: [PATCH 30/30] Fix top score not being selectable --- osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 71aa8a8a31..337d46ecdd 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -96,7 +96,10 @@ namespace osu.Game.Screens.Select.Leaderboards UpdateScores(); }; - Content.Add(topScoreContainer = new UserTopScoreContainer()); + Content.Add(topScoreContainer = new UserTopScoreContainer + { + ScoreSelected = s => ScoreSelected?.Invoke(s) + }); } protected override void Reset()