From 72141935e84f8edd224c94224d1d18f917ff123d Mon Sep 17 00:00:00 2001 From: Jorolf <jorolf@gmx.de> Date: Thu, 21 Sep 2017 22:07:23 +0200 Subject: [PATCH] make pagination work and remove duplication in RanksSection --- osu.Desktop.Tests/Visual/TestCaseUserRanks.cs | 100 -------- osu.Game/Beatmaps/BeatmapInfo.cs | 2 + .../API/Requests/GetUserScoresRequest.cs | 6 +- .../Profile/Sections/Ranks/DrawableScore.cs | 5 +- .../Overlays/Profile/Sections/RanksSection.cs | 236 ++++++++---------- osu.Game/Tests/Visual/TestCaseUserRanks.cs | 75 +----- osu.Game/osu.Game.csproj | 2 - 7 files changed, 121 insertions(+), 305 deletions(-) delete mode 100644 osu.Desktop.Tests/Visual/TestCaseUserRanks.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs b/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs deleted file mode 100644 index 41f3a37e94..0000000000 --- a/osu.Desktop.Tests/Visual/TestCaseUserRanks.cs +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Testing; -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Overlays.Profile.Sections; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Scoring; -using System; -using System.Collections.Generic; - -namespace osu.Desktop.Tests.Visual -{ - internal class TestCaseUserRanks : TestCase - { - public override string Description => "showing your latest achievements"; - - protected override void LoadComplete() - { - base.LoadComplete(); - - RanksSection ranks; - - Add(new Container - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.Gray(0.2f) - }, - ranks = new RanksSection(), - } - }); - - AddStep("Add Best Performances", () => - { - List<Score> scores = new List<Score>(); - Mod[] availableMods = { new OsuModHidden(), new OsuModFlashlight(), new OsuModHardRock(), new OsuModDoubleTime(), new OsuModPerfect() }; - List<Mod> selectedMods = new List<Mod>(availableMods); - for (int i = 0; i <= availableMods.Length; i++) - { - scores.Add(new Score - { - Rank = (ScoreRank) Enum.GetValues(typeof(ScoreRank)).GetValue(Enum.GetValues(typeof(ScoreRank)).Length - 1 - i), - Accuracy = Math.Pow(0.99, i), - PP = Math.Pow(0.5, i) * 800, - Date = DateTimeOffset.UtcNow.AddDays(-Math.Pow(i, 2)), - Mods = selectedMods.ToArray(), - Beatmap = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Title = "Highscore", - Artist = "Panda Eyes & Teminite" - }, - Version = "Game Over", - OnlineBeatmapID = 736215, - } - }); - if(i < availableMods.Length) - selectedMods.Remove(availableMods[i]); - } - ranks.ScoresBest = scores.ToArray(); - }); - - AddStep("Add First Place", () => ranks.ScoresFirst = new[] - { - new Score - { - Rank = ScoreRank.A, - Accuracy = 0.735, - PP = 666, - Date = DateTimeOffset.UtcNow, - Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime(), new OsuModEasy() }, - Beatmap = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Title = "FREEDOM DiVE", - Artist = "xi" - }, - Version = "FOUR DIMENSIONS", - OnlineBeatmapID = 129891, - } - } - }); - - AddStep("Show More", ((RanksSection.ScoreFlowContainer)ranks.Children[1]).ShowMore); - } - } -} diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 0776669811..5775299ffb 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -19,8 +19,10 @@ namespace osu.Game.Beatmaps //TODO: should be in database public int BeatmapVersion; + [JsonProperty("id")] public int? OnlineBeatmapID { get; set; } + [JsonProperty("beatmapset_id")] public int? OnlineBeatmapSetID { get; set; } [ForeignKey(typeof(BeatmapSetInfo))] diff --git a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs index 20597aecc1..98db234196 100644 --- a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs @@ -9,14 +9,16 @@ namespace osu.Game.Online.API.Requests { private readonly long userId; private readonly ScoreType type; + private readonly int offset; - public GetUserScoresRequest(long userId, ScoreType type) + public GetUserScoresRequest(long userId, ScoreType type, int offset = 0) { this.userId = userId; this.type = type; + this.offset = offset; } - protected override string Target => $@"users/{userId}/scores/{type.ToString().ToLower()}"; + protected override string Target => $@"users/{userId}/scores/{type.ToString().ToLower()}?offset={offset}"; } public enum ScoreType diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs index d92ebf6dca..27df3fd0fa 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableScore.cs @@ -17,6 +17,7 @@ using osu.Framework.Localisation; using System.Globalization; using osu.Game.Rulesets.Scoring; using osu.Framework.Graphics.Cursor; +using System; namespace osu.Game.Overlays.Profile.Sections.Ranks { @@ -81,7 +82,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { stats.Add(new OsuSpriteText { - Text = $"{score.PP ?? 0}pp", + Text = $"{Math.Round(score.PP ?? 0)}pp", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, TextSize = 18, @@ -91,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { stats.Add(new OsuSpriteText { - Text = $"weighted: {(int)(score?.PP * weight ?? 0)}pp ({weight.ToString("0%", CultureInfo.CurrentCulture)})", + Text = $"weighted: {Math.Round(score.PP * weight ?? 0)}pp ({weight.ToString("0%", CultureInfo.CurrentCulture)})", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Colour = colour.GrayA, diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index 4f9470bd6e..b6c56f5cb1 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -15,6 +15,8 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Rulesets; using osu.Game.Users; +using osu.Game.Graphics.UserInterface; +using OpenTK; namespace osu.Game.Overlays.Profile.Sections { @@ -24,8 +26,7 @@ namespace osu.Game.Overlays.Profile.Sections public override string Identifier => "top_ranks"; - private readonly ScoreFlowContainer best, first; - private readonly OsuSpriteText bestMissing, firstMissing; + private readonly ScoreContainer best, first; private APIAccess api; private RulesetStore rulesets; @@ -34,40 +35,8 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new OsuSpriteText - { - TextSize = 15, - Text = "Best Performance", - Font = "Exo2.0-RegularItalic", - Margin = new MarginPadding { Top = 10, Bottom = 10 }, - }, - best = new ScoreFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - }, - bestMissing = new OsuSpriteText - { - TextSize = 14, - Text = "No awesome performance records yet. :(", - }, - new OsuSpriteText - { - TextSize = 15, - Text = "First Place Ranks", - Font = "Exo2.0-RegularItalic", - Margin = new MarginPadding { Top = 20, Bottom = 10 }, - }, - first = new ScoreFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - }, - firstMissing = new OsuSpriteText - { - TextSize = 14, - Text = "No awesome performance records yet. :(", - }, + best = new ScoreContainer(ScoreType.Best, "Best Performance", true), + first = new ScoreContainer(ScoreType.Firsts, "First Place Ranks"), }; } @@ -88,119 +57,67 @@ namespace osu.Game.Overlays.Profile.Sections set { base.User = value; - - // fetch online ranks - foreach (ScoreType m in new[] { ScoreType.Best, ScoreType.Firsts }) - { - ScoreType thisType = m; - var req = new GetUserScoresRequest(User.Id, m); - req.Success += scores => - { - foreach (var s in scores) - s.ApplyRuleset(rulesets.GetRuleset(s.OnlineRulesetID)); - - switch (thisType) - { - case ScoreType.Best: - ScoresBest = scores; - break; - case ScoreType.Firsts: - ScoresFirst = scores; - break; - } - }; - - Schedule(() => { api.Queue(req); }); - } + best.User = value; + first.User = value; } } - - public IEnumerable<Score> ScoresBest + private class ScoreContainer : FillFlowContainer { - set + private readonly FillFlowContainer<DrawableScore> scoreContainer; + private readonly OsuSpriteText missing; + private readonly OsuHoverContainer showMoreButton; + private readonly LoadingAnimation showMoreLoading; + + private ScoreType type; + private int visiblePages; + private User user; + private readonly bool includeWeigth; + + private RulesetStore rulesets; + private APIAccess api; + + public User User { - best.Clear(); - if (!value.Any()) + set { - bestMissing.Show(); + user = value; + visiblePages = 0; + scoreContainer.Clear(); + showMoreButton.Hide(); + missing.Show(); + showMore(); } - else - { - bestMissing.Hide(); - int i = 0; - foreach (Score score in value) - { - best.Add(new DrawableScore(score, Math.Pow(0.95, i)) - { - RelativeSizeAxes = Axes.X, - Height = 60, - Alpha = 0, - }); - i++; - } - } - best.ShowMore(); } - } - public IEnumerable<Score> ScoresFirst - { - set + public ScoreContainer(ScoreType type, string header, bool includeWeigth = false) { - first.Clear(); - if (!value.Any()) - { - firstMissing.Show(); - } - else - { - firstMissing.Hide(); - foreach (Score score in value) - first.Add(new DrawableScore(score) - { - RelativeSizeAxes = Axes.X, - Height = 60, - Alpha = 0, - }); - } - first.ShowMore(); - } - } + this.type = type; + this.includeWeigth = includeWeigth; - public class ScoreFlowContainer : Container<DrawableScore> - { - private FillFlowContainer<DrawableScore> scores; - private OsuClickableContainer showMoreText; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Direction = FillDirection.Vertical; - protected override Container<DrawableScore> Content => scores; - - protected override void LoadComplete() - { - InternalChild = new FillFlowContainer + Children = new Drawable[] { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new OsuSpriteText { - scores = new FillFlowContainer<DrawableScore> - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - }, + TextSize = 15, + Text = header, + Font = "Exo2.0-RegularItalic", + Margin = new MarginPadding { Top = 10, Bottom = 10 }, }, - }; - } - - public override void Clear(bool disposeChildren) - { - base.Clear(disposeChildren); - if (showMoreText == null) - ((FillFlowContainer)InternalChild).Add(showMoreText = new OsuHoverContainer + scoreContainer = new FillFlowContainer<DrawableScore> { - Action = ShowMore, + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + }, + showMoreButton = new OsuHoverContainer + { + Alpha = 0, + Action = showMore, AutoSizeAxes = Axes.Both, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -209,12 +126,57 @@ namespace osu.Game.Overlays.Profile.Sections TextSize = 14, Text = "show more", } - }); - else - showMoreText.Show(); + }, + showMoreLoading = new LoadingAnimation + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Size = new Vector2(14), + }, + missing = new OsuSpriteText + { + TextSize = 14, + Text = "No awesome performance records yet. :(", + }, + }; } - public void ShowMore() => showMoreText.Alpha = Children.Where(d => !d.IsPresent).Where((d, i) => (d.Alpha = i < 5 ? 1 : 0) == 0).Any() ? 1 : 0; + [BackgroundDependencyLoader] + private void load(APIAccess api, RulesetStore rulesets) + { + this.api = api; + this.rulesets = rulesets; + } + + private void showMore() + { + var req = new GetUserScoresRequest(user.Id, type, visiblePages++ * 5); + + showMoreLoading.Show(); + showMoreButton.Hide(); + + req.Success += scores => + { + foreach (var s in scores) + s.ApplyRuleset(rulesets.GetRuleset(s.OnlineRulesetID)); + + showMoreButton.FadeTo(scores.Count == 5 ? 1 : 0); + showMoreLoading.Hide(); + + if (scores.Any()) + { + missing.Hide(); + foreach (Score score in scores) + scoreContainer.Add(new DrawableScore(score, includeWeigth ? Math.Pow(0.95, scoreContainer.Count) : -1) + { + RelativeSizeAxes = Axes.X, + Height = 60, + }); + } + }; + + Schedule(() => { api.Queue(req); }); + } } } } diff --git a/osu.Game/Tests/Visual/TestCaseUserRanks.cs b/osu.Game/Tests/Visual/TestCaseUserRanks.cs index 41f3a37e94..e164426a4e 100644 --- a/osu.Game/Tests/Visual/TestCaseUserRanks.cs +++ b/osu.Game/Tests/Visual/TestCaseUserRanks.cs @@ -8,28 +8,28 @@ using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Overlays.Profile.Sections; +using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Scoring; +using osu.Game.Users; using System; using System.Collections.Generic; -namespace osu.Desktop.Tests.Visual +namespace osu.Game.Tests.Visual { - internal class TestCaseUserRanks : TestCase + internal class TestCaseUserRanks : OsuTestCase { public override string Description => "showing your latest achievements"; - protected override void LoadComplete() - { - base.LoadComplete(); + public override IReadOnlyList<Type> RequiredTypes => new Type[] { typeof(DrawableScore), typeof(RanksSection) }; + public TestCaseUserRanks() + { RanksSection ranks; Add(new Container { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Both, Children = new Drawable[] { new Box @@ -37,64 +37,15 @@ namespace osu.Desktop.Tests.Visual RelativeSizeAxes = Axes.Both, Colour = OsuColour.Gray(0.2f) }, - ranks = new RanksSection(), - } - }); - - AddStep("Add Best Performances", () => - { - List<Score> scores = new List<Score>(); - Mod[] availableMods = { new OsuModHidden(), new OsuModFlashlight(), new OsuModHardRock(), new OsuModDoubleTime(), new OsuModPerfect() }; - List<Mod> selectedMods = new List<Mod>(availableMods); - for (int i = 0; i <= availableMods.Length; i++) - { - scores.Add(new Score + new ScrollContainer { - Rank = (ScoreRank) Enum.GetValues(typeof(ScoreRank)).GetValue(Enum.GetValues(typeof(ScoreRank)).Length - 1 - i), - Accuracy = Math.Pow(0.99, i), - PP = Math.Pow(0.5, i) * 800, - Date = DateTimeOffset.UtcNow.AddDays(-Math.Pow(i, 2)), - Mods = selectedMods.ToArray(), - Beatmap = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Title = "Highscore", - Artist = "Panda Eyes & Teminite" - }, - Version = "Game Over", - OnlineBeatmapID = 736215, - } - }); - if(i < availableMods.Length) - selectedMods.Remove(availableMods[i]); - } - ranks.ScoresBest = scores.ToArray(); - }); - - AddStep("Add First Place", () => ranks.ScoresFirst = new[] - { - new Score - { - Rank = ScoreRank.A, - Accuracy = 0.735, - PP = 666, - Date = DateTimeOffset.UtcNow, - Mods = new Mod[] { new ModAutoplay(), new ModDoubleTime(), new OsuModEasy() }, - Beatmap = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Title = "FREEDOM DiVE", - Artist = "xi" - }, - Version = "FOUR DIMENSIONS", - OnlineBeatmapID = 129891, - } + RelativeSizeAxes = Axes.Both, + Child = ranks = new RanksSection(), + }, } }); - AddStep("Show More", ((RanksSection.ScoreFlowContainer)ranks.Children[1]).ShowMore); + AddStep("Show cookiezi", () => ranks.User = new User { Id = 124493 }); } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 7a78ed8dd4..a20a5ee13f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -298,7 +298,6 @@ <Compile Include="Graphics\Containers\OsuFocusedOverlayContainer.cs" /> <Compile Include="Graphics\Containers\OsuHoverContainer.cs" /> <Compile Include="Graphics\Containers\OsuScrollContainer.cs" /> - <Compile Include="Graphics\Containers\SectionsContainer.cs" /> <Compile Include="Graphics\Containers\OsuTextFlowContainer.cs" /> <Compile Include="Graphics\Containers\ParallaxContainer.cs" /> <Compile Include="Graphics\Containers\ReverseChildIDFillFlowContainer.cs" /> @@ -318,7 +317,6 @@ <Compile Include="Graphics\UserInterface\DialogButton.cs" /> <Compile Include="Graphics\UserInterface\FocusedTextBox.cs" /> <Compile Include="Graphics\UserInterface\IconButton.cs" /> - <Compile Include="Graphics\UserInterface\ProgressBar.cs" /> <Compile Include="Graphics\UserInterface\LineGraph.cs" /> <Compile Include="Graphics\UserInterface\LoadingAnimation.cs" /> <Compile Include="Graphics\UserInterface\MenuItemType.cs" />