From b947e89a6b11946110ec66709657fc70bfbe73ec Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 28 Jan 2020 16:53:22 +0300 Subject: [PATCH 01/41] Add placeholder for no comments case in CommentsContainer --- .../Online/TestSceneCommentsContainer.cs | 1 + .../Overlays/Comments/CommentsContainer.cs | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 3d63e2b07e..2af191945c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -48,6 +48,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Airman comments", () => comments.ShowComments(CommentableType.Beatmapset, 24313)); AddStep("Lazer build comments", () => comments.ShowComments(CommentableType.Build, 4772)); AddStep("News comments", () => comments.ShowComments(CommentableType.NewsPost, 715)); + AddStep("Beatmap with no comments", () => comments.ShowComments(CommentableType.Beatmapset, 1291)); AddStep("Idle state", () => { scroll.Clear(); diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 78df73eb0d..fd5c390f0f 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -12,6 +12,7 @@ using osu.Game.Online.API.Requests.Responses; using System.Threading; using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.Comments { @@ -34,6 +35,7 @@ namespace osu.Game.Overlays.Comments private DeletedChildrenPlaceholder deletedChildrenPlaceholder; private CommentsShowMoreButton moreButton; private TotalCommentsCounter commentCounter; + private Container noCommentsPlaceholder; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -60,6 +62,27 @@ namespace osu.Game.Overlays.Comments Sort = { BindTarget = Sort }, ShowDeleted = { BindTarget = ShowDeleted } }, + noCommentsPlaceholder = new Container + { + Height = 80, + RelativeSizeAxes = Axes.X, + Alpha = 0, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background4 + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 50 }, + Text = @"No comments yet." + } + } + }, content = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -68,6 +91,7 @@ namespace osu.Game.Overlays.Comments }, new Container { + Name = @"Footer", RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Children = new Drawable[] @@ -154,12 +178,21 @@ namespace osu.Game.Overlays.Comments { currentPage = 1; deletedChildrenPlaceholder.DeletedCount.Value = 0; + moreButton.Show(); moreButton.IsLoading = true; content.Clear(); + noCommentsPlaceholder.Hide(); } private void onSuccess(CommentBundle response) { + if (!response.Comments.Any()) + { + noCommentsPlaceholder.Show(); + moreButton.Hide(); + return; + } + loadCancellation = new CancellationTokenSource(); var page = new FillFlowContainer From c5e0c77bcadb98cd252684dcb5adbb6c4fff9886 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 06:08:11 +0300 Subject: [PATCH 02/41] Refactor NoCommentsPlaceholder --- .../Online/TestSceneCommentsContainer.cs | 2 +- .../Overlays/Comments/CommentsContainer.cs | 50 ++++++++++--------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 2af191945c..c81e850cc9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Airman comments", () => comments.ShowComments(CommentableType.Beatmapset, 24313)); AddStep("Lazer build comments", () => comments.ShowComments(CommentableType.Build, 4772)); AddStep("News comments", () => comments.ShowComments(CommentableType.NewsPost, 715)); - AddStep("Beatmap with no comments", () => comments.ShowComments(CommentableType.Beatmapset, 1291)); + AddStep("Beatmap with no comments", () => comments.ShowComments(CommentableType.Beatmapset, 1288)); AddStep("Idle state", () => { scroll.Clear(); diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index fd5c390f0f..6abb85088f 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -35,7 +35,6 @@ namespace osu.Game.Overlays.Comments private DeletedChildrenPlaceholder deletedChildrenPlaceholder; private CommentsShowMoreButton moreButton; private TotalCommentsCounter commentCounter; - private Container noCommentsPlaceholder; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -62,27 +61,6 @@ namespace osu.Game.Overlays.Comments Sort = { BindTarget = Sort }, ShowDeleted = { BindTarget = ShowDeleted } }, - noCommentsPlaceholder = new Container - { - Height = 80, - RelativeSizeAxes = Axes.X, - Alpha = 0, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background4 - }, - new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 50 }, - Text = @"No comments yet." - } - } - }, content = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -181,14 +159,13 @@ namespace osu.Game.Overlays.Comments moreButton.Show(); moreButton.IsLoading = true; content.Clear(); - noCommentsPlaceholder.Hide(); } private void onSuccess(CommentBundle response) { if (!response.Comments.Any()) { - noCommentsPlaceholder.Show(); + content.Add(new NoCommentsPlaceholder()); moreButton.Hide(); return; } @@ -240,5 +217,30 @@ namespace osu.Game.Overlays.Comments loadCancellation?.Cancel(); base.Dispose(isDisposing); } + + private class NoCommentsPlaceholder : CompositeDrawable + { + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Height = 80; + RelativeSizeAxes = Axes.X; + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background4 + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 50 }, + Text = @"No comments yet." + } + }); + } + } } } From e7964023aed0a6d8eeebd6762de8e6e6aff04ad1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 06:22:08 +0300 Subject: [PATCH 03/41] Implement CommentsPage class --- .../Overlays/Comments/CommentsContainer.cs | 54 +------------ osu.Game/Overlays/Comments/CommentsPage.cs | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 51 deletions(-) create mode 100644 osu.Game/Overlays/Comments/CommentsPage.cs diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 6abb85088f..0e307d4d0d 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -12,7 +12,6 @@ using osu.Game.Online.API.Requests.Responses; using System.Threading; using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.Comments { @@ -163,34 +162,12 @@ namespace osu.Game.Overlays.Comments private void onSuccess(CommentBundle response) { - if (!response.Comments.Any()) - { - content.Add(new NoCommentsPlaceholder()); - moreButton.Hide(); - return; - } - loadCancellation = new CancellationTokenSource(); - var page = new FillFlowContainer + LoadComponentAsync(new CommentsPage(response) { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - }; - - foreach (var c in response.Comments) - { - if (c.IsTopLevel) - { - page.Add(new DrawableComment(c) - { - ShowDeleted = { BindTarget = ShowDeleted } - }); - } - } - - LoadComponentAsync(page, loaded => + ShowDeleted = { BindTarget = ShowDeleted } + }, loaded => { content.Add(loaded); @@ -217,30 +194,5 @@ namespace osu.Game.Overlays.Comments loadCancellation?.Cancel(); base.Dispose(isDisposing); } - - private class NoCommentsPlaceholder : CompositeDrawable - { - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - Height = 80; - RelativeSizeAxes = Axes.X; - AddRangeInternal(new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background4 - }, - new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 50 }, - Text = @"No comments yet." - } - }); - } - } } } diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs new file mode 100644 index 0000000000..1bc9c89dfc --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -0,0 +1,76 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Bindables; +using osu.Game.Online.API.Requests.Responses; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Sprites; +using System.Linq; + +namespace osu.Game.Overlays.Comments +{ + public class CommentsPage : FillFlowContainer + { + public readonly BindableBool ShowDeleted = new BindableBool(); + + private readonly CommentBundle commentBundle; + + public CommentsPage(CommentBundle commentBundle) + { + this.commentBundle = commentBundle; + } + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Direction = FillDirection.Vertical; + + if (!commentBundle.Comments.Any()) + { + Add(new NoCommentsPlaceholder()); + return; + } + + foreach (var c in commentBundle.Comments) + { + if (c.IsTopLevel) + { + Add(new DrawableComment(c) + { + ShowDeleted = { BindTarget = ShowDeleted } + }); + } + } + } + + private class NoCommentsPlaceholder : CompositeDrawable + { + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Height = 80; + RelativeSizeAxes = Axes.X; + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background4 + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 50 }, + Text = @"No comments yet." + } + }); + } + } + } +} From dc10e58b4f1f4c4e39fa68ebefdf88f919855905 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 06:44:39 +0300 Subject: [PATCH 04/41] Add tests for CommentsPage --- .../Online/TestSceneCommentsContainer.cs | 3 +- .../Visual/Online/TestSceneCommentsPage.cs | 165 ++++++++++++++++++ .../Online/API/Requests/Responses/Comment.cs | 6 +- .../API/Requests/Responses/CommentBundle.cs | 20 ++- osu.Game/Overlays/Comments/DrawableComment.cs | 4 +- 5 files changed, 184 insertions(+), 14 deletions(-) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index c81e850cc9..c877176adf 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -25,7 +25,8 @@ namespace osu.Game.Tests.Visual.Online typeof(SortTabControl), typeof(ShowChildrenButton), typeof(DeletedChildrenPlaceholder), - typeof(VotePill) + typeof(VotePill), + typeof(CommentsPage), }; protected override bool UseOnlineAPI => true; diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs new file mode 100644 index 0000000000..706b1ca1ba --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs @@ -0,0 +1,165 @@ +// 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.Collections.Generic; +using osu.Game.Overlays.Comments; +using osu.Game.Overlays; +using osu.Framework.Allocation; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Users; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneCommentsPage : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(DrawableComment), + typeof(CommentsPage), + }; + + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + + private readonly BindableBool showDeleted = new BindableBool(); + private readonly Container content; + + public TestSceneCommentsPage() + { + AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new OsuCheckbox + { + Current = showDeleted, + LabelText = @"Show Deleted" + }, + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + } + } + } + }); + + AddStep("load comments", () => createPage(comment_bundle)); + AddStep("load empty comments", () => createPage(empty_comment_bundle)); + } + + private void createPage(CommentBundle commentBundle) + { + content.Clear(); + content.Add(new CommentsPage(commentBundle) + { + ShowDeleted = { BindTarget = showDeleted } + }); + } + + private static readonly CommentBundle empty_comment_bundle = new CommentBundle + { + Comments = new List(), + Total = 0, + }; + + private static readonly CommentBundle comment_bundle = new CommentBundle + { + Comments = new List + { + new Comment + { + Id = 1, + Message = "Simple test comment", + LegacyName = "TestUser1", + CreatedAt = DateTimeOffset.Now, + VotesCount = 5 + }, + new Comment + { + Id = 2, + Message = "This comment has been deleted :( but visible for admins", + LegacyName = "TestUser2", + CreatedAt = DateTimeOffset.Now, + DeletedAt = DateTimeOffset.Now, + VotesCount = 5 + }, + new Comment + { + Id = 3, + Message = "This comment is a top level", + LegacyName = "TestUser3", + CreatedAt = DateTimeOffset.Now, + RepliesCount = 2, + }, + new Comment + { + Id = 4, + ParentId = 3, + Message = "And this is a reply", + RepliesCount = 1, + LegacyName = "TestUser1", + CreatedAt = DateTimeOffset.Now, + }, + new Comment + { + Id = 15, + ParentId = 4, + Message = "Reply to reply", + LegacyName = "TestUser1", + CreatedAt = DateTimeOffset.Now, + }, + new Comment + { + Id = 6, + ParentId = 3, + LegacyName = "TestUser11515", + CreatedAt = DateTimeOffset.Now, + DeletedAt = DateTimeOffset.Now, + }, + new Comment + { + Id = 5, + Message = "This comment is voted and edited", + LegacyName = "BigBrainUser", + CreatedAt = DateTimeOffset.Now, + EditedAt = DateTimeOffset.Now, + VotesCount = 1000, + EditedById = 1, + } + }, + IncludedComments = new List(), + UserVotes = new List + { + 5 + }, + Users = new List + { + new User + { + Id = 1, + Username = "Good_Admin" + } + }, + TopLevelCount = 4, + Total = 7 + }; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 5510e9afff..3e38c3067b 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -6,8 +6,6 @@ using osu.Game.Users; using System; using System.Collections.Generic; using System.Linq; -using System.Net; -using System.Text.RegularExpressions; namespace osu.Game.Online.API.Requests.Responses { @@ -70,12 +68,10 @@ namespace osu.Game.Online.API.Requests.Responses public bool IsDeleted => DeletedAt.HasValue; - public bool HasMessage => !string.IsNullOrEmpty(MessageHtml); + public bool HasMessage => !string.IsNullOrEmpty(Message); public bool IsVoted { get; set; } - public string GetMessage => HasMessage ? WebUtility.HtmlDecode(Regex.Replace(MessageHtml, @"<(.|\n)*?>", string.Empty)) : string.Empty; - public int DeletedChildrenCount => ChildComments.Count(c => c.IsDeleted); } } diff --git a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs index 8db5d8d6ad..c3dc775bd0 100644 --- a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs +++ b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs @@ -47,17 +47,25 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"included_comments")] public List IncludedComments { get; set; } + private List userVotes; + [JsonProperty(@"user_votes")] - private List userVotes + public List UserVotes { - set => value.ForEach(v => + get => userVotes; + set { - Comments.ForEach(c => + userVotes = value; + + value.ForEach(v => { - if (v == c.Id) - c.IsVoted = true; + Comments.ForEach(c => + { + if (v == c.Id) + c.IsVoted = true; + }); }); - }); + } } private List users; diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index bdae9da226..d77ba5e298 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -213,7 +213,7 @@ namespace osu.Game.Overlays.Comments if (comment.HasMessage) { - var formattedSource = MessageFormatter.FormatText(comment.GetMessage); + var formattedSource = MessageFormatter.FormatText(comment.Message); message.AddLinks(formattedSource.Text, formattedSource.Links); } @@ -343,7 +343,7 @@ namespace osu.Game.Overlays.Comments if (parentComment == null) return string.Empty; - return parentComment.HasMessage ? parentComment.GetMessage : parentComment.IsDeleted ? @"deleted" : string.Empty; + return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? @"deleted" : string.Empty; } } } From 5fcda013469f133efb573496fd0a398c65621785 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 06:58:53 +0300 Subject: [PATCH 05/41] Cleanup pass --- .../Visual/Online/TestSceneCommentsPage.cs | 35 +++++++++---------- osu.Game/Overlays/Comments/CommentsPage.cs | 26 +++++++++++--- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs index 706b1ca1ba..1217ce6b42 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs @@ -12,8 +12,7 @@ using osu.Game.Graphics.UserInterface; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; -using osu.Framework.Graphics.Shapes; -using osuTK.Graphics; +using osuTK; namespace osu.Game.Tests.Visual.Online { @@ -33,30 +32,28 @@ namespace osu.Game.Tests.Visual.Online public TestSceneCommentsPage() { - AddRange(new Drawable[] + Add(new FillFlowContainer { - new Box + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new Container { - new OsuCheckbox + AutoSizeAxes = Axes.Y, + Width = 200, + Child = new OsuCheckbox { Current = showDeleted, LabelText = @"Show Deleted" - }, - content = new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, } + }, + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, } } }); diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index 1bc9c89dfc..153ce676eb 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -12,7 +12,7 @@ using System.Linq; namespace osu.Game.Overlays.Comments { - public class CommentsPage : FillFlowContainer + public class CommentsPage : CompositeDrawable { public readonly BindableBool ShowDeleted = new BindableBool(); @@ -24,15 +24,31 @@ namespace osu.Game.Overlays.Comments } [BackgroundDependencyLoader] - private void load() + private void load(OverlayColourProvider colourProvider) { + FillFlowContainer flow; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Direction = FillDirection.Vertical; + + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background5 + }, + flow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + } + }); if (!commentBundle.Comments.Any()) { - Add(new NoCommentsPlaceholder()); + flow.Add(new NoCommentsPlaceholder()); return; } @@ -40,7 +56,7 @@ namespace osu.Game.Overlays.Comments { if (c.IsTopLevel) { - Add(new DrawableComment(c) + flow.Add(new DrawableComment(c) { ShowDeleted = { BindTarget = ShowDeleted } }); From 3d6e00095edc737f247b6a93e20b4608d0206b7b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 14:08:10 +0300 Subject: [PATCH 06/41] Remove useless test --- osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index c877176adf..de6f7fd29d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -49,7 +49,6 @@ namespace osu.Game.Tests.Visual.Online AddStep("Airman comments", () => comments.ShowComments(CommentableType.Beatmapset, 24313)); AddStep("Lazer build comments", () => comments.ShowComments(CommentableType.Build, 4772)); AddStep("News comments", () => comments.ShowComments(CommentableType.NewsPost, 715)); - AddStep("Beatmap with no comments", () => comments.ShowComments(CommentableType.Beatmapset, 1288)); AddStep("Idle state", () => { scroll.Clear(); From 786ed038683f49ebd105b7668da9b95007c4e6d1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 21:01:40 +0300 Subject: [PATCH 07/41] Update profile recent activities in line with the web design --- .../Online/TestSceneHistoricalSection.cs | 6 +- .../TestSceneUserProfileRecentSection.cs | 5 + .../Sections/BeatmapMetadataContainer.cs | 2 +- .../Profile/Sections/DrawableProfileRow.cs | 124 ------------------ .../Sections/Recent/DrawableRecentActivity.cs | 78 +++++++---- .../Profile/Sections/Recent/MedalIcon.cs | 3 +- .../PaginatedRecentActivityContainer.cs | 4 +- 7 files changed, 68 insertions(+), 154 deletions(-) delete mode 100644 osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index d3b037f499..5825bc72f7 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -4,10 +4,12 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Overlays; using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections.Historical; using osu.Game.Users; @@ -24,9 +26,11 @@ namespace osu.Game.Tests.Visual.Online typeof(HistoricalSection), typeof(PaginatedMostPlayedBeatmapContainer), typeof(DrawableMostPlayedBeatmap), - typeof(DrawableProfileRow) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + public TestSceneHistoricalSection() { HistoricalSection section; diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs index f022425bf6..532aaa9c92 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -12,6 +13,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays; using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections.Recent; @@ -28,6 +30,9 @@ namespace osu.Game.Tests.Visual.Online typeof(MedalIcon) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + public TestSceneUserProfileRecentSection() { Children = new Drawable[] diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs index 13b547eed3..67a976fe6f 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Profile.Sections { /// - /// Display artist/title/mapper information, commonly used as the left portion of a profile or score display row (see ). + /// Display artist/title/mapper information, commonly used as the left portion of a profile or score display row. /// public abstract class BeatmapMetadataContainer : OsuHoverContainer { diff --git a/osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs b/osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs deleted file mode 100644 index 03ee29d0c2..0000000000 --- a/osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs +++ /dev/null @@ -1,124 +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 osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Effects; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Overlays.Profile.Sections -{ - public abstract class DrawableProfileRow : Container - { - private const int fade_duration = 200; - - private Box underscoreLine; - private Box coloredBackground; - private Container background; - - /// - /// A visual element displayed to the left of content. - /// - protected abstract Drawable CreateLeftVisual(); - - protected FillFlowContainer LeftFlowContainer { get; private set; } - protected FillFlowContainer RightFlowContainer { get; private set; } - - protected override Container Content { get; } - - protected DrawableProfileRow() - { - RelativeSizeAxes = Axes.X; - Height = 60; - - Content = new Container - { - RelativeSizeAxes = Axes.Both, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Width = 0.97f, - }; - } - - [BackgroundDependencyLoader(true)] - private void load(OsuColour colour) - { - InternalChildren = new Drawable[] - { - background = new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 3, - Alpha = 0, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 1f), - Radius = 1f, - Colour = Color4.Black.Opacity(0.2f), - }, - Child = coloredBackground = new Box { RelativeSizeAxes = Axes.Both } - }, - Content, - underscoreLine = new Box - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.X, - Height = 1, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new[] - { - CreateLeftVisual(), - LeftFlowContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 10 }, - Direction = FillDirection.Vertical, - }, - } - }, - RightFlowContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Direction = FillDirection.Vertical, - }, - }; - - coloredBackground.Colour = underscoreLine.Colour = colour.Gray4; - } - - protected override bool OnClick(ClickEvent e) => true; - - protected override bool OnHover(HoverEvent e) - { - background.FadeIn(fade_duration, Easing.OutQuint); - underscoreLine.FadeOut(fade_duration, Easing.OutQuint); - return true; - } - - protected override void OnHoverLost(HoverLostEvent e) - { - background.FadeOut(fade_duration, Easing.OutQuint); - underscoreLine.FadeIn(fade_duration, Easing.OutQuint); - base.OnHoverLost(e); - } - } -} diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 4e856845ac..aef8044b12 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -14,7 +14,7 @@ using osu.Game.Online.Leaderboards; namespace osu.Game.Overlays.Profile.Sections.Recent { - public class DrawableRecentActivity : DrawableProfileRow + public class DrawableRecentActivity : CompositeDrawable { private IAPIProvider api; @@ -28,24 +28,55 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } [BackgroundDependencyLoader] - private void load(IAPIProvider api) + private void load(IAPIProvider api, OverlayColourProvider colourProvider) { this.api = api; - LeftFlowContainer.Padding = new MarginPadding { Left = 10, Right = 160 }; - - LeftFlowContainer.Add(content = new LinkFlowContainer + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + AddInternal(new GridContainer { - AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - }); - - RightFlowContainer.Add(new DrawableDate(activity.CreatedAt) - { - Font = OsuFont.GetFont(size: 13), - Colour = OsuColour.Gray(0xAA), - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Y, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Absolute, size: 40), + new Dimension(), + new Dimension(GridSizeMode.AutoSize) + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = createIcon().With(icon => + { + icon.Anchor = Anchor.Centre; + icon.Origin = Anchor.Centre; + }) + }, + content = new LinkFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + }, + new DrawableDate(activity.CreatedAt) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Colour = colourProvider.Foreground1, + } + } + } }); var formatted = createMessage(); @@ -53,36 +84,33 @@ namespace osu.Game.Overlays.Profile.Sections.Recent content.AddLinks(formatted.Text, formatted.Links); } - protected override Drawable CreateLeftVisual() + private Drawable createIcon() { switch (activity.Type) { case RecentActivityType.Rank: return new UpdateableRank(activity.ScoreRank) { - RelativeSizeAxes = Axes.Y, - Width = 60, + RelativeSizeAxes = Axes.X, + Height = 16, FillMode = FillMode.Fit, }; case RecentActivityType.Achievement: return new DelayedLoadWrapper(new MedalIcon(activity.Achievement.Slug) { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, }) { - RelativeSizeAxes = Axes.Y, - Width = 60, + RelativeSizeAxes = Axes.X, + Height = 20 }; default: - return new Container - { - RelativeSizeAxes = Axes.Y, - Width = 60, - FillMode = FillMode.Fit, - }; + return Empty(); } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs index 4563510046..0c1f8b2e92 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs @@ -23,8 +23,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent Child = sprite = new Sprite { - Height = 40, - Width = 40, + RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, }; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 3f9d4dc93e..7a9cce4675 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API; using System.Collections.Generic; +using osuTK; namespace osu.Game.Overlays.Profile.Sections.Recent { @@ -16,7 +17,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent public PaginatedRecentActivityContainer(Bindable user, string header, string missing) : base(user, header, missing) { - ItemsPerPage = 5; + ItemsPerPage = 10; + ItemsContainer.Spacing = new Vector2(0, 5); } protected override APIRequest> CreateRequest() => From d20c48d15146b1c5e69616bb71afbc6441ade761 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 00:53:05 +0300 Subject: [PATCH 08/41] Resolve possible UserVotes issues --- osu.Game/Online/API/Requests/Responses/CommentBundle.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs index c3dc775bd0..9b3ef8b6e5 100644 --- a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs +++ b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs @@ -57,14 +57,7 @@ namespace osu.Game.Online.API.Requests.Responses { userVotes = value; - value.ForEach(v => - { - Comments.ForEach(c => - { - if (v == c.Id) - c.IsVoted = true; - }); - }); + Comments.ForEach(c => c.IsVoted = value.Contains(c.Id)); } } From b2c501a4393751eb58cd220400688b5fd52f08dc Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 10:54:58 +0300 Subject: [PATCH 09/41] Adjust font size --- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index aef8044b12..b8b53f6ab6 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -16,6 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public class DrawableRecentActivity : CompositeDrawable { + private const int font_size = 14; + private IAPIProvider api; private readonly APIRecentActivity activity; @@ -62,7 +64,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent icon.Origin = Anchor.Centre; }) }, - content = new LinkFlowContainer + content = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: font_size)) { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, @@ -74,6 +76,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Colour = colourProvider.Foreground1, + Font = OsuFont.GetFont(size: font_size), } } } From 2f7076f91c15b21896a92c08b2c3c86969e13a35 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 11:16:58 +0300 Subject: [PATCH 10/41] Adjust icons size --- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index b8b53f6ab6..0387f79131 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent AutoSizeAxes = Axes.Y, ColumnDimensions = new[] { - new Dimension(GridSizeMode.Absolute, size: 40), + new Dimension(GridSizeMode.Absolute, size: 28), new Dimension(), new Dimension(GridSizeMode.AutoSize) }, @@ -95,8 +95,9 @@ namespace osu.Game.Overlays.Profile.Sections.Recent return new UpdateableRank(activity.ScoreRank) { RelativeSizeAxes = Axes.X, - Height = 16, + Height = 11, FillMode = FillMode.Fit, + Margin = new MarginPadding { Top = 2 } }; case RecentActivityType.Achievement: @@ -109,7 +110,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent }) { RelativeSizeAxes = Axes.X, - Height = 20 + Width = 0.5f, + Height = 18 }; default: From 29ba82ee448ecab176c603ea4582e0edf3021912 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 12:29:35 +0300 Subject: [PATCH 11/41] Apply different font styles for different content parts --- .../Sections/Recent/DrawableRecentActivity.cs | 80 ++++++++++++------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 0387f79131..e9377bb00b 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API; @@ -82,9 +83,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } }); - var formatted = createMessage(); - - content.AddLinks(formatted.Text, formatted.Links); + createMessage(); } private Drawable createIcon() @@ -119,81 +118,106 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } } - private string toAbsoluteUrl(string url) => $"{api.Endpoint}{url}"; + private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument; - private MessageFormatter.MessageFormatterResult createMessage() + private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular) + => OsuFont.GetFont(size: font_size, weight: fontWeight, italics: true); + + private void addUserLink() + => content.AddLink(activity.User?.Username, LinkAction.OpenUserProfile, getLinkArgument(activity.User?.Url), creationParameters: t => t.Font = getLinkFont(FontWeight.Bold)); + + private void addBeatmapLink() + => content.AddLink(activity.Beatmap?.Title, LinkAction.OpenBeatmap, getLinkArgument(activity.Beatmap?.Url), creationParameters: t => t.Font = getLinkFont()); + + private void addBeatmapsetLink() + => content.AddLink(activity.Beatmapset?.Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset?.Url), creationParameters: t => t.Font = getLinkFont()); + + private void addText(string text) + => content.AddText(text, t => t.Font = OsuFont.GetFont(size: font_size, weight: FontWeight.SemiBold)); + + private void createMessage() { - string userLinkTemplate() => $"[{toAbsoluteUrl(activity.User?.Url)} {activity.User?.Username}]"; - string beatmapLinkTemplate() => $"[{toAbsoluteUrl(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; - string beatmapsetLinkTemplate() => $"[{toAbsoluteUrl(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; - - string message; - switch (activity.Type) { case RecentActivityType.Achievement: - message = $"{userLinkTemplate()} unlocked the {activity.Achievement.Name} medal!"; + addUserLink(); + addText($" unlocked the \"{activity.Achievement.Name}\" medal!"); break; case RecentActivityType.BeatmapPlaycount: - message = $"{beatmapLinkTemplate()} has been played {activity.Count} times!"; + addBeatmapLink(); + addText($" has been played {activity.Count} times!"); break; case RecentActivityType.BeatmapsetApprove: - message = $"{beatmapsetLinkTemplate()} has been {activity.Approval.ToString().ToLowerInvariant()}!"; + addBeatmapsetLink(); + addText($" has been {activity.Approval.ToString().ToLowerInvariant()}!"); break; case RecentActivityType.BeatmapsetDelete: - message = $"{beatmapsetLinkTemplate()} has been deleted."; + addBeatmapsetLink(); + addText(" has been deleted."); break; case RecentActivityType.BeatmapsetRevive: - message = $"{beatmapsetLinkTemplate()} has been revived from eternal slumber by {userLinkTemplate()}."; + addBeatmapsetLink(); + addText(" has been revived from eternal slumber by "); + addUserLink(); break; case RecentActivityType.BeatmapsetUpdate: - message = $"{userLinkTemplate()} has updated the beatmap {beatmapsetLinkTemplate()}!"; + addUserLink(); + addText(" has updated the beatmap "); + addBeatmapsetLink(); break; case RecentActivityType.BeatmapsetUpload: - message = $"{userLinkTemplate()} has submitted a new beatmap {beatmapsetLinkTemplate()}!"; + addUserLink(); + addText(" has submitted a new beatmap "); + addBeatmapsetLink(); break; case RecentActivityType.Medal: // apparently this shouldn't exist look at achievement instead (https://github.com/ppy/osu-web/blob/master/resources/assets/coffee/react/profile-page/recent-activity.coffee#L111) - message = string.Empty; break; case RecentActivityType.Rank: - message = $"{userLinkTemplate()} achieved rank #{activity.Rank} on {beatmapLinkTemplate()} ({activity.Mode}!)"; + addUserLink(); + addText($" achieved rank #{activity.Rank} on "); + addBeatmapLink(); + addText($" ({activity.Mode}!)"); break; case RecentActivityType.RankLost: - message = $"{userLinkTemplate()} has lost first place on {beatmapLinkTemplate()} ({activity.Mode}!)"; + addUserLink(); + addText(" has lost first place on "); + addBeatmapLink(); + addText($" ({activity.Mode}!)"); break; case RecentActivityType.UserSupportAgain: - message = $"{userLinkTemplate()} has once again chosen to support osu! - thanks for your generosity!"; + addUserLink(); + addText(" has once again chosen to support osu! - thanks for your generosity!"); break; case RecentActivityType.UserSupportFirst: - message = $"{userLinkTemplate()} has become an osu!supporter - thanks for your generosity!"; + addUserLink(); + addText(" has become an osu!supporter - thanks for your generosity!"); break; case RecentActivityType.UserSupportGift: - message = $"{userLinkTemplate()} has received the gift of osu!supporter!"; + addUserLink(); + addText(" has received the gift of osu!supporter!"); break; case RecentActivityType.UsernameChange: - message = $"{activity.User?.PreviousUsername} has changed their username to {userLinkTemplate()}!"; + addText($"{activity.User?.PreviousUsername} has changed their username to "); + addUserLink(); break; default: - message = string.Empty; break; } - - return MessageFormatter.FormatText(message); } } } From a7a3372a984bd9ad79c3414a4e75d16d883df2b5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 13:01:40 +0300 Subject: [PATCH 12/41] Remove redundant empty switch section --- .../Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index e9377bb00b..d5bdcffeef 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -214,9 +214,6 @@ namespace osu.Game.Overlays.Profile.Sections.Recent addText($"{activity.User?.PreviousUsername} has changed their username to "); addUserLink(); break; - - default: - break; } } } From 3f62c40e709bd1ac2d66abe6f33578fa99ed8aec Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 13:55:50 +0300 Subject: [PATCH 13/41] Increase spacing --- .../Profile/Sections/Recent/PaginatedRecentActivityContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 7a9cce4675..a37f398272 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent : base(user, header, missing) { ItemsPerPage = 10; - ItemsContainer.Spacing = new Vector2(0, 5); + ItemsContainer.Spacing = new Vector2(0, 8); } protected override APIRequest> CreateRequest() => From 3002366e70281b1bc600c741239a529b114ae9f1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 13:56:19 +0300 Subject: [PATCH 14/41] Adjust mode part --- .../Requests/Responses/APIRecentActivity.cs | 31 ++++++++++++++++++- .../Sections/Recent/DrawableRecentActivity.cs | 4 +-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs index 8695d09570..92b520c36b 100644 --- a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs +++ b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs @@ -41,8 +41,37 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("count")] public int Count; + public string Mode { get; private set; } + [JsonProperty("mode")] - public string Mode; + private string mode + { + set + { + switch (value) + { + default: + Mode = value; + return; + + case "osu": + Mode = "osu!"; + return; + + case "mania": + Mode = "osu!mania"; + return; + + case "taiko": + Mode = "osu!taiko"; + return; + + case "fruits": + Mode = "osu!catch"; + return; + } + } + } [JsonProperty("beatmap")] public RecentActivityBeatmap Beatmap; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index d5bdcffeef..3f8ab93abd 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -185,14 +185,14 @@ namespace osu.Game.Overlays.Profile.Sections.Recent addUserLink(); addText($" achieved rank #{activity.Rank} on "); addBeatmapLink(); - addText($" ({activity.Mode}!)"); + addText($" ({activity.Mode})"); break; case RecentActivityType.RankLost: addUserLink(); addText(" has lost first place on "); addBeatmapLink(); - addText($" ({activity.Mode}!)"); + addText($" ({activity.Mode})"); break; case RecentActivityType.UserSupportAgain: From 3db4c11f29979057147f0e3589ed3009e917ec13 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 14:05:55 +0300 Subject: [PATCH 15/41] CI fix --- osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs index 92b520c36b..b416085217 100644 --- a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs +++ b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs @@ -41,7 +41,7 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("count")] public int Count; - public string Mode { get; private set; } + public string Mode; [JsonProperty("mode")] private string mode From 4a444face115c69cb95f8df0e538602a2cb0d94d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 31 Jan 2020 09:46:35 +0300 Subject: [PATCH 16/41] Change ShowMoreButton hide logic --- osu.Game/Overlays/Comments/CommentsContainer.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index d174c78666..8761b88b1e 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -181,10 +181,12 @@ namespace osu.Game.Overlays.Comments moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments; moreButton.IsLoading = false; } + else + { + moreButton.Hide(); + } commentCounter.Current.Value = response.Total; - - moreButton.FadeTo(response.HasMore ? 1 : 0); }, loadCancellation.Token); } From 3b5b799d60157ab47a7507ee3184365591d151c2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 31 Jan 2020 09:51:56 +0300 Subject: [PATCH 17/41] Adjust height of ShowMore button --- osu.Game/Graphics/UserInterface/ShowMoreButton.cs | 5 +++-- osu.Game/Overlays/Comments/CommentsShowMoreButton.cs | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs index 4931a6aed6..c9cd9f1158 100644 --- a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs +++ b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs @@ -40,13 +40,14 @@ namespace osu.Game.Graphics.UserInterface public ShowMoreButton() { - AutoSizeAxes = Axes.Both; + Height = 30; + Width = 140; } protected override Drawable CreateContent() => new CircularContainer { Masking = true, - Size = new Vector2(140, 30), + RelativeSizeAxes = Axes.Both, Children = new Drawable[] { background = new Box diff --git a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs index ab65c9c63a..d2ff7ecb1f 100644 --- a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs +++ b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs @@ -14,6 +14,8 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { + Height = 20; + IdleColour = colourProvider.Background2; HoverColour = colourProvider.Background1; ChevronIconColour = colourProvider.Foreground1; From a74d22d9e55a5fb76fcd4f55bc049ae4ee046b32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 1 Feb 2020 15:50:33 +0100 Subject: [PATCH 18/41] Extract beatmap stats test to separate scene --- .../SongSelect/TestSceneAdvancedStats.cs | 125 ++++++++++++++++++ .../SongSelect/TestSceneBeatmapDetails.cs | 28 ---- .../Screens/Select/Details/AdvancedStats.cs | 40 +++--- 3 files changed, 146 insertions(+), 47 deletions(-) create mode 100644 osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs new file mode 100644 index 0000000000..c08e974544 --- /dev/null +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs @@ -0,0 +1,125 @@ +// 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.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; +using osu.Game.Screens.Select.Details; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.SongSelect +{ + [System.ComponentModel.Description("Advanced beatmap statistics display")] + public class TestSceneAdvancedStats : OsuTestScene + { + private TestAdvancedStats advancedStats; + + [Resolved] + private RulesetStore rulesets { get; set; } + + [Resolved] + private OsuColour colours { get; set; } + + [SetUp] + public void Setup() => Schedule(() => Child = advancedStats = new TestAdvancedStats + { + Width = 500 + }); + + private BeatmapInfo exampleBeatmapInfo => new BeatmapInfo + { + RulesetID = 0, + Ruleset = rulesets.AvailableRulesets.First(), + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 7.2f, + DrainRate = 1, + OverallDifficulty = 5.7f, + ApproachRate = 3.5f + }, + StarDifficulty = 4.5f + }; + + [Test] + public void TestNoMod() + { + AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); + + AddStep("no mods selected", () => SelectedMods.Value = Array.Empty()); + + AddAssert("first bar text is Circle Size", () => advancedStats.ChildrenOfType().First().Text == "Circle Size"); + AddAssert("circle size bar is white", () => advancedStats.FirstValue.ModBar.AccentColour == Color4.White); + AddAssert("HP drain bar is white", () => advancedStats.HpDrain.ModBar.AccentColour == Color4.White); + AddAssert("accuracy bar is white", () => advancedStats.Accuracy.ModBar.AccentColour == Color4.White); + AddAssert("approach rate bar is white", () => advancedStats.ApproachRate.ModBar.AccentColour == Color4.White); + } + + [Test] + public void TestManiaFirstBarText() + { + AddStep("set beatmap", () => advancedStats.Beatmap = new BeatmapInfo + { + Ruleset = rulesets.GetRuleset(3), + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 5, + DrainRate = 4.3f, + OverallDifficulty = 4.5f, + ApproachRate = 3.1f + }, + StarDifficulty = 8 + }); + + AddAssert("first bar text is Key Count", () => advancedStats.ChildrenOfType().First().Text == "Key Count"); + } + + [Test] + public void TestEasyMod() + { + AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); + + AddStep("select EZ mod", () => + { + var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); + SelectedMods.Value = new[] { ruleset.GetAllMods().OfType().Single() }; + }); + + AddAssert("circle size bar is blue", () => advancedStats.FirstValue.ModBar.AccentColour == colours.BlueDark); + AddAssert("HP drain bar is blue", () => advancedStats.HpDrain.ModBar.AccentColour == colours.BlueDark); + AddAssert("accuracy bar is blue", () => advancedStats.Accuracy.ModBar.AccentColour == colours.BlueDark); + AddAssert("approach rate bar is blue", () => advancedStats.ApproachRate.ModBar.AccentColour == colours.BlueDark); + } + + [Test] + public void TestHardRockMod() + { + AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); + + AddStep("select HR mod", () => + { + var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); + SelectedMods.Value = new[] { ruleset.GetAllMods().OfType().Single() }; + }); + + AddAssert("circle size bar is red", () => advancedStats.FirstValue.ModBar.AccentColour == colours.Red); + AddAssert("HP drain bar is red", () => advancedStats.HpDrain.ModBar.AccentColour == colours.Red); + AddAssert("accuracy bar is red", () => advancedStats.Accuracy.ModBar.AccentColour == colours.Red); + AddAssert("approach rate bar is red", () => advancedStats.ApproachRate.ModBar.AccentColour == colours.Red); + } + + private class TestAdvancedStats : AdvancedStats + { + public new StatisticRow FirstValue => base.FirstValue; + public new StatisticRow HpDrain => base.HpDrain; + public new StatisticRow Accuracy => base.Accuracy; + public new StatisticRow ApproachRate => base.ApproachRate; + } + } +} diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs index 6aa5a76490..acf037198f 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs @@ -3,14 +3,8 @@ using System.Linq; using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Testing; using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; -using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; using osu.Game.Screens.Select; namespace osu.Game.Tests.Visual.SongSelect @@ -180,27 +174,5 @@ namespace osu.Game.Tests.Visual.SongSelect OnlineBeatmapID = 162, }); } - - [Resolved] - private RulesetStore rulesets { get; set; } - - [Resolved] - private OsuColour colours { get; set; } - - [Test] - public void TestModAdjustments() - { - TestAllMetrics(); - - Ruleset ruleset = rulesets.AvailableRulesets.First().CreateInstance(); - - AddStep("with EZ mod", () => SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModEasy) }); - - AddAssert("first bar coloured blue", () => details.ChildrenOfType().Skip(1).First().AccentColour == colours.BlueDark); - - AddStep("with HR mod", () => SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModHardRock) }); - - AddAssert("first bar coloured red", () => details.ChildrenOfType().Skip(1).First().AccentColour == colours.Red); - } } } diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 56c400e869..81f2b8dc7b 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -26,7 +26,8 @@ namespace osu.Game.Screens.Select.Details [Resolved] private IBindable> mods { get; set; } - private readonly StatisticRow firstValue, hpDrain, accuracy, approachRate, starDifficulty; + protected readonly StatisticRow FirstValue, HpDrain, Accuracy, ApproachRate; + private readonly StatisticRow starDifficulty; private BeatmapInfo beatmap; @@ -52,10 +53,10 @@ namespace osu.Game.Screens.Select.Details Spacing = new Vector2(4f), Children = new[] { - firstValue = new StatisticRow(), //circle size/key amount - hpDrain = new StatisticRow { Title = "HP Drain" }, - accuracy = new StatisticRow { Title = "Accuracy" }, - approachRate = new StatisticRow { Title = "Approach Rate" }, + FirstValue = new StatisticRow(), //circle size/key amount + HpDrain = new StatisticRow { Title = "HP Drain" }, + Accuracy = new StatisticRow { Title = "Accuracy" }, + ApproachRate = new StatisticRow { Title = "Approach Rate" }, starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" }, }, }; @@ -122,24 +123,24 @@ namespace osu.Game.Screens.Select.Details case 3: // Account for mania differences locally for now // Eventually this should be handled in a more modular way, allowing rulesets to return arbitrary difficulty attributes - firstValue.Title = "Key Count"; - firstValue.Value = (baseDifficulty?.CircleSize ?? 0, null); + FirstValue.Title = "Key Count"; + FirstValue.Value = (baseDifficulty?.CircleSize ?? 0, null); break; default: - firstValue.Title = "Circle Size"; - firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize); + FirstValue.Title = "Circle Size"; + FirstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize); break; } starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null); - hpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate); - accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty); - approachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate); + HpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate); + Accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty); + ApproachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate); } - private class StatisticRow : Container, IHasAccentColour + public class StatisticRow : Container, IHasAccentColour { private const float value_width = 25; private const float name_width = 70; @@ -147,7 +148,8 @@ namespace osu.Game.Screens.Select.Details private readonly float maxValue; private readonly bool forceDecimalPlaces; private readonly OsuSpriteText name, valueText; - private readonly Bar bar, modBar; + private readonly Bar bar; + public readonly Bar ModBar; [Resolved] private OsuColour colours { get; set; } @@ -173,14 +175,14 @@ namespace osu.Game.Screens.Select.Details bar.Length = value.baseValue / maxValue; valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##"); - modBar.Length = (value.adjustedValue ?? 0) / maxValue; + ModBar.Length = (value.adjustedValue ?? 0) / maxValue; if (value.adjustedValue > value.baseValue) - modBar.AccentColour = valueText.Colour = colours.Red; + ModBar.AccentColour = valueText.Colour = colours.Red; else if (value.adjustedValue < value.baseValue) - modBar.AccentColour = valueText.Colour = colours.BlueDark; + ModBar.AccentColour = valueText.Colour = colours.BlueDark; else - modBar.AccentColour = valueText.Colour = Color4.White; + ModBar.AccentColour = valueText.Colour = Color4.White; } } @@ -217,7 +219,7 @@ namespace osu.Game.Screens.Select.Details BackgroundColour = Color4.White.Opacity(0.5f), Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 }, }, - modBar = new Bar + ModBar = new Bar { Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, From e90ae667b7e2481ad867fabae6df1e1969064012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 1 Feb 2020 16:08:24 +0100 Subject: [PATCH 19/41] Add failing tests --- .../SongSelect/TestSceneAdvancedStats.cs | 76 +++++++++++++++---- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs index c08e974544..3d3517ada4 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs @@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.SongSelect BaseDifficulty = new BeatmapDifficulty { CircleSize = 7.2f, - DrainRate = 1, + DrainRate = 3, OverallDifficulty = 5.7f, ApproachRate = 3.5f }, @@ -55,10 +55,10 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("no mods selected", () => SelectedMods.Value = Array.Empty()); AddAssert("first bar text is Circle Size", () => advancedStats.ChildrenOfType().First().Text == "Circle Size"); - AddAssert("circle size bar is white", () => advancedStats.FirstValue.ModBar.AccentColour == Color4.White); - AddAssert("HP drain bar is white", () => advancedStats.HpDrain.ModBar.AccentColour == Color4.White); - AddAssert("accuracy bar is white", () => advancedStats.Accuracy.ModBar.AccentColour == Color4.White); - AddAssert("approach rate bar is white", () => advancedStats.ApproachRate.ModBar.AccentColour == Color4.White); + AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue)); + AddAssert("HP drain bar is white", () => barIsWhite(advancedStats.HpDrain)); + AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy)); + AddAssert("approach rate bar is white", () => barIsWhite(advancedStats.ApproachRate)); } [Test] @@ -91,10 +91,10 @@ namespace osu.Game.Tests.Visual.SongSelect SelectedMods.Value = new[] { ruleset.GetAllMods().OfType().Single() }; }); - AddAssert("circle size bar is blue", () => advancedStats.FirstValue.ModBar.AccentColour == colours.BlueDark); - AddAssert("HP drain bar is blue", () => advancedStats.HpDrain.ModBar.AccentColour == colours.BlueDark); - AddAssert("accuracy bar is blue", () => advancedStats.Accuracy.ModBar.AccentColour == colours.BlueDark); - AddAssert("approach rate bar is blue", () => advancedStats.ApproachRate.ModBar.AccentColour == colours.BlueDark); + AddAssert("circle size bar is blue", () => barIsBlue(advancedStats.FirstValue)); + AddAssert("HP drain bar is blue", () => barIsBlue(advancedStats.HpDrain)); + AddAssert("accuracy bar is blue", () => barIsBlue(advancedStats.Accuracy)); + AddAssert("approach rate bar is blue", () => barIsBlue(advancedStats.ApproachRate)); } [Test] @@ -108,12 +108,62 @@ namespace osu.Game.Tests.Visual.SongSelect SelectedMods.Value = new[] { ruleset.GetAllMods().OfType().Single() }; }); - AddAssert("circle size bar is red", () => advancedStats.FirstValue.ModBar.AccentColour == colours.Red); - AddAssert("HP drain bar is red", () => advancedStats.HpDrain.ModBar.AccentColour == colours.Red); - AddAssert("accuracy bar is red", () => advancedStats.Accuracy.ModBar.AccentColour == colours.Red); - AddAssert("approach rate bar is red", () => advancedStats.ApproachRate.ModBar.AccentColour == colours.Red); + AddAssert("circle size bar is red", () => barIsRed(advancedStats.FirstValue)); + AddAssert("HP drain bar is red", () => barIsRed(advancedStats.HpDrain)); + AddAssert("accuracy bar is red", () => barIsRed(advancedStats.Accuracy)); + AddAssert("approach rate bar is red", () => barIsRed(advancedStats.ApproachRate)); } + [Test] + public void TestUnchangedDifficultyAdjustMod() + { + AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); + + AddStep("select unchanged Difficulty Adjust mod", () => + { + var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); + var difficultyAdjustMod = ruleset.GetAllMods().OfType().Single(); + difficultyAdjustMod.ReadFromDifficulty(advancedStats.Beatmap.BaseDifficulty); + SelectedMods.Value = new[] { difficultyAdjustMod }; + }); + + AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue)); + AddAssert("HP drain bar is white", () => barIsWhite(advancedStats.HpDrain)); + AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy)); + AddAssert("approach rate bar is white", () => barIsWhite(advancedStats.ApproachRate)); + } + + [Test] + public void TestChangedDifficultyAdjustMod() + { + AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); + + AddStep("select changed Difficulty Adjust mod", () => + { + var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); + var difficultyAdjustMod = ruleset.GetAllMods().OfType().Single(); + var originalDifficulty = advancedStats.Beatmap.BaseDifficulty; + var adjustedDifficulty = new BeatmapDifficulty + { + CircleSize = originalDifficulty.CircleSize, + DrainRate = originalDifficulty.DrainRate - 0.5f, + OverallDifficulty = originalDifficulty.OverallDifficulty, + ApproachRate = originalDifficulty.ApproachRate + 2.2f, + }; + difficultyAdjustMod.ReadFromDifficulty(adjustedDifficulty); + SelectedMods.Value = new[] { difficultyAdjustMod }; + }); + + AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue)); + AddAssert("drain rate bar is blue", () => barIsBlue(advancedStats.HpDrain)); + AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy)); + AddAssert("approach rate bar is red", () => barIsRed(advancedStats.ApproachRate)); + } + + private bool barIsWhite(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == Color4.White; + private bool barIsBlue(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.BlueDark; + private bool barIsRed(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.Red; + private class TestAdvancedStats : AdvancedStats { public new StatisticRow FirstValue => base.FirstValue; From 0bfadfbbf1fbb713e10f252001285b43cbae6343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 1 Feb 2020 16:16:15 +0100 Subject: [PATCH 20/41] Apply precision when comparing adjusted values In some cases, applying the Difficulty Adjust mod without actually changing any of the settings previously caused the bar in song select beatmap details to appear red/blue instead of staying white. This was caused by not accounting for floating-point imprecisions when determining bar colour in AdvancedStats. To resolve, first check equality with tolerance, and only then apply blue/red colours if that equality check does not hold. --- osu.Game/Screens/Select/Details/AdvancedStats.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 81f2b8dc7b..7ab91677a9 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -16,6 +16,7 @@ using System.Collections.Generic; using osu.Game.Rulesets.Mods; using System.Linq; using osu.Framework.Threading; +using osu.Framework.Utils; using osu.Game.Configuration; using osu.Game.Overlays.Settings; @@ -177,12 +178,12 @@ namespace osu.Game.Screens.Select.Details valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##"); ModBar.Length = (value.adjustedValue ?? 0) / maxValue; - if (value.adjustedValue > value.baseValue) + if (Precision.AlmostEquals(value.baseValue, value.adjustedValue ?? value.baseValue, 0.05f)) + ModBar.AccentColour = valueText.Colour = Color4.White; + else if (value.adjustedValue > value.baseValue) ModBar.AccentColour = valueText.Colour = colours.Red; else if (value.adjustedValue < value.baseValue) ModBar.AccentColour = valueText.Colour = colours.BlueDark; - else - ModBar.AccentColour = valueText.Colour = Color4.White; } } From 9f4261111b3347719009e7ea21dff8c895791548 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sat, 1 Feb 2020 16:55:30 +0100 Subject: [PATCH 21/41] Match osu-stable behaviour and size --- .../Objects/Drawables/Pieces/SliderBall.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index ef7b077480..1fa27b6ff6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private readonly Slider slider; public readonly Drawable FollowCircle; + public readonly Drawable InternalFollowCircle; private readonly DrawableSlider drawableSlider; public SliderBall(Slider slider, DrawableSlider drawableSlider = null) @@ -38,6 +39,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Children = new[] { + InternalFollowCircle = new CircularContainer + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Alpha = 0 + }, FollowCircle = new FollowCircleContainer { Origin = Anchor.Centre, @@ -95,7 +103,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces tracking = value; - FollowCircle.ScaleTo(tracking ? 2f : 1, 300, Easing.OutQuint); + // Cursor input is checked against the internal circle, which scales instantly to match osu-stable behaviour + InternalFollowCircle.ScaleTo(tracking ? 2.4f : 1f); + FollowCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint); FollowCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint); } } @@ -149,7 +159,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces // in valid time range Time.Current >= slider.StartTime && Time.Current < slider.EndTime && // in valid position range - lastScreenSpaceMousePosition.HasValue && FollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && + lastScreenSpaceMousePosition.HasValue && InternalFollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && // valid action (actions?.Any(isValidTrackingAction) ?? false); } From 36116f8c45f06ffa0256f6e2ba53a67182a74753 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 2 Feb 2020 12:03:51 +0300 Subject: [PATCH 22/41] Refactor ruleset presentation --- .../TestSceneUserProfileRecentSection.cs | 16 ++++++++++ .../Requests/Responses/APIRecentActivity.cs | 31 +------------------ .../Sections/Recent/DrawableRecentActivity.cs | 26 ++++++++++++---- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs index 532aaa9c92..06091f3c81 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs @@ -136,6 +136,22 @@ namespace osu.Game.Tests.Visual.Online Beatmap = dummyBeatmap, }, new APIRecentActivity + { + User = dummyUser, + Type = RecentActivityType.Rank, + Rank = 1, + Mode = "vitaru", + Beatmap = dummyBeatmap, + }, + new APIRecentActivity + { + User = dummyUser, + Type = RecentActivityType.Rank, + Rank = 1, + Mode = "fruits", + Beatmap = dummyBeatmap, + }, + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.RankLost, diff --git a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs index b416085217..8695d09570 100644 --- a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs +++ b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs @@ -41,37 +41,8 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("count")] public int Count; - public string Mode; - [JsonProperty("mode")] - private string mode - { - set - { - switch (value) - { - default: - Mode = value; - return; - - case "osu": - Mode = "osu!"; - return; - - case "mania": - Mode = "osu!mania"; - return; - - case "taiko": - Mode = "osu!taiko"; - return; - - case "fruits": - Mode = "osu!catch"; - return; - } - } - } + public string Mode; [JsonProperty("beatmap")] public RecentActivityBeatmap Beatmap; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 3f8ab93abd..5a315b59b4 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.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.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,6 +13,7 @@ using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Online.Leaderboards; +using osu.Game.Rulesets; namespace osu.Game.Overlays.Profile.Sections.Recent { @@ -19,7 +21,11 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { private const int font_size = 14; - private IAPIProvider api; + [Resolved] + private IAPIProvider api { get; set; } + + [Resolved] + private RulesetStore rulesets { get; set; } private readonly APIRecentActivity activity; @@ -31,10 +37,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } [BackgroundDependencyLoader] - private void load(IAPIProvider api, OverlayColourProvider colourProvider) + private void load(OverlayColourProvider colourProvider) { - this.api = api; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; AddInternal(new GridContainer @@ -118,6 +122,16 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } } + private string getRulesetName() + { + var shortName = activity.Mode; + + if (rulesets.AvailableRulesets.Select(r => r.ShortName).Contains(shortName)) + return rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == shortName).Name; + + return shortName; + } + private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument; private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular) @@ -185,14 +199,14 @@ namespace osu.Game.Overlays.Profile.Sections.Recent addUserLink(); addText($" achieved rank #{activity.Rank} on "); addBeatmapLink(); - addText($" ({activity.Mode})"); + addText($" ({getRulesetName()})"); break; case RecentActivityType.RankLost: addUserLink(); addText(" has lost first place on "); addBeatmapLink(); - addText($" ({activity.Mode})"); + addText($" ({getRulesetName()})"); break; case RecentActivityType.UserSupportAgain: From a70385f2b26058cec6da3d7ebb7d150cbe54967c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 2 Feb 2020 12:19:09 +0300 Subject: [PATCH 23/41] Simplify getRulesetName --- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 5a315b59b4..f538833eb0 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -126,10 +126,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { var shortName = activity.Mode; - if (rulesets.AvailableRulesets.Select(r => r.ShortName).Contains(shortName)) - return rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == shortName).Name; - - return shortName; + return rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == shortName)?.Name ?? shortName; } private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument; From e2589b2dcb6cdaaef86485ce04484635c7d0ed92 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 11:24:28 +0100 Subject: [PATCH 24/41] Rename drawable --- .../Objects/Drawables/Pieces/SliderBall.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index 1fa27b6ff6..4599044912 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private readonly Slider slider; public readonly Drawable FollowCircle; - public readonly Drawable InternalFollowCircle; + public readonly Drawable TrackingArea; private readonly DrawableSlider drawableSlider; public SliderBall(Slider slider, DrawableSlider drawableSlider = null) @@ -39,7 +39,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Children = new[] { - InternalFollowCircle = new CircularContainer + // This is separate from the visible followcircle to ensure consistent internal tracking area (needed to match osu-stable) + TrackingArea = new CircularContainer { Origin = Anchor.Centre, Anchor = Anchor.Centre, @@ -103,8 +104,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces tracking = value; - // Cursor input is checked against the internal circle, which scales instantly to match osu-stable behaviour - InternalFollowCircle.ScaleTo(tracking ? 2.4f : 1f); + // Tracking area is bigger than the visible followcircle and scales instantly to match osu-stable + TrackingArea.ScaleTo(tracking ? 2.4f : 1f); FollowCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint); FollowCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint); } @@ -159,7 +160,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces // in valid time range Time.Current >= slider.StartTime && Time.Current < slider.EndTime && // in valid position range - lastScreenSpaceMousePosition.HasValue && InternalFollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && + lastScreenSpaceMousePosition.HasValue && TrackingArea.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && // valid action (actions?.Any(isValidTrackingAction) ?? false); } From 52aae684116fbed2109b168dcb2a534da491fb88 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 17:52:34 +0700 Subject: [PATCH 25/41] Adjust profile scores to closer match osu-web --- .../Profile/Sections/Ranks/DrawableProfileScore.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 5196bef48d..13f4d9a3a5 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -23,7 +23,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks public class DrawableProfileScore : CompositeDrawable { private const int performance_width = 80; - private const int content_padding = 10; + private const int content_padding_left = 10; + private const int content_padding_right = 30; protected readonly ScoreInfo Score; @@ -51,7 +52,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = content_padding, Right = performance_width + content_padding }, + Padding = new MarginPadding { Left = content_padding_left, Right = performance_width + content_padding_right }, Children = new Drawable[] { new FillFlowContainer @@ -142,17 +143,21 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { new Box { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Both, - Size = new Vector2(1, 0.5f), + Size = new Vector2(1.06f, 0.5f), Colour = Color4.Black.Opacity(0.5f), Shear = new Vector2(-0.45f, 0), EdgeSmoothness = new Vector2(2, 0), }, new Box { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Both, RelativePositionAxes = Axes.Y, - Size = new Vector2(1, -0.5f), + Size = new Vector2(1.06f, -0.5f), Position = new Vector2(0, 1), Colour = Color4.Black.Opacity(0.5f), Shear = new Vector2(0.45f, 0), From f7abfdb40e8fcea47b3ddfc8bb33550f9bc60ba7 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 14:33:48 +0100 Subject: [PATCH 26/41] Remove unnecessary parameter --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index 4599044912..a81ac3f4ff 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.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; @@ -44,8 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { Origin = Anchor.Centre, Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Alpha = 0 + RelativeSizeAxes = Axes.Both }, FollowCircle = new FollowCircleContainer { From 35032e2ddd1b0d76bd1615c25dd17de7cd3cee10 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 14:34:06 +0100 Subject: [PATCH 27/41] Make variables private --- .../Objects/Drawables/Pieces/SliderBall.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index a81ac3f4ff..b89b0cafc4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.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; @@ -23,8 +23,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces public Func GetInitialHitAction; private readonly Slider slider; - public readonly Drawable FollowCircle; - public readonly Drawable TrackingArea; + private readonly Drawable followCircle; + private readonly Drawable trackingArea; private readonly DrawableSlider drawableSlider; public SliderBall(Slider slider, DrawableSlider drawableSlider = null) @@ -40,13 +40,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Children = new[] { // This is separate from the visible followcircle to ensure consistent internal tracking area (needed to match osu-stable) - TrackingArea = new CircularContainer + trackingArea = new CircularContainer { Origin = Anchor.Centre, Anchor = Anchor.Centre, RelativeSizeAxes = Axes.Both }, - FollowCircle = new FollowCircleContainer + followCircle = new FollowCircleContainer { Origin = Anchor.Centre, Anchor = Anchor.Centre, @@ -104,9 +104,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces tracking = value; // Tracking area is bigger than the visible followcircle and scales instantly to match osu-stable - TrackingArea.ScaleTo(tracking ? 2.4f : 1f); - FollowCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint); - FollowCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint); + trackingArea.ScaleTo(tracking ? 2.4f : 1f); + followCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint); + followCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint); } } @@ -159,7 +159,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces // in valid time range Time.Current >= slider.StartTime && Time.Current < slider.EndTime && // in valid position range - lastScreenSpaceMousePosition.HasValue && TrackingArea.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && + lastScreenSpaceMousePosition.HasValue && trackingArea.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && // valid action (actions?.Any(isValidTrackingAction) ?? false); } From 122fd63ac467912b80ffea3d9d1d90637ba47dcc Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 21:05:20 +0700 Subject: [PATCH 28/41] Inline single-use constants --- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 13f4d9a3a5..7400bed04e 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.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.Linq; @@ -23,8 +23,6 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks public class DrawableProfileScore : CompositeDrawable { private const int performance_width = 80; - private const int content_padding_left = 10; - private const int content_padding_right = 30; protected readonly ScoreInfo Score; @@ -52,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = content_padding_left, Right = performance_width + content_padding_right }, + Padding = new MarginPadding { Left = 10, Right = performance_width + 30 }, Children = new Drawable[] { new FillFlowContainer From a641069ec2b9ef3b7f47da143084facfecaaa719 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 21:07:23 +0700 Subject: [PATCH 29/41] Change profile score background colour --- osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs | 4 ++-- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs index 717ec4fb1a..f65c909155 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs @@ -44,8 +44,8 @@ namespace osu.Game.Overlays.Profile.Sections [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - background.Colour = idleColour = colourProvider.Background4; - hoverColour = colourProvider.Background3; + background.Colour = idleColour = colourProvider.Background3; + hoverColour = colourProvider.Background2; } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 7400bed04e..55ed80cc04 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.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.Linq; @@ -145,7 +145,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Both, Size = new Vector2(1.06f, 0.5f), - Colour = Color4.Black.Opacity(0.5f), + Colour = colourProvider.Background4, Shear = new Vector2(-0.45f, 0), EdgeSmoothness = new Vector2(2, 0), }, @@ -157,7 +157,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks RelativePositionAxes = Axes.Y, Size = new Vector2(1.06f, -0.5f), Position = new Vector2(0, 1), - Colour = Color4.Black.Opacity(0.5f), + Colour = colourProvider.Background4, Shear = new Vector2(0.45f, 0), EdgeSmoothness = new Vector2(2, 0), }, From 79efcbd6f315c4cc6e6d723d09f544d75838dde7 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 21:08:16 +0700 Subject: [PATCH 30/41] Fix performance background width --- .../Sections/Ranks/DrawableProfileScore.cs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 55ed80cc04..07a85be041 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.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 System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -16,14 +16,16 @@ using osu.Game.Online.Leaderboards; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Sections.Ranks { public class DrawableProfileScore : CompositeDrawable { + private const int height = 40; private const int performance_width = 80; + private const float performance_background_shear = 0.45f; + protected readonly ScoreInfo Score; [Resolved] @@ -37,12 +39,14 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Score = score; RelativeSizeAxes = Axes.X; - Height = 40; + Height = height; } [BackgroundDependencyLoader] private void load() { + float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); + AddInternal(new ProfileItemContainer { Children = new Drawable[] @@ -143,22 +147,24 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.Both, - Size = new Vector2(1.06f, 0.5f), + RelativeSizeAxes = Axes.Y, + Width = performance_background_width, + Height = 0.5f, Colour = colourProvider.Background4, - Shear = new Vector2(-0.45f, 0), + Shear = new Vector2(-performance_background_shear, 0), EdgeSmoothness = new Vector2(2, 0), }, new Box { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.Y, RelativePositionAxes = Axes.Y, - Size = new Vector2(1.06f, -0.5f), + Width = performance_background_width, + Height = -0.5f, Position = new Vector2(0, 1), Colour = colourProvider.Background4, - Shear = new Vector2(0.45f, 0), + Shear = new Vector2(performance_background_shear, 0), EdgeSmoothness = new Vector2(2, 0), }, createDrawablePerformance().With(d => From aa13b605a4877458470173f33ddd0946b26a781a Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 21:34:35 +0700 Subject: [PATCH 31/41] Fix inconsistent local variable naming --- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 07a85be041..930f9b8a43 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks [BackgroundDependencyLoader] private void load() { - float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); + float performanceBackgroundWidth = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); AddInternal(new ProfileItemContainer { @@ -148,7 +148,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, - Width = performance_background_width, + Width = performanceBackgroundWidth, Height = 0.5f, Colour = colourProvider.Background4, Shear = new Vector2(-performance_background_shear, 0), @@ -160,7 +160,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, RelativePositionAxes = Axes.Y, - Width = performance_background_width, + Width = performanceBackgroundWidth, Height = -0.5f, Position = new Vector2(0, 1), Colour = colourProvider.Background4, From 0a186fe7229380551c663cb828f299bb6634a5b3 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 22:37:58 +0700 Subject: [PATCH 32/41] Avoid calculating constants in load() --- .../Profile/Sections/Ranks/DrawableProfileScore.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 930f9b8a43..1905728442 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -25,6 +25,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks private const int performance_width = 80; private const float performance_background_shear = 0.45f; + private float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); protected readonly ScoreInfo Score; @@ -45,8 +46,6 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks [BackgroundDependencyLoader] private void load() { - float performanceBackgroundWidth = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); - AddInternal(new ProfileItemContainer { Children = new Drawable[] @@ -148,7 +147,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, - Width = performanceBackgroundWidth, + Width = performance_background_width, Height = 0.5f, Colour = colourProvider.Background4, Shear = new Vector2(-performance_background_shear, 0), @@ -160,7 +159,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, RelativePositionAxes = Axes.Y, - Width = performanceBackgroundWidth, + Width = performance_background_width, Height = -0.5f, Position = new Vector2(0, 1), Colour = colourProvider.Background4, From 878489651c456b6747960b6e724c7305400f71b3 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 23:04:11 +0700 Subject: [PATCH 33/41] Make performance_background_width readonly --- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 1905728442..f55d469e22 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks private const int performance_width = 80; private const float performance_background_shear = 0.45f; - private float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); + private readonly float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); protected readonly ScoreInfo Score; From fd7fccbb62c50a7201d88218c4375f1cd984a648 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 19:16:54 +0100 Subject: [PATCH 34/41] Add tests --- .../TestSceneSliderInput.cs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index b6fc9821a4..675c9fd0e7 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -44,6 +44,7 @@ namespace osu.Game.Rulesets.Osu.Tests private const double time_during_slide_2 = 3000; private const double time_during_slide_3 = 3500; private const double time_during_slide_4 = 3800; + private const double time_slider_end = 4000; private List judgementResults; private bool allJudgedFired; @@ -284,6 +285,47 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("Tracking acquired", assertMidSliderJudgements); } + + /// + /// Scenario: + /// - Press a key on the slider head + /// - While holding the key, move cursor close to the edge of tracking area + /// - Keep the cursor on the edge of tracking area until the slider ends + /// Expected Result: + /// A passing test case will have the slider track the cursor throughout the whole test. + /// + [Test] + public void TestTrackingAreaEdge() + { + performTest(new List + { + new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, + new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, + new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + }); + AddAssert("Tracking kept", assertGreatJudge); + } + + /// + /// Scenario: + /// - Press a key on the slider head + /// - While holding the key, move cursor just outside the tracking area + /// - Keep the cursor just outside the tracking area until the slider ends + /// Expected Result: + /// A passing test case will have the slider drop the tracking on frame 2. + /// + [Test] + public void TestTrackingAreaOutsideEdge() + { + performTest(new List + { + new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, + new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.2f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, + new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.2f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + }); + AddAssert("Tracking dropped", assertMidSliderJudgementFail); + } + private bool assertGreatJudge() => judgementResults.Last().Type == HitResult.Great; private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.Great && judgementResults.First().Type == HitResult.Miss; From c7f1d4a8a0874b6e59b58bbaccb10456966320b0 Mon Sep 17 00:00:00 2001 From: Tree Date: Sun, 2 Feb 2020 19:29:26 +0100 Subject: [PATCH 35/41] Remove unnecessary newline --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 675c9fd0e7..38dcc3b23e 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -285,7 +285,6 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("Tracking acquired", assertMidSliderJudgements); } - /// /// Scenario: /// - Press a key on the slider head From 162a3713a33bbec70b4b4c3f260cf9167dc881ae Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 21:25:35 +0100 Subject: [PATCH 36/41] Modify tests to avoid fails in CLI testing --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 675c9fd0e7..7dc81059eb 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -300,8 +300,8 @@ namespace osu.Game.Rulesets.Osu.Tests performTest(new List { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, - new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, + new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking kept", assertGreatJudge); } @@ -320,8 +320,8 @@ namespace osu.Game.Rulesets.Osu.Tests performTest(new List { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, - new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.2f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.2f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, + new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking dropped", assertMidSliderJudgementFail); } From edb4c0f7528dfee3d20290166d82ca375626c550 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 10:24:53 +0900 Subject: [PATCH 37/41] Add blank lines for conformity --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 4b18b961ad..eaa714d68a 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -302,6 +302,7 @@ namespace osu.Game.Rulesets.Osu.Tests new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); + AddAssert("Tracking kept", assertGreatJudge); } @@ -322,6 +323,7 @@ namespace osu.Game.Rulesets.Osu.Tests new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); + AddAssert("Tracking dropped", assertMidSliderJudgementFail); } From ff17c76a20180b5789f03b5b217b11aa315a8b42 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Mon, 3 Feb 2020 08:26:12 +0700 Subject: [PATCH 38/41] Fix modifiers for performance_background_width --- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index f55d469e22..c9f787bb26 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks private const int performance_width = 80; private const float performance_background_shear = 0.45f; - private readonly float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); + private static readonly float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); protected readonly ScoreInfo Score; From 2253ed4c0d13544ab4ef802c666acfd6a004bb87 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 10:29:40 +0900 Subject: [PATCH 39/41] Move path length to a constant --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index eaa714d68a..2ad2c544e5 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -300,7 +300,7 @@ namespace osu.Game.Rulesets.Osu.Tests { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking kept", assertGreatJudge); @@ -321,7 +321,7 @@ namespace osu.Game.Rulesets.Osu.Tests { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking dropped", assertMidSliderJudgementFail); @@ -337,6 +337,8 @@ namespace osu.Game.Rulesets.Osu.Tests private ScoreAccessibleReplayPlayer currentPlayer; + private const float slider_path_length = 25; + private void performTest(List frames) { AddStep("load player", () => @@ -352,8 +354,8 @@ namespace osu.Game.Rulesets.Osu.Tests Path = new SliderPath(PathType.PerfectCurve, new[] { Vector2.Zero, - new Vector2(25, 0), - }, 25), + new Vector2(slider_path_length, 0), + }, slider_path_length), } }, BeatmapInfo = From 9426f786e91adefae97c64397ed9356fc2125d8c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 10:33:56 +0900 Subject: [PATCH 40/41] Use slightly closer values --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 2ad2c544e5..33d79d9cbc 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -300,7 +300,7 @@ namespace osu.Game.Rulesets.Osu.Tests { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking kept", assertGreatJudge); @@ -321,7 +321,7 @@ namespace osu.Game.Rulesets.Osu.Tests { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.201f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking dropped", assertMidSliderJudgementFail); From 9680c0941fa1b751b1dd0a4ab48235e6b15081ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 12:46:11 +0900 Subject: [PATCH 41/41] Move private helper methods to botom of file --- .../Sections/Recent/DrawableRecentActivity.cs | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index f538833eb0..8782e82642 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -122,30 +122,6 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } } - private string getRulesetName() - { - var shortName = activity.Mode; - - return rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == shortName)?.Name ?? shortName; - } - - private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument; - - private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular) - => OsuFont.GetFont(size: font_size, weight: fontWeight, italics: true); - - private void addUserLink() - => content.AddLink(activity.User?.Username, LinkAction.OpenUserProfile, getLinkArgument(activity.User?.Url), creationParameters: t => t.Font = getLinkFont(FontWeight.Bold)); - - private void addBeatmapLink() - => content.AddLink(activity.Beatmap?.Title, LinkAction.OpenBeatmap, getLinkArgument(activity.Beatmap?.Url), creationParameters: t => t.Font = getLinkFont()); - - private void addBeatmapsetLink() - => content.AddLink(activity.Beatmapset?.Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset?.Url), creationParameters: t => t.Font = getLinkFont()); - - private void addText(string text) - => content.AddText(text, t => t.Font = OsuFont.GetFont(size: font_size, weight: FontWeight.SemiBold)); - private void createMessage() { switch (activity.Type) @@ -227,5 +203,25 @@ namespace osu.Game.Overlays.Profile.Sections.Recent break; } } + + private string getRulesetName() => + rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == activity.Mode)?.Name ?? activity.Mode; + + private void addUserLink() + => content.AddLink(activity.User?.Username, LinkAction.OpenUserProfile, getLinkArgument(activity.User?.Url), creationParameters: t => t.Font = getLinkFont(FontWeight.Bold)); + + private void addBeatmapLink() + => content.AddLink(activity.Beatmap?.Title, LinkAction.OpenBeatmap, getLinkArgument(activity.Beatmap?.Url), creationParameters: t => t.Font = getLinkFont()); + + private void addBeatmapsetLink() + => content.AddLink(activity.Beatmapset?.Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset?.Url), creationParameters: t => t.Font = getLinkFont()); + + private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument; + + private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular) + => OsuFont.GetFont(size: font_size, weight: fontWeight, italics: true); + + private void addText(string text) + => content.AddText(text, t => t.Font = OsuFont.GetFont(size: font_size, weight: FontWeight.SemiBold)); } }