From 76db200bd3efd8f3f1a93820e852cbdb9e54fdc8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 7 Oct 2019 16:48:05 +0300 Subject: [PATCH 01/72] Implement GetCommentsRequest --- .../Online/API/Requests/GetCommentsRequest.cs | 53 ++++++++++++++++++ .../API/Requests/Responses/APIComments.cs | 36 ++++++++++++ .../Online/API/Requests/Responses/Comment.cs | 56 +++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 osu.Game/Online/API/Requests/GetCommentsRequest.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIComments.cs create mode 100644 osu.Game/Online/API/Requests/Responses/Comment.cs diff --git a/osu.Game/Online/API/Requests/GetCommentsRequest.cs b/osu.Game/Online/API/Requests/GetCommentsRequest.cs new file mode 100644 index 0000000000..279a1905da --- /dev/null +++ b/osu.Game/Online/API/Requests/GetCommentsRequest.cs @@ -0,0 +1,53 @@ +// 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.IO.Network; +using Humanizer; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetCommentsRequest : APIRequest + { + private readonly long id; + private readonly int page; + private readonly CommentableType type; + private readonly SortCommentsBy sort; + + public GetCommentsRequest(CommentableType type, long id, SortCommentsBy sort = SortCommentsBy.New, int page = 1) + { + this.type = type; + this.sort = sort; + this.id = id; + this.page = page; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + + req.AddParameter("commentable_type", type.ToString().Underscore().ToLowerInvariant()); + req.AddParameter("commentable_id", id.ToString()); + req.AddParameter("sort", sort.ToString()); + req.AddParameter("page", page.ToString()); + + return req; + } + + protected override string Target => "comments"; + } + + public enum CommentableType + { + Build, + Beatmapset, + NewsPost + } + + public enum SortCommentsBy + { + New, + Old, + Top + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIComments.cs b/osu.Game/Online/API/Requests/Responses/APIComments.cs new file mode 100644 index 0000000000..158430a5b6 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIComments.cs @@ -0,0 +1,36 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Newtonsoft.Json; +using osu.Game.Users; +using System.Collections.Generic; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIComments + { + [JsonProperty(@"comments")] + public List Comments { get; set; } + + [JsonProperty(@"has_more")] + public bool HasMore { get; set; } + + [JsonProperty(@"has_more_id")] + public long HasMoreId { get; set; } + + [JsonProperty(@"user_follow")] + public bool UserFollow { get; set; } + + [JsonProperty(@"included_comments")] + public List IncludedComments { get; set; } + + [JsonProperty(@"users")] + public List Users { get; set; } + + [JsonProperty(@"total")] + public int Total { get; set; } + + [JsonProperty(@"top_level_count")] + public int TopLevelCount { get; set; } + } +} diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs new file mode 100644 index 0000000000..e157a10f8a --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -0,0 +1,56 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Newtonsoft.Json; +using System; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class Comment + { + [JsonProperty(@"id")] + public long Id { get; set; } + + [JsonProperty(@"parent_id")] + public long ParentId { get; set; } + + [JsonProperty(@"user_id")] + public long UserId { get; set; } + + [JsonProperty(@"message")] + public string Message { get; set; } + + [JsonProperty(@"message_html")] + public string MessageHTML { get; set; } + + [JsonProperty(@"replies_count")] + public int RepliesCount { get; set; } + + [JsonProperty(@"votes_count")] + public int VotesCount { get; set; } + + [JsonProperty(@"commenatble_type")] + public string CommentableType { get; set; } + + [JsonProperty(@"commentable_id")] + public int CommentableId { get; set; } + + [JsonProperty(@"legacy_name")] + public string LegacyName { get; set; } + + [JsonProperty(@"created_at")] + public DateTimeOffset CreatedAt { get; set; } + + [JsonProperty(@"updated_at")] + public DateTimeOffset UpdatedAt { get; set; } + + [JsonProperty(@"deleted_at")] + public DateTimeOffset DeletedAt { get; set; } + + [JsonProperty(@"edited_at")] + public DateTimeOffset EditedAt { get; set; } + + [JsonProperty(@"edited_by_id")] + public long EditedById { get; set; } + } +} From 738580ec617a23789236575f2525606a6a4d227e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 7 Oct 2019 16:58:24 +0300 Subject: [PATCH 02/72] Add IsTopLevel property --- osu.Game/Online/API/Requests/Responses/Comment.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index e157a10f8a..6edf13d2da 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -11,8 +11,18 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"id")] public long Id { get; set; } + private long? parentId; + [JsonProperty(@"parent_id")] - public long ParentId { get; set; } + public long? ParentId + { + get => parentId; + set + { + parentId = value; + IsTopLevel = value != null; + } + } [JsonProperty(@"user_id")] public long UserId { get; set; } @@ -52,5 +62,7 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"edited_by_id")] public long EditedById { get; set; } + + public bool IsTopLevel { get; set; } } } From e772822bd5ee46afddc5bc14398e73f84ff84564 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 7 Oct 2019 17:49:20 +0300 Subject: [PATCH 03/72] Basic implementation --- .../Online/TestSceneCommentsContainer.cs | 29 +++++ osu.Game/Overlays/CommentsContainer.cs | 110 ++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs create mode 100644 osu.Game/Overlays/CommentsContainer.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs new file mode 100644 index 0000000000..c99062d59b --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -0,0 +1,29 @@ +// 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 NUnit.Framework; +using osu.Game.Overlays; +using osu.Game.Online.API.Requests; + +namespace osu.Game.Tests.Visual.Online +{ + [TestFixture] + public class TestSceneCommentsContainer : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(CommentsContainer), + }; + + public TestSceneCommentsContainer() + { + AddStep("Big Black comments", () => + { + Clear(); + Add(new CommentsContainer(CommentableType.Beatmapset, 41823)); + }); + } + } +} diff --git a/osu.Game/Overlays/CommentsContainer.cs b/osu.Game/Overlays/CommentsContainer.cs new file mode 100644 index 0000000000..8ed6fd0878 --- /dev/null +++ b/osu.Game/Overlays/CommentsContainer.cs @@ -0,0 +1,110 @@ +// 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.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Framework.Graphics; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Framework.Graphics.Sprites; +using osuTK; + +namespace osu.Game.Overlays +{ + public class CommentsContainer : CompositeDrawable + { + private readonly CommentableType type; + private readonly long id; + + public readonly Bindable Sort = new Bindable(); + + [Resolved] + private IAPIProvider api { get; set; } + + private readonly CommentsHeader header; + private readonly Box background; + + public CommentsContainer(CommentableType type, long id) + { + this.type = type; + this.id = id; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + AddRangeInternal(new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + header = new CommentsHeader + { + Sort = { BindTarget = Sort } + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray3; + } + + private class CommentsHeader : CompositeDrawable + { + private const int height = 40; + private const int spacing = 10; + private const int padding = 50; + + public readonly Bindable Sort = new Bindable(); + + private readonly Box background; + + public CommentsHeader() + { + RelativeSizeAxes = Axes.X; + Height = height; + AddRangeInternal(new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = padding }, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(spacing, 0), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Children = new Drawable[] + { + new SpriteText + { + Font = OsuFont.GetFont(size: 14), + Text = @"Sort by" + } + } + } + } + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray4; + } + } + } +} From aa8df0fa20426b0beec6997a2f2a07895cdddbaf Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 7 Oct 2019 18:26:07 +0300 Subject: [PATCH 04/72] Hook up api and implement some visual comments representation --- .../Online/TestSceneCommentsContainer.cs | 15 +++- .../API/Requests/Responses/APIComments.cs | 2 +- .../Online/API/Requests/Responses/Comment.cs | 8 +- osu.Game/Overlays/CommentsContainer.cs | 84 ++++++++++++++++++- 4 files changed, 99 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index c99062d59b..bf4117189a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -6,6 +6,8 @@ using System.Collections.Generic; using NUnit.Framework; using osu.Game.Overlays; using osu.Game.Online.API.Requests; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; namespace osu.Game.Tests.Visual.Online { @@ -17,12 +19,21 @@ namespace osu.Game.Tests.Visual.Online typeof(CommentsContainer), }; + protected override bool UseOnlineAPI => true; + public TestSceneCommentsContainer() { + BasicScrollContainer scrollFlow; + + Add(scrollFlow = new BasicScrollContainer + { + RelativeSizeAxes = Axes.Both, + }); + AddStep("Big Black comments", () => { - Clear(); - Add(new CommentsContainer(CommentableType.Beatmapset, 41823)); + scrollFlow.Clear(); + scrollFlow.Add(new CommentsContainer(CommentableType.Beatmapset, 41823)); }); } } diff --git a/osu.Game/Online/API/Requests/Responses/APIComments.cs b/osu.Game/Online/API/Requests/Responses/APIComments.cs index 158430a5b6..af7650e512 100644 --- a/osu.Game/Online/API/Requests/Responses/APIComments.cs +++ b/osu.Game/Online/API/Requests/Responses/APIComments.cs @@ -16,7 +16,7 @@ namespace osu.Game.Online.API.Requests.Responses public bool HasMore { get; set; } [JsonProperty(@"has_more_id")] - public long HasMoreId { get; set; } + public long? HasMoreId { get; set; } [JsonProperty(@"user_follow")] public bool UserFollow { get; set; } diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 6edf13d2da..df5c812fa0 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -52,16 +52,16 @@ namespace osu.Game.Online.API.Requests.Responses public DateTimeOffset CreatedAt { get; set; } [JsonProperty(@"updated_at")] - public DateTimeOffset UpdatedAt { get; set; } + public DateTimeOffset? UpdatedAt { get; set; } [JsonProperty(@"deleted_at")] - public DateTimeOffset DeletedAt { get; set; } + public DateTimeOffset? DeletedAt { get; set; } [JsonProperty(@"edited_at")] - public DateTimeOffset EditedAt { get; set; } + public DateTimeOffset? EditedAt { get; set; } [JsonProperty(@"edited_by_id")] - public long EditedById { get; set; } + public long? EditedById { get; set; } public bool IsTopLevel { get; set; } } diff --git a/osu.Game/Overlays/CommentsContainer.cs b/osu.Game/Overlays/CommentsContainer.cs index 8ed6fd0878..fce9b3f03b 100644 --- a/osu.Game/Overlays/CommentsContainer.cs +++ b/osu.Game/Overlays/CommentsContainer.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Framework.Graphics.Sprites; using osuTK; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays { @@ -24,8 +25,14 @@ namespace osu.Game.Overlays [Resolved] private IAPIProvider api { get; set; } + [Resolved] + private OsuColour colours { get; set; } + + private GetCommentsRequest request; + private readonly CommentsHeader header; private readonly Box background; + private readonly FillFlowContainer content; public CommentsContainer(CommentableType type, long id) { @@ -40,15 +47,86 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, }, - header = new CommentsHeader + new FillFlowContainer { - Sort = { BindTarget = Sort } + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + header = new CommentsHeader + { + Sort = { BindTarget = Sort } + }, + content = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + } + } + } + }); + } + + protected override void LoadComplete() + { + Sort.BindValueChanged(onSortChanged, true); + base.LoadComplete(); + } + + private void onSortChanged(ValueChangedEvent sort) => getComments(); + + private void getComments() + { + request?.Cancel(); + request = new GetCommentsRequest(type, id, Sort.Value); + request.Success += onSuccess; + api.Queue(request); + } + + private void onSuccess(APIComments response) + { + content.Clear(); + + foreach (var c in response.Comments) + { + createDrawableComment(c); + } + } + + private void createDrawableComment(Comment comment) + { + content.Add(new Container + { + RelativeSizeAxes = Axes.X, + Height = 70, + Children = new Drawable[] + { + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = comment.MessageHTML, + }, + new Container + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + Height = 1, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + } + } } }); } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { background.Colour = colours.Gray3; } From cc6bf2f173b4d53c9fb568963c4685e133417254 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 7 Oct 2019 18:45:22 +0300 Subject: [PATCH 05/72] Add IsDeleted property --- .../Online/API/Requests/Responses/Comment.cs | 16 ++++++++++++++-- osu.Game/Overlays/CommentsContainer.cs | 6 +++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index df5c812fa0..e4b66ddeee 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -20,7 +20,7 @@ namespace osu.Game.Online.API.Requests.Responses set { parentId = value; - IsTopLevel = value != null; + IsTopLevel = value == null; } } @@ -54,8 +54,18 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"updated_at")] public DateTimeOffset? UpdatedAt { get; set; } + private DateTimeOffset? deletedAt; + [JsonProperty(@"deleted_at")] - public DateTimeOffset? DeletedAt { get; set; } + public DateTimeOffset? DeletedAt + { + get => deletedAt; + set + { + deletedAt = value; + IsDeleted = value != null; + } + } [JsonProperty(@"edited_at")] public DateTimeOffset? EditedAt { get; set; } @@ -64,5 +74,7 @@ namespace osu.Game.Online.API.Requests.Responses public long? EditedById { get; set; } public bool IsTopLevel { get; set; } + + public bool IsDeleted { get; set; } } } diff --git a/osu.Game/Overlays/CommentsContainer.cs b/osu.Game/Overlays/CommentsContainer.cs index fce9b3f03b..b22fefb3de 100644 --- a/osu.Game/Overlays/CommentsContainer.cs +++ b/osu.Game/Overlays/CommentsContainer.cs @@ -30,7 +30,6 @@ namespace osu.Game.Overlays private GetCommentsRequest request; - private readonly CommentsHeader header; private readonly Box background; private readonly FillFlowContainer content; @@ -54,7 +53,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new CommentsHeader + new CommentsHeader { Sort = { BindTarget = Sort } }, @@ -91,7 +90,8 @@ namespace osu.Game.Overlays foreach (var c in response.Comments) { - createDrawableComment(c); + if (!c.IsDeleted) + createDrawableComment(c); } } From 4b1a40dabaebadb49d07cbc077d71709714fe6d8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 13:31:49 +0300 Subject: [PATCH 06/72] Implement temp fix to get the actual message --- osu.Game/Online/API/Requests/Responses/Comment.cs | 6 ++++++ osu.Game/Overlays/CommentsContainer.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index e4b66ddeee..ba71faa843 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -76,5 +76,11 @@ namespace osu.Game.Online.API.Requests.Responses public bool IsTopLevel { get; set; } public bool IsDeleted { get; set; } + + public string GetMessage() + { + //temporary fix until HTML parsing will be implemented + return MessageHTML.Remove(MessageHTML.LastIndexOf("

")).Substring(65); + } } } diff --git a/osu.Game/Overlays/CommentsContainer.cs b/osu.Game/Overlays/CommentsContainer.cs index b22fefb3de..1b4bbee6a1 100644 --- a/osu.Game/Overlays/CommentsContainer.cs +++ b/osu.Game/Overlays/CommentsContainer.cs @@ -107,7 +107,7 @@ namespace osu.Game.Overlays { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Text = comment.MessageHTML, + Text = comment.GetMessage(), }, new Container { From 801b5b474e300343bafc0defc0a8818e3516919d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 13:45:13 +0300 Subject: [PATCH 07/72] Add a User property to the comment for easy access --- .../API/Requests/Responses/APIComments.cs | 20 ++++++++++++++++- .../Online/API/Requests/Responses/Comment.cs | 3 +++ osu.Game/Overlays/CommentsContainer.cs | 22 +++++++++++++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIComments.cs b/osu.Game/Online/API/Requests/Responses/APIComments.cs index af7650e512..86bbf0358a 100644 --- a/osu.Game/Online/API/Requests/Responses/APIComments.cs +++ b/osu.Game/Online/API/Requests/Responses/APIComments.cs @@ -24,8 +24,26 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"included_comments")] public List IncludedComments { get; set; } + private List users; + [JsonProperty(@"users")] - public List Users { get; set; } + public List Users + { + get => users; + set + { + users = value; + + value.ForEach(u => + { + Comments.ForEach(c => + { + if (c.UserId == u.Id) + c.User = u; + }); + }); + } + } [JsonProperty(@"total")] public int Total { get; set; } diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index ba71faa843..46212dd50f 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using Newtonsoft.Json; +using osu.Game.Users; using System; namespace osu.Game.Online.API.Requests.Responses @@ -27,6 +28,8 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"user_id")] public long UserId { get; set; } + public User User { get; set; } + [JsonProperty(@"message")] public string Message { get; set; } diff --git a/osu.Game/Overlays/CommentsContainer.cs b/osu.Game/Overlays/CommentsContainer.cs index 1b4bbee6a1..c871810d8a 100644 --- a/osu.Game/Overlays/CommentsContainer.cs +++ b/osu.Game/Overlays/CommentsContainer.cs @@ -103,11 +103,29 @@ namespace osu.Game.Overlays Height = 70, Children = new Drawable[] { - new SpriteText + new FillFlowContainer { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Text = comment.GetMessage(), + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 3), + Children = new[] + { + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = $"user: {comment.User.Username}", + }, + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = $"message: {comment.GetMessage()}", + }, + } }, new Container { From 1c89841949e025fe693aab73a97dd9a93c78b85b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 14:51:12 +0300 Subject: [PATCH 08/72] Move all the logic to it's own namespace --- .../Online/TestSceneCommentsContainer.cs | 2 +- .../{ => Comments}/CommentsContainer.cs | 67 +++---------- osu.Game/Overlays/Comments/DrawableComment.cs | 99 +++++++++++++++++++ 3 files changed, 116 insertions(+), 52 deletions(-) rename osu.Game/Overlays/{ => Comments}/CommentsContainer.cs (73%) create mode 100644 osu.Game/Overlays/Comments/DrawableComment.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index bf4117189a..e6f9582910 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -4,10 +4,10 @@ using System; using System.Collections.Generic; using NUnit.Framework; -using osu.Game.Overlays; using osu.Game.Online.API.Requests; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; +using osu.Game.Overlays.Comments; namespace osu.Game.Tests.Visual.Online { diff --git a/osu.Game/Overlays/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs similarity index 73% rename from osu.Game/Overlays/CommentsContainer.cs rename to osu.Game/Overlays/Comments/CommentsContainer.cs index c871810d8a..60b22428f0 100644 --- a/osu.Game/Overlays/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -13,7 +13,7 @@ using osu.Framework.Graphics.Sprites; using osuTK; using osu.Game.Online.API.Requests.Responses; -namespace osu.Game.Overlays +namespace osu.Game.Overlays.Comments { public class CommentsContainer : CompositeDrawable { @@ -90,59 +90,24 @@ namespace osu.Game.Overlays foreach (var c in response.Comments) { - if (!c.IsDeleted) - createDrawableComment(c); + if (!c.IsDeleted && c.IsTopLevel) + content.AddRange(new Drawable[] + { + new DrawableComment(c), + new Container + { + RelativeSizeAxes = Axes.X, + Height = 1, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + } + } + }); } } - private void createDrawableComment(Comment comment) - { - content.Add(new Container - { - RelativeSizeAxes = Axes.X, - Height = 70, - Children = new Drawable[] - { - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 3), - Children = new[] - { - new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = $"user: {comment.User.Username}", - }, - new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = $"message: {comment.GetMessage()}", - }, - } - }, - new Container - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.X, - Height = 1, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.Gray1, - } - } - } - }); - } - [BackgroundDependencyLoader] private void load() { diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs new file mode 100644 index 0000000000..bbb804dc5b --- /dev/null +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -0,0 +1,99 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osu.Framework.Graphics.Sprites; +using osuTK; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Users.Drawables; +using osu.Game.Graphics.Containers; +using osu.Game.Utils; + +namespace osu.Game.Overlays.Comments +{ + public class DrawableComment : CompositeDrawable + { + private const int avatar_size = 40; + private const int margin = 10; + + public DrawableComment(Comment comment) + { + LinkFlowContainer username; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + InternalChild = new GridContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding(margin), + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(), + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] + { + new UpdateableAvatar(comment.User) + { + Size = new Vector2(avatar_size), + Margin = new MarginPadding { Horizontal = margin }, + Masking = true, + CornerRadius = avatar_size / 2, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Spacing = new Vector2(0, 2), + Children = new Drawable[] + { + username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + }, + new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 18)) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Text = comment.GetMessage() + } + } + } + }, + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + }, + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Text = HumanizerUtils.Humanize(comment.CreatedAt) + } + } + } + }; + + username.AddUserLink(comment.User); + } + } +} From 2564214a72b70007368fa3c5763c407fab2192ac Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 15:01:18 +0300 Subject: [PATCH 09/72] Fix some padding issues with the big comments --- osu.Game/Overlays/Comments/DrawableComment.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index bbb804dc5b..6f3d92c7fd 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -54,21 +54,16 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Top = margin / 2 }, Spacing = new Vector2(0, 2), Children = new Drawable[] { username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, }, - new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 18)) + new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Text = comment.GetMessage() From 451a7342ce7459ae42562521e549af8e7e8a1d5b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 15:39:03 +0300 Subject: [PATCH 10/72] Parse child comments --- .../API/Requests/Responses/APIComments.cs | 22 +++- .../Online/API/Requests/Responses/Comment.cs | 3 + .../Overlays/Comments/CommentsContainer.cs | 4 +- osu.Game/Overlays/Comments/DrawableComment.cs | 106 +++++++++++------- 4 files changed, 92 insertions(+), 43 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIComments.cs b/osu.Game/Online/API/Requests/Responses/APIComments.cs index 86bbf0358a..9a12fb613e 100644 --- a/osu.Game/Online/API/Requests/Responses/APIComments.cs +++ b/osu.Game/Online/API/Requests/Responses/APIComments.cs @@ -9,8 +9,28 @@ namespace osu.Game.Online.API.Requests.Responses { public class APIComments { + private List comments; + [JsonProperty(@"comments")] - public List Comments { get; set; } + public List Comments + { + get => comments; + set + { + comments = value; + comments.ForEach(child => + { + if (child.ParentId != null) + { + comments.ForEach(parent => + { + if (parent.Id == child.ParentId) + parent.ChildComments.Add(child); + }); + } + }); + } + } [JsonProperty(@"has_more")] public bool HasMore { get; set; } diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 46212dd50f..cdc3c3204b 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -4,6 +4,7 @@ using Newtonsoft.Json; using osu.Game.Users; using System; +using System.Collections.Generic; namespace osu.Game.Online.API.Requests.Responses { @@ -25,6 +26,8 @@ namespace osu.Game.Online.API.Requests.Responses } } + public List ChildComments = new List(); + [JsonProperty(@"user_id")] public long UserId { get; set; } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 60b22428f0..d02e74a5a4 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -17,6 +17,8 @@ namespace osu.Game.Overlays.Comments { public class CommentsContainer : CompositeDrawable { + private const float separator_height = 1.5f; + private readonly CommentableType type; private readonly long id; @@ -97,7 +99,7 @@ namespace osu.Game.Overlays.Comments new Container { RelativeSizeAxes = Axes.X, - Height = 1, + Height = separator_height, Child = new Box { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 6f3d92c7fd..53366be878 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -17,78 +17,102 @@ namespace osu.Game.Overlays.Comments { private const int avatar_size = 40; private const int margin = 10; + private const int child_margin = 20; public DrawableComment(Comment comment) { LinkFlowContainer username; + FillFlowContainer childCommentsContainer; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - InternalChild = new GridContainer + InternalChild = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding(margin), - ColumnDimensions = new[] + Direction = FillDirection.Vertical, + Children = new Drawable[] { - new Dimension(GridSizeMode.AutoSize), - new Dimension(), - }, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize) - }, - Content = new[] - { - new Drawable[] + new GridContainer { - new UpdateableAvatar(comment.User) + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding(margin), + ColumnDimensions = new[] { - Size = new Vector2(avatar_size), - Margin = new MarginPadding { Horizontal = margin }, - Masking = true, - CornerRadius = avatar_size / 2, + new Dimension(GridSizeMode.AutoSize), + new Dimension(), }, - new FillFlowContainer + RowDimensions = new[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = margin / 2 }, - Spacing = new Vector2(0, 2), - Children = new Drawable[] + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] { - username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + new UpdateableAvatar(comment.User) { - AutoSizeAxes = Axes.Both, + Size = new Vector2(avatar_size), + Margin = new MarginPadding { Horizontal = margin }, + Masking = true, + CornerRadius = avatar_size / 2, }, - new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) + new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Text = comment.GetMessage() + Margin = new MarginPadding { Top = margin / 2 }, + Spacing = new Vector2(0, 2), + Children = new Drawable[] + { + username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + { + AutoSizeAxes = Axes.Both, + }, + new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Text = comment.GetMessage() + } + } + } + }, + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + }, + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Text = HumanizerUtils.Humanize(comment.CreatedAt) } } } }, - new Drawable[] + childCommentsContainer = new FillFlowContainer { - new Container - { - RelativeSizeAxes = Axes.Both, - }, - new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12), - Text = HumanizerUtils.Humanize(comment.CreatedAt) - } + Margin = new MarginPadding { Left = child_margin }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical } } }; username.AddUserLink(comment.User); + + comment.ChildComments.ForEach(c => + { + if (!c.IsDeleted) + childCommentsContainer.Add(new DrawableComment(c)); + }); } } } From 9c7e403cf8ca62b83ded5505c030b77f8ee0a81b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 16:00:34 +0300 Subject: [PATCH 11/72] Implement replies button --- osu.Game/Overlays/Comments/DrawableComment.cs | 98 +++++++++++++++++-- 1 file changed, 90 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 53366be878..9879995b00 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -10,6 +10,8 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Users.Drawables; using osu.Game.Graphics.Containers; using osu.Game.Utils; +using osu.Framework.Input.Events; +using System; namespace osu.Game.Overlays.Comments { @@ -18,11 +20,39 @@ namespace osu.Game.Overlays.Comments private const int avatar_size = 40; private const int margin = 10; private const int child_margin = 20; + private const int duration = 200; + + private bool childExpanded = true; + + public bool ChildExpanded + { + get => childExpanded; + set + { + if (childExpanded == value) + return; + + childExpanded = value; + + childCommentsVisibilityContainer.ClearTransforms(); + + if (childExpanded) + childCommentsVisibilityContainer.AutoSizeAxes = Axes.Y; + else + { + childCommentsVisibilityContainer.AutoSizeAxes = Axes.None; + childCommentsVisibilityContainer.ResizeHeightTo(0, duration, Easing.OutQuint); + } + } + } + + private readonly Container childCommentsVisibilityContainer; public DrawableComment(Comment comment) { LinkFlowContainer username; FillFlowContainer childCommentsContainer; + RepliesButton replies; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -86,22 +116,40 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.Both, }, - new SpriteText + new FillFlowContainer { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12), - Text = HumanizerUtils.Humanize(comment.CreatedAt) + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Text = HumanizerUtils.Humanize(comment.CreatedAt) + }, + replies = new RepliesButton(comment.RepliesCount), + } } } } }, - childCommentsContainer = new FillFlowContainer + childCommentsVisibilityContainer = new Container { - Margin = new MarginPadding { Left = child_margin }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical + AutoSizeDuration = duration, + AutoSizeEasing = Easing.OutQuint, + Masking = true, + Child = childCommentsContainer = new FillFlowContainer + { + Margin = new MarginPadding { Left = child_margin }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical + } } } }; @@ -113,6 +161,40 @@ namespace osu.Game.Overlays.Comments if (!c.IsDeleted) childCommentsContainer.Add(new DrawableComment(c)); }); + + replies.Action += expanded => ChildExpanded = expanded; + } + + private class RepliesButton : Container + { + private readonly SpriteText text; + private bool expanded; + private readonly int count; + + public Action Action; + + public RepliesButton(int count) + { + this.count = count; + + AutoSizeAxes = Axes.Both; + Alpha = count == 0 ? 0 : 1; + Child = text = new SpriteText + { + Font = OsuFont.GetFont(size: 12), + Text = $@"[-] replies ({count})" + }; + + expanded = true; + } + + protected override bool OnClick(ClickEvent e) + { + text.Text = $@"{(expanded ? "[+]" : "[-]")} replies ({count})"; + expanded = !expanded; + Action?.Invoke(expanded); + return base.OnClick(e); + } } } } From 3f8fecbc5034d2b601ea6e6bc3643e25b8e13fc6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 16:04:52 +0300 Subject: [PATCH 12/72] Adjust spacing --- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 9879995b00..f3d8d2f577 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -120,7 +120,7 @@ namespace osu.Game.Overlays.Comments { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), + Spacing = new Vector2(10, 0), Children = new Drawable[] { new SpriteText From 000e4a563cf4389d9fc86683838ece2e8251230b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 19:09:02 +0300 Subject: [PATCH 13/72] Parse parent comments --- .../API/Requests/Responses/APIComments.cs | 3 ++ .../Online/API/Requests/Responses/Comment.cs | 2 + osu.Game/Overlays/Comments/DrawableComment.cs | 45 ++++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIComments.cs b/osu.Game/Online/API/Requests/Responses/APIComments.cs index 9a12fb613e..f454d4052f 100644 --- a/osu.Game/Online/API/Requests/Responses/APIComments.cs +++ b/osu.Game/Online/API/Requests/Responses/APIComments.cs @@ -25,7 +25,10 @@ namespace osu.Game.Online.API.Requests.Responses comments.ForEach(parent => { if (parent.Id == child.ParentId) + { parent.ChildComments.Add(child); + child.ParentComment = parent; + } }); } }); diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index cdc3c3204b..e5d3f14d27 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -28,6 +28,8 @@ namespace osu.Game.Online.API.Requests.Responses public List ChildComments = new List(); + public Comment ParentComment { get; set; } + [JsonProperty(@"user_id")] public long UserId { get; set; } diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index f3d8d2f577..dea14f22c8 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -12,6 +12,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Utils; using osu.Framework.Input.Events; using System; +using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.Comments { @@ -97,9 +98,19 @@ namespace osu.Game.Overlays.Comments Spacing = new Vector2(0, 2), Children = new Drawable[] { - username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + new FillFlowContainer { AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(7, 0), + Children = new Drawable[] + { + username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + { + AutoSizeAxes = Axes.Both, + }, + new ParentUsername(comment) + } }, new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) { @@ -196,5 +207,37 @@ namespace osu.Game.Overlays.Comments return base.OnClick(e); } } + + private class ParentUsername : FillFlowContainer, IHasTooltip + { + private const int spacing = 3; + + public string TooltipText => comment.ParentComment?.GetMessage() ?? ""; + + private readonly Comment comment; + + public ParentUsername(Comment comment) + { + this.comment = comment; + + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + Spacing = new Vector2(spacing, 0); + Alpha = comment.ParentId == null ? 0 : 1; + Children = new Drawable[] + { + new SpriteIcon + { + Icon = FontAwesome.Solid.Reply, + Size = new Vector2(14), + }, + new SpriteText + { + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), + Text = comment.ParentComment?.User?.Username + } + }; + } + } } } From 341702b91d084207316711e6f43e33afa3fadcc6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 19:18:46 +0300 Subject: [PATCH 14/72] Use Bindable for expansion logic --- osu.Game/Overlays/Comments/DrawableComment.cs | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index dea14f22c8..bf24cbb70d 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -11,8 +11,8 @@ using osu.Game.Users.Drawables; using osu.Game.Graphics.Containers; using osu.Game.Utils; using osu.Framework.Input.Events; -using System; using osu.Framework.Graphics.Cursor; +using osu.Framework.Bindables; namespace osu.Game.Overlays.Comments { @@ -23,29 +23,7 @@ namespace osu.Game.Overlays.Comments private const int child_margin = 20; private const int duration = 200; - private bool childExpanded = true; - - public bool ChildExpanded - { - get => childExpanded; - set - { - if (childExpanded == value) - return; - - childExpanded = value; - - childCommentsVisibilityContainer.ClearTransforms(); - - if (childExpanded) - childCommentsVisibilityContainer.AutoSizeAxes = Axes.Y; - else - { - childCommentsVisibilityContainer.AutoSizeAxes = Axes.None; - childCommentsVisibilityContainer.ResizeHeightTo(0, duration, Easing.OutQuint); - } - } - } + private readonly BindableBool childExpanded = new BindableBool(true); private readonly Container childCommentsVisibilityContainer; @@ -53,7 +31,6 @@ namespace osu.Game.Overlays.Comments { LinkFlowContainer username; FillFlowContainer childCommentsContainer; - RepliesButton replies; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -141,7 +118,8 @@ namespace osu.Game.Overlays.Comments Font = OsuFont.GetFont(size: 12), Text = HumanizerUtils.Humanize(comment.CreatedAt) }, - replies = new RepliesButton(comment.RepliesCount), + new RepliesButton(comment.RepliesCount) + { Expanded = { BindTarget = childExpanded } }, } } } @@ -172,17 +150,33 @@ namespace osu.Game.Overlays.Comments if (!c.IsDeleted) childCommentsContainer.Add(new DrawableComment(c)); }); + } - replies.Action += expanded => ChildExpanded = expanded; + protected override void LoadComplete() + { + childExpanded.BindValueChanged(onChildExpandedChanged, true); + base.LoadComplete(); + } + + private void onChildExpandedChanged(ValueChangedEvent expanded) + { + childCommentsVisibilityContainer.ClearTransforms(); + + if (expanded.NewValue) + childCommentsVisibilityContainer.AutoSizeAxes = Axes.Y; + else + { + childCommentsVisibilityContainer.AutoSizeAxes = Axes.None; + childCommentsVisibilityContainer.ResizeHeightTo(0, duration, Easing.OutQuint); + } } private class RepliesButton : Container { private readonly SpriteText text; - private bool expanded; private readonly int count; - public Action Action; + public readonly BindableBool Expanded = new BindableBool(true); public RepliesButton(int count) { @@ -193,17 +187,23 @@ namespace osu.Game.Overlays.Comments Child = text = new SpriteText { Font = OsuFont.GetFont(size: 12), - Text = $@"[-] replies ({count})" }; + } - expanded = true; + protected override void LoadComplete() + { + Expanded.BindValueChanged(onExpandedChanged, true); + base.LoadComplete(); + } + + private void onExpandedChanged(ValueChangedEvent expanded) + { + text.Text = $@"{(expanded.NewValue ? "[+]" : "[-]")} replies ({count})"; } protected override bool OnClick(ClickEvent e) { - text.Text = $@"{(expanded ? "[+]" : "[-]")} replies ({count})"; - expanded = !expanded; - Action?.Invoke(expanded); + Expanded.Value = !Expanded.Value; return base.OnClick(e); } } From 4230b00110768023bd1cf9d0e1fc098d5b273224 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 19:22:23 +0300 Subject: [PATCH 15/72] Rename APIComments to APICommentsController --- osu.Game/Online/API/Requests/GetCommentsRequest.cs | 2 +- .../Responses/{APIComments.cs => APICommentsController.cs} | 2 +- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename osu.Game/Online/API/Requests/Responses/{APIComments.cs => APICommentsController.cs} (98%) diff --git a/osu.Game/Online/API/Requests/GetCommentsRequest.cs b/osu.Game/Online/API/Requests/GetCommentsRequest.cs index 279a1905da..5a2b61b4d0 100644 --- a/osu.Game/Online/API/Requests/GetCommentsRequest.cs +++ b/osu.Game/Online/API/Requests/GetCommentsRequest.cs @@ -7,7 +7,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetCommentsRequest : APIRequest + public class GetCommentsRequest : APIRequest { private readonly long id; private readonly int page; diff --git a/osu.Game/Online/API/Requests/Responses/APIComments.cs b/osu.Game/Online/API/Requests/Responses/APICommentsController.cs similarity index 98% rename from osu.Game/Online/API/Requests/Responses/APIComments.cs rename to osu.Game/Online/API/Requests/Responses/APICommentsController.cs index f454d4052f..cf2e5e8a35 100644 --- a/osu.Game/Online/API/Requests/Responses/APIComments.cs +++ b/osu.Game/Online/API/Requests/Responses/APICommentsController.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; namespace osu.Game.Online.API.Requests.Responses { - public class APIComments + public class APICommentsController { private List comments; diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index d02e74a5a4..abbd2cdbde 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -86,7 +86,7 @@ namespace osu.Game.Overlays.Comments api.Queue(request); } - private void onSuccess(APIComments response) + private void onSuccess(APICommentsController response) { content.Clear(); From 35cfb16c8d21594237251fbf63d4fd69491efc3f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 19:56:43 +0300 Subject: [PATCH 16/72] Implement VotePill component --- osu.Game/Overlays/Comments/DrawableComment.cs | 55 +++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index bf24cbb70d..ce60d905ad 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -13,6 +13,8 @@ using osu.Game.Utils; using osu.Framework.Input.Events; using osu.Framework.Graphics.Cursor; using osu.Framework.Bindables; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; namespace osu.Game.Overlays.Comments { @@ -60,12 +62,28 @@ namespace osu.Game.Overlays.Comments { new Drawable[] { - new UpdateableAvatar(comment.User) + new FillFlowContainer { - Size = new Vector2(avatar_size), + AutoSizeAxes = Axes.Both, Margin = new MarginPadding { Horizontal = margin }, - Masking = true, - CornerRadius = avatar_size / 2, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new VotePill(comment.VotesCount) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new UpdateableAvatar(comment.User) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(avatar_size), + Masking = true, + CornerRadius = avatar_size / 2, + }, + } }, new FillFlowContainer { @@ -239,5 +257,34 @@ namespace osu.Game.Overlays.Comments }; } } + + private class VotePill : CircularContainer + { + private const int height = 20; + private const int margin = 10; + + public VotePill(int count) + { + AutoSizeAxes = Axes.X; + Height = height; + Masking = true; + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black + }, + new SpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Horizontal = margin }, + Font = OsuFont.GetFont(size: 14), + Text = $"+{count}" + } + }; + } + } } } From 9ab309fc0ef387e2226991c7f010e75f52fe1a19 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 20:44:01 +0300 Subject: [PATCH 17/72] Use bold font for replies button --- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index ce60d905ad..ce78dfec9f 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -204,7 +204,7 @@ namespace osu.Game.Overlays.Comments Alpha = count == 0 ? 0 : 1; Child = text = new SpriteText { - Font = OsuFont.GetFont(size: 12), + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), }; } From b9ad079bf8b077ae7a9aa53bdb2da1e6dcc0993e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 20:57:55 +0300 Subject: [PATCH 18/72] Move CommentsHeader to it's own file --- .../Online/TestSceneCommentsContainer.cs | 2 + .../Overlays/Comments/CommentsContainer.cs | 56 --------------- osu.Game/Overlays/Comments/CommentsHeader.cs | 69 +++++++++++++++++++ 3 files changed, 71 insertions(+), 56 deletions(-) create mode 100644 osu.Game/Overlays/Comments/CommentsHeader.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index e6f9582910..c8d16bdf21 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -17,6 +17,8 @@ namespace osu.Game.Tests.Visual.Online public override IReadOnlyList RequiredTypes => new[] { typeof(CommentsContainer), + typeof(CommentsHeader), + typeof(DrawableComment), }; protected override bool UseOnlineAPI => true; diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index abbd2cdbde..f8783952d1 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -9,8 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Bindables; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; -using osu.Framework.Graphics.Sprites; -using osuTK; using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Comments @@ -115,59 +113,5 @@ namespace osu.Game.Overlays.Comments { background.Colour = colours.Gray3; } - - private class CommentsHeader : CompositeDrawable - { - private const int height = 40; - private const int spacing = 10; - private const int padding = 50; - - public readonly Bindable Sort = new Bindable(); - - private readonly Box background; - - public CommentsHeader() - { - RelativeSizeAxes = Axes.X; - Height = height; - AddRangeInternal(new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = padding }, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(spacing, 0), - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Children = new Drawable[] - { - new SpriteText - { - Font = OsuFont.GetFont(size: 14), - Text = @"Sort by" - } - } - } - } - } - }); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = colours.Gray4; - } - } } } diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs new file mode 100644 index 0000000000..9ebd257a5d --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -0,0 +1,69 @@ +// 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.Game.Online.API.Requests; +using osu.Framework.Graphics; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Framework.Graphics.Sprites; +using osuTK; + +namespace osu.Game.Overlays.Comments +{ + public class CommentsHeader : CompositeDrawable + { + private const int height = 40; + private const int spacing = 10; + private const int padding = 50; + + public readonly Bindable Sort = new Bindable(); + + private readonly Box background; + + public CommentsHeader() + { + RelativeSizeAxes = Axes.X; + Height = height; + AddRangeInternal(new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = padding }, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(spacing, 0), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Children = new Drawable[] + { + new SpriteText + { + Font = OsuFont.GetFont(size: 14), + Text = @"Sort by" + } + } + } + } + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray4; + } + } +} From 574170124cff05070833415e324f77a2e5fe88ef Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 21:38:19 +0300 Subject: [PATCH 19/72] Implement HeaderButton component --- .../Online/TestSceneCommentsContainer.cs | 1 + osu.Game/Overlays/Comments/CommentsHeader.cs | 63 ++++++++++++++++- osu.Game/Overlays/Comments/HeaderButton.cs | 68 +++++++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Overlays/Comments/HeaderButton.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index c8d16bdf21..f5205552e0 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -19,6 +19,7 @@ namespace osu.Game.Tests.Visual.Online typeof(CommentsContainer), typeof(CommentsHeader), typeof(DrawableComment), + typeof(HeaderButton), }; protected override bool UseOnlineAPI => true; diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index 9ebd257a5d..b9dee7935e 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Framework.Graphics.Sprites; using osuTK; +using osu.Framework.Input.Events; namespace osu.Game.Overlays.Comments { @@ -18,8 +19,10 @@ namespace osu.Game.Overlays.Comments private const int height = 40; private const int spacing = 10; private const int padding = 50; + private const int text_size = 14; public readonly Bindable Sort = new Bindable(); + public readonly BindableBool ShowDeleted = new BindableBool(); private readonly Box background; @@ -50,10 +53,16 @@ namespace osu.Game.Overlays.Comments { new SpriteText { - Font = OsuFont.GetFont(size: 14), + Font = OsuFont.GetFont(size: text_size), Text = @"Sort by" } } + }, + new ShowDeletedButton + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Checked = { BindTarget = ShowDeleted } } } } @@ -65,5 +74,57 @@ namespace osu.Game.Overlays.Comments { background.Colour = colours.Gray4; } + + private class ShowDeletedButton : HeaderButton + { + private const int spacing = 5; + + public readonly BindableBool Checked = new BindableBool(); + + private readonly SpriteIcon checkboxIcon; + + public ShowDeletedButton() + { + Add(new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(spacing, 0), + Children = new Drawable[] + { + checkboxIcon = new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(10), + }, + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: text_size), + Text = @"Show deleted" + } + }, + }); + } + + protected override void LoadComplete() + { + Checked.BindValueChanged(onCheckedChanged, true); + base.LoadComplete(); + } + + private void onCheckedChanged(ValueChangedEvent isChecked) + { + checkboxIcon.Icon = isChecked.NewValue ? FontAwesome.Solid.CheckSquare : FontAwesome.Regular.Square; + } + + protected override bool OnClick(ClickEvent e) + { + Checked.Value = !Checked.Value; + return base.OnClick(e); + } + } } } diff --git a/osu.Game/Overlays/Comments/HeaderButton.cs b/osu.Game/Overlays/Comments/HeaderButton.cs new file mode 100644 index 0000000000..db8ea92a1a --- /dev/null +++ b/osu.Game/Overlays/Comments/HeaderButton.cs @@ -0,0 +1,68 @@ +// 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.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Framework.Input.Events; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Comments +{ + public class HeaderButton : Container + { + private const int height = 20; + private const int corner_radius = 3; + private const int margin = 10; + private const int duration = 200; + + protected override Container Content => content; + + private readonly Box background; + private readonly Container content; + + public HeaderButton() + { + AutoSizeAxes = Axes.X; + Height = height; + Masking = true; + CornerRadius = corner_radius; + AddRangeInternal(new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + }, + content = new Container + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Horizontal = margin } + }, + new HoverClickSounds(), + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray6; + } + + protected override bool OnHover(HoverEvent e) + { + background.FadeIn(duration, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + background.FadeOut(duration, Easing.OutQuint); + } + } +} From 29b0eacc821b5091c0251d6066e2e52296d8c279 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 8 Oct 2019 22:46:42 +0300 Subject: [PATCH 20/72] Implement SortSelector component --- .../Online/TestSceneCommentsContainer.cs | 1 + .../Online/API/Requests/GetCommentsRequest.cs | 2 +- .../Online/API/Requests/Responses/Comment.cs | 2 +- .../Overlays/Comments/CommentsContainer.cs | 3 +- osu.Game/Overlays/Comments/CommentsHeader.cs | 8 ++ osu.Game/Overlays/Comments/DrawableComment.cs | 9 ++- osu.Game/Overlays/Comments/HeaderButton.cs | 8 +- osu.Game/Overlays/Comments/SortSelector.cs | 75 +++++++++++++++++++ 8 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 osu.Game/Overlays/Comments/SortSelector.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index f5205552e0..7fbe9d7e8b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -20,6 +20,7 @@ namespace osu.Game.Tests.Visual.Online typeof(CommentsHeader), typeof(DrawableComment), typeof(HeaderButton), + typeof(SortSelector) }; protected override bool UseOnlineAPI => true; diff --git a/osu.Game/Online/API/Requests/GetCommentsRequest.cs b/osu.Game/Online/API/Requests/GetCommentsRequest.cs index 5a2b61b4d0..02a36f7aa2 100644 --- a/osu.Game/Online/API/Requests/GetCommentsRequest.cs +++ b/osu.Game/Online/API/Requests/GetCommentsRequest.cs @@ -28,7 +28,7 @@ namespace osu.Game.Online.API.Requests req.AddParameter("commentable_type", type.ToString().Underscore().ToLowerInvariant()); req.AddParameter("commentable_id", id.ToString()); - req.AddParameter("sort", sort.ToString()); + req.AddParameter("sort", sort.ToString().ToLowerInvariant()); req.AddParameter("page", page.ToString()); return req; diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index e5d3f14d27..30aca3c2ea 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -31,7 +31,7 @@ namespace osu.Game.Online.API.Requests.Responses public Comment ParentComment { get; set; } [JsonProperty(@"user_id")] - public long UserId { get; set; } + public long? UserId { get; set; } public User User { get; set; } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index f8783952d1..5be1b6c1c4 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -79,6 +79,7 @@ namespace osu.Game.Overlays.Comments private void getComments() { request?.Cancel(); + content.Clear(); request = new GetCommentsRequest(type, id, Sort.Value); request.Success += onSuccess; api.Queue(request); @@ -86,8 +87,6 @@ namespace osu.Game.Overlays.Comments private void onSuccess(APICommentsController response) { - content.Clear(); - foreach (var c in response.Comments) { if (!c.IsDeleted && c.IsTopLevel) diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index b9dee7935e..90a6f44d6b 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -53,8 +53,16 @@ namespace osu.Game.Overlays.Comments { new SpriteText { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, Font = OsuFont.GetFont(size: text_size), Text = @"Sort by" + }, + new SortSelector + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Current = { BindTarget = Sort } } } }, diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index ce78dfec9f..41b30513a1 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -161,7 +161,14 @@ namespace osu.Game.Overlays.Comments } }; - username.AddUserLink(comment.User); + if (comment.UserId == null) + { + username.AddText(comment.LegacyName); + } + else + { + username.AddUserLink(comment.User); + } comment.ChildComments.ForEach(c => { diff --git a/osu.Game/Overlays/Comments/HeaderButton.cs b/osu.Game/Overlays/Comments/HeaderButton.cs index db8ea92a1a..e3729b3b05 100644 --- a/osu.Game/Overlays/Comments/HeaderButton.cs +++ b/osu.Game/Overlays/Comments/HeaderButton.cs @@ -55,14 +55,18 @@ namespace osu.Game.Overlays.Comments protected override bool OnHover(HoverEvent e) { - background.FadeIn(duration, Easing.OutQuint); + FadeInBackground(); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - background.FadeOut(duration, Easing.OutQuint); + FadeOutBackground(); } + + public void FadeInBackground() => background.FadeIn(duration, Easing.OutQuint); + + public void FadeOutBackground() => background.FadeOut(duration, Easing.OutQuint); } } diff --git a/osu.Game/Overlays/Comments/SortSelector.cs b/osu.Game/Overlays/Comments/SortSelector.cs new file mode 100644 index 0000000000..4425145c3e --- /dev/null +++ b/osu.Game/Overlays/Comments/SortSelector.cs @@ -0,0 +1,75 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Online.API.Requests; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osuTK; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Framework.Bindables; + +namespace osu.Game.Overlays.Comments +{ + public class SortSelector : OsuTabControl + { + private const int spacing = 5; + + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(SortCommentsBy value) => new SortTabItem(value); + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(spacing, 0), + }; + + public SortSelector() + { + AutoSizeAxes = Axes.Both; + } + + private class SortTabItem : TabItem + { + private readonly TabContent content; + + public SortTabItem(SortCommentsBy value) + : base(value) + { + AutoSizeAxes = Axes.Both; + Child = content = new TabContent(value) + { Active = { BindTarget = Active } }; + } + + protected override void OnActivated() => content.FadeInBackground(); + + protected override void OnDeactivated() => content.FadeOutBackground(); + + private class TabContent : HeaderButton + { + private const int text_size = 14; + + public readonly BindableBool Active = new BindableBool(); + + public TabContent(SortCommentsBy value) + { + Add(new SpriteText + { + Font = OsuFont.GetFont(size: text_size), + Text = value.ToString() + }); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + if (!Active.Value) base.OnHoverLost(e); + } + } + } + } +} From faef4d932d08cc7ef5fde89d88953b3c21cd7ac6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 9 Oct 2019 10:17:14 +0300 Subject: [PATCH 21/72] Improve message parsing --- osu.Game/Online/API/Requests/Responses/Comment.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 30aca3c2ea..fb0aad0e0b 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -87,8 +87,7 @@ namespace osu.Game.Online.API.Requests.Responses public string GetMessage() { - //temporary fix until HTML parsing will be implemented - return MessageHTML.Remove(MessageHTML.LastIndexOf("

")).Substring(65); + return MessageHTML.Replace("
", "").Replace("

", "").Replace("
", "").Replace("

", "").Replace("
", ""); } } } From 4462d454e87fba91a25b92b3bc4fef0a9ba6007c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 9 Oct 2019 10:34:17 +0300 Subject: [PATCH 22/72] Message padding improvements --- osu.Game/Overlays/Comments/CommentsContainer.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 5be1b6c1c4..b9effb39e8 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -16,6 +16,7 @@ namespace osu.Game.Overlays.Comments public class CommentsContainer : CompositeDrawable { private const float separator_height = 1.5f; + private const int padding = 40; private readonly CommentableType type; private readonly long id; @@ -92,7 +93,13 @@ namespace osu.Game.Overlays.Comments if (!c.IsDeleted && c.IsTopLevel) content.AddRange(new Drawable[] { - new DrawableComment(c), + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Right = padding }, + Child = new DrawableComment(c) + }, new Container { RelativeSizeAxes = Axes.X, From 0a56b041fdf7116ceb72d8a7251383f912961f5f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 9 Oct 2019 11:07:56 +0300 Subject: [PATCH 23/72] Implement ShowChildsButton --- .../Online/TestSceneCommentsContainer.cs | 3 +- .../Online/API/Requests/Responses/Comment.cs | 2 +- .../Overlays/Comments/CommentsContainer.cs | 9 +-- osu.Game/Overlays/Comments/DrawableComment.cs | 72 ++++++++++++------- .../Overlays/Comments/ShowChildsButton.cs | 34 +++++++++ 5 files changed, 85 insertions(+), 35 deletions(-) create mode 100644 osu.Game/Overlays/Comments/ShowChildsButton.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 7fbe9d7e8b..4187771963 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -20,7 +20,8 @@ namespace osu.Game.Tests.Visual.Online typeof(CommentsHeader), typeof(DrawableComment), typeof(HeaderButton), - typeof(SortSelector) + typeof(SortSelector), + typeof(ShowChildsButton) }; protected override bool UseOnlineAPI => true; diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index fb0aad0e0b..9a3dee30b4 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -87,7 +87,7 @@ namespace osu.Game.Online.API.Requests.Responses public string GetMessage() { - return MessageHTML.Replace("
", "").Replace("

", "").Replace("
", "").Replace("

", "").Replace("
", ""); + return MessageHTML.Replace("
", "").Replace("

", "").Replace("
", "").Replace("

", "").Replace("
", "").Replace(""", "\""); } } } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index b9effb39e8..5be1b6c1c4 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -16,7 +16,6 @@ namespace osu.Game.Overlays.Comments public class CommentsContainer : CompositeDrawable { private const float separator_height = 1.5f; - private const int padding = 40; private readonly CommentableType type; private readonly long id; @@ -93,13 +92,7 @@ namespace osu.Game.Overlays.Comments if (!c.IsDeleted && c.IsTopLevel) content.AddRange(new Drawable[] { - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Right = padding }, - Child = new DrawableComment(c) - }, + new DrawableComment(c), new Container { RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 41b30513a1..a66b8fcd44 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -10,11 +10,11 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Users.Drawables; using osu.Game.Graphics.Containers; using osu.Game.Utils; -using osu.Framework.Input.Events; using osu.Framework.Graphics.Cursor; using osu.Framework.Bindables; using osu.Framework.Graphics.Shapes; using osuTK.Graphics; +using System.Linq; namespace osu.Game.Overlays.Comments { @@ -23,6 +23,8 @@ namespace osu.Game.Overlays.Comments private const int avatar_size = 40; private const int margin = 10; private const int child_margin = 20; + private const int chevron_margin = 30; + private const int message_padding = 40; private const int duration = 200; private readonly BindableBool childExpanded = new BindableBool(true); @@ -93,25 +95,41 @@ namespace osu.Game.Overlays.Comments Spacing = new Vector2(0, 2), Children = new Drawable[] { - new FillFlowContainer + new Container { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(7, 0), + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Children = new Drawable[] { - username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + new FillFlowContainer { AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(7, 0), + Children = new Drawable[] + { + username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + { + AutoSizeAxes = Axes.Both, + }, + new ParentUsername(comment) + } }, - new ParentUsername(comment) + new ChevronButton(comment) + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Margin = new MarginPadding { Right = chevron_margin }, + Expanded = { BindTarget = childExpanded } + } } }, new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Text = comment.GetMessage() + Text = comment.GetMessage(), + Padding = new MarginPadding { Right = message_padding } } } } @@ -196,18 +214,34 @@ namespace osu.Game.Overlays.Comments } } - private class RepliesButton : Container + private class ChevronButton : ShowChildsButton + { + private readonly SpriteIcon icon; + + public ChevronButton(Comment comment) + { + Alpha = comment.IsTopLevel && comment.ChildComments.Any() ? 1 : 0; + Child = icon = new SpriteIcon + { + Size = new Vector2(12), + }; + } + + protected override void OnExpandedChanged(ValueChangedEvent expanded) + { + icon.Icon = expanded.NewValue ? FontAwesome.Solid.ChevronUp : FontAwesome.Solid.ChevronDown; + } + } + + private class RepliesButton : ShowChildsButton { private readonly SpriteText text; private readonly int count; - public readonly BindableBool Expanded = new BindableBool(true); - public RepliesButton(int count) { this.count = count; - AutoSizeAxes = Axes.Both; Alpha = count == 0 ? 0 : 1; Child = text = new SpriteText { @@ -215,22 +249,10 @@ namespace osu.Game.Overlays.Comments }; } - protected override void LoadComplete() - { - Expanded.BindValueChanged(onExpandedChanged, true); - base.LoadComplete(); - } - - private void onExpandedChanged(ValueChangedEvent expanded) + protected override void OnExpandedChanged(ValueChangedEvent expanded) { text.Text = $@"{(expanded.NewValue ? "[+]" : "[-]")} replies ({count})"; } - - protected override bool OnClick(ClickEvent e) - { - Expanded.Value = !Expanded.Value; - return base.OnClick(e); - } } private class ParentUsername : FillFlowContainer, IHasTooltip diff --git a/osu.Game/Overlays/Comments/ShowChildsButton.cs b/osu.Game/Overlays/Comments/ShowChildsButton.cs new file mode 100644 index 0000000000..81280a71b5 --- /dev/null +++ b/osu.Game/Overlays/Comments/ShowChildsButton.cs @@ -0,0 +1,34 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Graphics.Containers; +using osu.Framework.Input.Events; +using osu.Framework.Bindables; + +namespace osu.Game.Overlays.Comments +{ + public abstract class ShowChildsButton : OsuHoverContainer + { + public readonly BindableBool Expanded = new BindableBool(true); + + public ShowChildsButton() + { + AutoSizeAxes = Axes.Both; + } + + protected override void LoadComplete() + { + Expanded.BindValueChanged(OnExpandedChanged, true); + base.LoadComplete(); + } + + protected abstract void OnExpandedChanged(ValueChangedEvent expanded); + + protected override bool OnClick(ClickEvent e) + { + Expanded.Value = !Expanded.Value; + return base.OnClick(e); + } + } +} From a0dfbfe1488e9cbb66ad068828fdbf88069b24ec Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 9 Oct 2019 11:18:26 +0300 Subject: [PATCH 24/72] Handle parent usernames for legacy comments --- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index a66b8fcd44..6215f5e108 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -281,7 +281,7 @@ namespace osu.Game.Overlays.Comments new SpriteText { Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), - Text = comment.ParentComment?.User?.Username + Text = comment.ParentComment?.User?.Username ?? comment.ParentComment?.LegacyName } }; } From ad99a3236f052d2f2130a8c3559093f5c3c3699d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 9 Oct 2019 11:32:17 +0300 Subject: [PATCH 25/72] Handle edited comments --- .../Requests/Responses/APICommentsController.cs | 3 +++ osu.Game/Online/API/Requests/Responses/Comment.cs | 2 ++ osu.Game/Overlays/Comments/DrawableComment.cs | 14 +++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APICommentsController.cs b/osu.Game/Online/API/Requests/Responses/APICommentsController.cs index cf2e5e8a35..ca6062e371 100644 --- a/osu.Game/Online/API/Requests/Responses/APICommentsController.cs +++ b/osu.Game/Online/API/Requests/Responses/APICommentsController.cs @@ -63,6 +63,9 @@ namespace osu.Game.Online.API.Requests.Responses { if (c.UserId == u.Id) c.User = u; + + if (c.EditedById == u.Id) + c.EditedUser = u; }); }); } diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 9a3dee30b4..e420a585fe 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -81,6 +81,8 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"edited_by_id")] public long? EditedById { get; set; } + public User EditedUser { get; set; } + public bool IsTopLevel { get; set; } public bool IsDeleted { get; set; } diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 6215f5e108..92b59a985b 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -35,6 +35,7 @@ namespace osu.Game.Overlays.Comments { LinkFlowContainer username; FillFlowContainer childCommentsContainer; + FillFlowContainer info; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -140,7 +141,7 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.Both, }, - new FillFlowContainer + info = new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, @@ -188,6 +189,17 @@ namespace osu.Game.Overlays.Comments username.AddUserLink(comment.User); } + if (comment.EditedAt.HasValue) + { + info.Add(new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Text = $@"edited {HumanizerUtils.Humanize(comment.EditedAt.Value)} by {comment.EditedUser.Username}" + }); + } + comment.ChildComments.ForEach(c => { if (!c.IsDeleted) From b2bd78308dc4473d89d89244b873e5bd97b9f54f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 9 Oct 2019 12:18:49 +0300 Subject: [PATCH 26/72] Handle deleted comments --- .../Online/API/Requests/Responses/Comment.cs | 2 +- .../Overlays/Comments/CommentsContainer.cs | 24 +-- osu.Game/Overlays/Comments/DrawableComment.cs | 150 +++++++++++------- 3 files changed, 98 insertions(+), 78 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index e420a585fe..76a322e5c9 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -89,7 +89,7 @@ namespace osu.Game.Online.API.Requests.Responses public string GetMessage() { - return MessageHTML.Replace("
", "").Replace("

", "").Replace("
", "").Replace("

", "").Replace("
", "").Replace(""", "\""); + return IsDeleted ? @"deleted" : MessageHTML.Replace("
", "").Replace("

", "").Replace("
", "").Replace("

", "").Replace("
", "").Replace(""", "\""); } } } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 5be1b6c1c4..fb97f08a6e 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -15,12 +15,11 @@ namespace osu.Game.Overlays.Comments { public class CommentsContainer : CompositeDrawable { - private const float separator_height = 1.5f; - private readonly CommentableType type; private readonly long id; public readonly Bindable Sort = new Bindable(); + public readonly BindableBool ShowDeleted = new BindableBool(); [Resolved] private IAPIProvider api { get; set; } @@ -55,7 +54,8 @@ namespace osu.Game.Overlays.Comments { new CommentsHeader { - Sort = { BindTarget = Sort } + Sort = { BindTarget = Sort }, + ShowDeleted = { BindTarget = ShowDeleted } }, content = new FillFlowContainer { @@ -89,21 +89,9 @@ namespace osu.Game.Overlays.Comments { foreach (var c in response.Comments) { - if (!c.IsDeleted && c.IsTopLevel) - content.AddRange(new Drawable[] - { - new DrawableComment(c), - new Container - { - RelativeSizeAxes = Axes.X, - Height = separator_height, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.Gray1, - } - } - }); + if (c.IsTopLevel) + content.Add(new DrawableComment(c) + { ShowDeleted = { BindTarget = ShowDeleted } }); } } diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 92b59a985b..4092cbb177 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -26,19 +26,29 @@ namespace osu.Game.Overlays.Comments private const int chevron_margin = 30; private const int message_padding = 40; private const int duration = 200; + private const float separator_height = 1.5f; + + public readonly BindableBool ShowDeleted = new BindableBool(); private readonly BindableBool childExpanded = new BindableBool(true); private readonly Container childCommentsVisibilityContainer; + private readonly Comment comment; public DrawableComment(Comment comment) { LinkFlowContainer username; FillFlowContainer childCommentsContainer; FillFlowContainer info; + TextFlowContainer message; + GridContainer content; + VotePill votePill; + + this.comment = comment; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + Masking = true; InternalChild = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -46,7 +56,7 @@ namespace osu.Game.Overlays.Comments Direction = FillDirection.Vertical, Children = new Drawable[] { - new GridContainer + content = new GridContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -58,7 +68,6 @@ namespace osu.Game.Overlays.Comments }, RowDimensions = new[] { - new Dimension(GridSizeMode.AutoSize), new Dimension(GridSizeMode.AutoSize) }, Content = new[] @@ -73,10 +82,11 @@ namespace osu.Game.Overlays.Comments Spacing = new Vector2(5, 0), Children = new Drawable[] { - new VotePill(comment.VotesCount) + votePill = new VotePill(comment.VotesCount) { Anchor = Anchor.Centre, Origin = Anchor.Centre, + AlwaysPresent = true, }, new UpdateableAvatar(comment.User) { @@ -92,71 +102,53 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = margin / 2 }, - Spacing = new Vector2(0, 2), + Spacing = new Vector2(0, 3), Children = new Drawable[] { - new Container + new FillFlowContainer { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(7, 0), Children = new Drawable[] { - new FillFlowContainer + username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) { AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(7, 0), - Children = new Drawable[] - { - username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) - { - AutoSizeAxes = Axes.Both, - }, - new ParentUsername(comment) - } }, - new ChevronButton(comment) + new ParentUsername(comment), + new SpriteText { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Margin = new MarginPadding { Right = chevron_margin }, - Expanded = { BindTarget = childExpanded } + Alpha = comment.IsDeleted? 1 : 0, + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), + Text = @"deleted", } } }, - new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) + message = new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Text = comment.GetMessage(), Padding = new MarginPadding { Right = message_padding } - } - } - } - }, - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - }, - info = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12), - Text = HumanizerUtils.Humanize(comment.CreatedAt) }, - new RepliesButton(comment.RepliesCount) - { Expanded = { BindTarget = childExpanded } }, + info = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Text = HumanizerUtils.Humanize(comment.CreatedAt) + }, + new RepliesButton(comment.RepliesCount) + { Expanded = { BindTarget = childExpanded } }, + } + } } } } @@ -181,13 +173,9 @@ namespace osu.Game.Overlays.Comments }; if (comment.UserId == null) - { username.AddText(comment.LegacyName); - } else - { username.AddUserLink(comment.User); - } if (comment.EditedAt.HasValue) { @@ -200,15 +188,45 @@ namespace osu.Game.Overlays.Comments }); } - comment.ChildComments.ForEach(c => + if (!comment.IsDeleted) + message.Text = comment.GetMessage(); + else { - if (!c.IsDeleted) - childCommentsContainer.Add(new DrawableComment(c)); - }); + content.FadeColour(OsuColour.Gray(0.5f)); + votePill.Hide(); + } + + if (comment.IsTopLevel) + { + AddInternal(new Container + { + RelativeSizeAxes = Axes.X, + Height = separator_height, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.1f) + } + }); + + if (comment.ChildComments.Any()) + { + AddInternal(new ChevronButton(comment) + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Margin = new MarginPadding { Right = chevron_margin, Top = margin }, + Expanded = { BindTarget = childExpanded } + }); + } + } + + comment.ChildComments.ForEach(c => childCommentsContainer.Add(new DrawableComment(c))); } protected override void LoadComplete() { + ShowDeleted.BindValueChanged(onShowDeletedChanged, true); childExpanded.BindValueChanged(onChildExpandedChanged, true); base.LoadComplete(); } @@ -226,6 +244,20 @@ namespace osu.Game.Overlays.Comments } } + private void onShowDeletedChanged(ValueChangedEvent show) + { + if (comment.IsDeleted) + { + if (show.NewValue) + AutoSizeAxes = Axes.Y; + else + { + AutoSizeAxes = Axes.None; + this.ResizeHeightTo(0); + } + } + } + private class ChevronButton : ShowChildsButton { private readonly SpriteIcon icon; From 7e3c97f4962e0503b16527d13cc2fb545a3dc659 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 9 Oct 2019 13:37:07 +0300 Subject: [PATCH 27/72] Implement DeletedChildsPlaceholder component --- .../Online/TestSceneCommentsContainer.cs | 6 ++ .../Online/API/Requests/Responses/Comment.cs | 18 +++++ osu.Game/Overlays/Comments/DrawableComment.cs | 66 +++++++++++++++++-- 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 4187771963..8a6ec81d8e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -40,6 +40,12 @@ namespace osu.Game.Tests.Visual.Online scrollFlow.Clear(); scrollFlow.Add(new CommentsContainer(CommentableType.Beatmapset, 41823)); }); + + AddStep("Airman comments", () => + { + scrollFlow.Clear(); + scrollFlow.Add(new CommentsContainer(CommentableType.Beatmapset, 24313)); + }); } } } diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 76a322e5c9..6fea994cb9 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -5,6 +5,7 @@ using Newtonsoft.Json; using osu.Game.Users; using System; using System.Collections.Generic; +using System.Linq; namespace osu.Game.Online.API.Requests.Responses { @@ -91,5 +92,22 @@ namespace osu.Game.Online.API.Requests.Responses { return IsDeleted ? @"deleted" : MessageHTML.Replace("
", "").Replace("

", "").Replace("
", "").Replace("

", "").Replace("
", "").Replace(""", "\""); } + + public int GetDeletedChildsCount() + { + int count = 0; + + if (ChildComments.Any()) + ChildComments.ForEach(child => + { + if (child.IsDeleted) + count++; + }); + + if (IsDeleted) + count++; + + return count; + } } } diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 4092cbb177..60cae8c62a 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -27,6 +27,7 @@ namespace osu.Game.Overlays.Comments private const int message_padding = 40; private const int duration = 200; private const float separator_height = 1.5f; + private const int deleted_placeholder_margin = 80; public readonly BindableBool ShowDeleted = new BindableBool(); @@ -161,12 +162,26 @@ namespace osu.Game.Overlays.Comments AutoSizeDuration = duration, AutoSizeEasing = Easing.OutQuint, Masking = true, - Child = childCommentsContainer = new FillFlowContainer + Child = new FillFlowContainer { - Margin = new MarginPadding { Left = child_margin }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + childCommentsContainer = new FillFlowContainer + { + Margin = new MarginPadding { Left = child_margin }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical + }, + new DeletedChildsPlaceholder(comment.GetDeletedChildsCount()) + { + Margin = new MarginPadding { Bottom = margin, Left = deleted_placeholder_margin }, + ShowDeleted = { BindTarget = ShowDeleted } + } + } } } } @@ -221,7 +236,8 @@ namespace osu.Game.Overlays.Comments } } - comment.ChildComments.ForEach(c => childCommentsContainer.Add(new DrawableComment(c))); + comment.ChildComments.ForEach(c => childCommentsContainer.Add(new DrawableComment(c) + { ShowDeleted = { BindTarget = ShowDeleted } })); } protected override void LoadComplete() @@ -258,6 +274,48 @@ namespace osu.Game.Overlays.Comments } } + private class DeletedChildsPlaceholder : FillFlowContainer + { + public readonly BindableBool ShowDeleted = new BindableBool(); + + private readonly bool canBeVisible; + + public DeletedChildsPlaceholder(int count) + { + canBeVisible = count != 0; + + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + Spacing = new Vector2(3, 0); + Alpha = 0; + Children = new Drawable[] + { + new SpriteIcon + { + Icon = FontAwesome.Solid.Trash, + Size = new Vector2(14), + }, + new SpriteText + { + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), + Text = $@"{count} deleted comments" + } + }; + } + + protected override void LoadComplete() + { + ShowDeleted.BindValueChanged(onShowDeletedChanged, true); + base.LoadComplete(); + } + + private void onShowDeletedChanged(ValueChangedEvent showDeleted) + { + if (canBeVisible) + this.FadeTo(showDeleted.NewValue ? 0 : 1); + } + } + private class ChevronButton : ShowChildsButton { private readonly SpriteIcon icon; From c9d5bea0f1bd1a8a01c4fe2f08242e8292dffe22 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 9 Oct 2019 13:45:14 +0300 Subject: [PATCH 28/72] Remove animations --- osu.Game/Overlays/Comments/DrawableComment.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 60cae8c62a..94ec7a861a 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -25,7 +25,6 @@ namespace osu.Game.Overlays.Comments private const int child_margin = 20; private const int chevron_margin = 30; private const int message_padding = 40; - private const int duration = 200; private const float separator_height = 1.5f; private const int deleted_placeholder_margin = 80; @@ -159,8 +158,6 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - AutoSizeDuration = duration, - AutoSizeEasing = Easing.OutQuint, Masking = true, Child = new FillFlowContainer { @@ -249,14 +246,12 @@ namespace osu.Game.Overlays.Comments private void onChildExpandedChanged(ValueChangedEvent expanded) { - childCommentsVisibilityContainer.ClearTransforms(); - if (expanded.NewValue) childCommentsVisibilityContainer.AutoSizeAxes = Axes.Y; else { childCommentsVisibilityContainer.AutoSizeAxes = Axes.None; - childCommentsVisibilityContainer.ResizeHeightTo(0, duration, Easing.OutQuint); + childCommentsVisibilityContainer.ResizeHeightTo(0); } } From 107d39c3e97edb17e56bc9377d7e6cf76574ed43 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 9 Oct 2019 14:10:05 +0300 Subject: [PATCH 29/72] Add DeletedChildsPlaceholder to the bottom of the comments container --- .../Online/TestSceneCommentsContainer.cs | 3 +- .../Online/API/Requests/Responses/Comment.cs | 3 - .../Overlays/Comments/CommentsContainer.cs | 13 +++++ .../Comments/DeletedChildsPlaceholder.cs | 58 +++++++++++++++++++ osu.Game/Overlays/Comments/DrawableComment.cs | 46 +-------------- 5 files changed, 75 insertions(+), 48 deletions(-) create mode 100644 osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 8a6ec81d8e..342ba487f0 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -21,7 +21,8 @@ namespace osu.Game.Tests.Visual.Online typeof(DrawableComment), typeof(HeaderButton), typeof(SortSelector), - typeof(ShowChildsButton) + typeof(ShowChildsButton), + typeof(DeletedChildsPlaceholder) }; protected override bool UseOnlineAPI => true; diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 6fea994cb9..2334c86519 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -104,9 +104,6 @@ namespace osu.Game.Online.API.Requests.Responses count++; }); - if (IsDeleted) - count++; - return count; } } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index fb97f08a6e..bf68457988 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -93,6 +93,19 @@ namespace osu.Game.Overlays.Comments content.Add(new DrawableComment(c) { ShowDeleted = { BindTarget = ShowDeleted } }); } + + int deletedComments = 0; + + response.Comments.ForEach(comment => + { + if (comment.IsDeleted && comment.IsTopLevel) + deletedComments++; + }); + + content.Add(new DeletedChildsPlaceholder(deletedComments) + { + ShowDeleted = { BindTarget = ShowDeleted } + }); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs b/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs new file mode 100644 index 0000000000..d0e6c17ccb --- /dev/null +++ b/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs @@ -0,0 +1,58 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osu.Framework.Graphics.Sprites; +using osuTK; +using osu.Framework.Bindables; + +namespace osu.Game.Overlays.Comments +{ + public class DeletedChildsPlaceholder : FillFlowContainer + { + private const int deleted_placeholder_margin = 80; + private const int margin = 10; + + public readonly BindableBool ShowDeleted = new BindableBool(); + + private readonly bool canBeVisible; + + public DeletedChildsPlaceholder(int count) + { + canBeVisible = count != 0; + + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + Spacing = new Vector2(3, 0); + Margin = new MarginPadding { Vertical = margin, Left = deleted_placeholder_margin }; + Alpha = 0; + Children = new Drawable[] + { + new SpriteIcon + { + Icon = FontAwesome.Solid.Trash, + Size = new Vector2(14), + }, + new SpriteText + { + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), + Text = $@"{count} deleted comments" + } + }; + } + + protected override void LoadComplete() + { + ShowDeleted.BindValueChanged(onShowDeletedChanged, true); + base.LoadComplete(); + } + + private void onShowDeletedChanged(ValueChangedEvent showDeleted) + { + if (canBeVisible) + this.FadeTo(showDeleted.NewValue ? 0 : 1); + } + } +} diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 94ec7a861a..4af2e07227 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -26,7 +26,6 @@ namespace osu.Game.Overlays.Comments private const int chevron_margin = 30; private const int message_padding = 40; private const float separator_height = 1.5f; - private const int deleted_placeholder_margin = 80; public readonly BindableBool ShowDeleted = new BindableBool(); @@ -175,7 +174,6 @@ namespace osu.Game.Overlays.Comments }, new DeletedChildsPlaceholder(comment.GetDeletedChildsCount()) { - Margin = new MarginPadding { Bottom = margin, Left = deleted_placeholder_margin }, ShowDeleted = { BindTarget = ShowDeleted } } } @@ -214,6 +212,8 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.X, Height = separator_height, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, Child = new Box { RelativeSizeAxes = Axes.Both, @@ -269,48 +269,6 @@ namespace osu.Game.Overlays.Comments } } - private class DeletedChildsPlaceholder : FillFlowContainer - { - public readonly BindableBool ShowDeleted = new BindableBool(); - - private readonly bool canBeVisible; - - public DeletedChildsPlaceholder(int count) - { - canBeVisible = count != 0; - - AutoSizeAxes = Axes.Both; - Direction = FillDirection.Horizontal; - Spacing = new Vector2(3, 0); - Alpha = 0; - Children = new Drawable[] - { - new SpriteIcon - { - Icon = FontAwesome.Solid.Trash, - Size = new Vector2(14), - }, - new SpriteText - { - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), - Text = $@"{count} deleted comments" - } - }; - } - - protected override void LoadComplete() - { - ShowDeleted.BindValueChanged(onShowDeletedChanged, true); - base.LoadComplete(); - } - - private void onShowDeletedChanged(ValueChangedEvent showDeleted) - { - if (canBeVisible) - this.FadeTo(showDeleted.NewValue ? 0 : 1); - } - } - private class ChevronButton : ShowChildsButton { private readonly SpriteIcon icon; From f6b78ad6617508f49654c86696585b934c83a8d2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 10 Oct 2019 11:43:45 +0300 Subject: [PATCH 30/72] Overall cleanups --- .../Online/API/Requests/GetCommentsRequest.cs | 8 +-- .../Overlays/Comments/CommentsContainer.cs | 4 +- osu.Game/Overlays/Comments/CommentsHeader.cs | 3 +- .../Comments/DeletedChildsPlaceholder.cs | 3 +- osu.Game/Overlays/Comments/DrawableComment.cs | 59 +++++++------------ osu.Game/Overlays/Comments/SortSelector.cs | 8 ++- 6 files changed, 35 insertions(+), 50 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetCommentsRequest.cs b/osu.Game/Online/API/Requests/GetCommentsRequest.cs index 02a36f7aa2..fb30130ee9 100644 --- a/osu.Game/Online/API/Requests/GetCommentsRequest.cs +++ b/osu.Game/Online/API/Requests/GetCommentsRequest.cs @@ -4,6 +4,7 @@ using osu.Framework.IO.Network; using Humanizer; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Comments; namespace osu.Game.Online.API.Requests { @@ -43,11 +44,4 @@ namespace osu.Game.Online.API.Requests Beatmapset, NewsPost } - - public enum SortCommentsBy - { - New, - Old, - Top - } } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index bf68457988..314376f5ff 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -91,7 +91,9 @@ namespace osu.Game.Overlays.Comments { if (c.IsTopLevel) content.Add(new DrawableComment(c) - { ShowDeleted = { BindTarget = ShowDeleted } }); + { + ShowDeleted = { BindTarget = ShowDeleted } + }); } int deletedComments = 0; diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index 90a6f44d6b..6e9864f153 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -3,7 +3,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; -using osu.Game.Online.API.Requests; using osu.Framework.Graphics; using osu.Framework.Bindables; using osu.Framework.Graphics.Shapes; @@ -62,7 +61,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Current = { BindTarget = Sort } + Current = Sort } } }, diff --git a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs b/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs index d0e6c17ccb..7aae42908e 100644 --- a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs +++ b/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs @@ -7,6 +7,7 @@ using osu.Game.Graphics; using osu.Framework.Graphics.Sprites; using osuTK; using osu.Framework.Bindables; +using System.Linq; namespace osu.Game.Overlays.Comments { @@ -38,7 +39,7 @@ namespace osu.Game.Overlays.Comments new SpriteText { Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), - Text = $@"{count} deleted comments" + Text = $@"{count} deleted comment{(count.ToString().ToCharArray().Last() == '1' ? "" : "s")}" } }; } diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 4af2e07227..fd7f874304 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Comments private readonly BindableBool childExpanded = new BindableBool(true); - private readonly Container childCommentsVisibilityContainer; + private readonly FillFlowContainer childCommentsVisibilityContainer; private readonly Comment comment; public DrawableComment(Comment comment) @@ -47,7 +47,6 @@ namespace osu.Game.Overlays.Comments RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Masking = true; InternalChild = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -145,7 +144,9 @@ namespace osu.Game.Overlays.Comments Text = HumanizerUtils.Humanize(comment.CreatedAt) }, new RepliesButton(comment.RepliesCount) - { Expanded = { BindTarget = childExpanded } }, + { + Expanded = { BindTarget = childExpanded } + }, } } } @@ -153,29 +154,23 @@ namespace osu.Game.Overlays.Comments } } }, - childCommentsVisibilityContainer = new Container + childCommentsVisibilityContainer = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Masking = true, - Child = new FillFlowContainer + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] + childCommentsContainer = new FillFlowContainer { - childCommentsContainer = new FillFlowContainer - { - Margin = new MarginPadding { Left = child_margin }, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical - }, - new DeletedChildsPlaceholder(comment.GetDeletedChildsCount()) - { - ShowDeleted = { BindTarget = ShowDeleted } - } + Margin = new MarginPadding { Left = child_margin }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical + }, + new DeletedChildsPlaceholder(comment.GetDeletedChildsCount()) + { + ShowDeleted = { BindTarget = ShowDeleted } } } } @@ -234,7 +229,9 @@ namespace osu.Game.Overlays.Comments } comment.ChildComments.ForEach(c => childCommentsContainer.Add(new DrawableComment(c) - { ShowDeleted = { BindTarget = ShowDeleted } })); + { + ShowDeleted = { BindTarget = ShowDeleted } + })); } protected override void LoadComplete() @@ -246,27 +243,13 @@ namespace osu.Game.Overlays.Comments private void onChildExpandedChanged(ValueChangedEvent expanded) { - if (expanded.NewValue) - childCommentsVisibilityContainer.AutoSizeAxes = Axes.Y; - else - { - childCommentsVisibilityContainer.AutoSizeAxes = Axes.None; - childCommentsVisibilityContainer.ResizeHeightTo(0); - } + childCommentsVisibilityContainer.FadeTo(expanded.NewValue ? 1 : 0); } private void onShowDeletedChanged(ValueChangedEvent show) { if (comment.IsDeleted) - { - if (show.NewValue) - AutoSizeAxes = Axes.Y; - else - { - AutoSizeAxes = Axes.None; - this.ResizeHeightTo(0); - } - } + this.FadeTo(show.NewValue ? 1 : 0); } private class ChevronButton : ShowChildsButton diff --git a/osu.Game/Overlays/Comments/SortSelector.cs b/osu.Game/Overlays/Comments/SortSelector.cs index 4425145c3e..cb95a758ff 100644 --- a/osu.Game/Overlays/Comments/SortSelector.cs +++ b/osu.Game/Overlays/Comments/SortSelector.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Online.API.Requests; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; @@ -72,4 +71,11 @@ namespace osu.Game.Overlays.Comments } } } + + public enum SortCommentsBy + { + New, + Old, + Top + } } From 64f62bd2bfbccd702bb39039bc77166eb16a1b0b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 10 Oct 2019 12:06:25 +0300 Subject: [PATCH 31/72] Implement CommentsHeader component --- .../Visual/Online/TestSceneCommentsHeader.cs | 39 +++++ osu.Game/Overlays/Comments/CommentsHeader.cs | 137 ++++++++++++++++++ osu.Game/Overlays/Comments/HeaderButton.cs | 72 +++++++++ osu.Game/Overlays/Comments/SortSelector.cs | 106 ++++++++++++++ osu.Game/osu.Game.csproj | 3 + 5 files changed, 357 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs create mode 100644 osu.Game/Overlays/Comments/CommentsHeader.cs create mode 100644 osu.Game/Overlays/Comments/HeaderButton.cs create mode 100644 osu.Game/Overlays/Comments/SortSelector.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs new file mode 100644 index 0000000000..52318605d9 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs @@ -0,0 +1,39 @@ +// 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 NUnit.Framework; +using osu.Framework.Bindables; +using osu.Game.Overlays.Comments; + +namespace osu.Game.Tests.Visual.Online +{ + [TestFixture] + public class TestSceneCommentsHeader : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(CommentsHeader), + typeof(HeaderButton), + typeof(SortSelector), + }; + + private readonly Bindable sort = new Bindable(); + private readonly BindableBool showDeleted = new BindableBool(); + + public TestSceneCommentsHeader() + { + Add(new CommentsHeader + { + Sort = { BindTarget = sort }, + ShowDeleted = { BindTarget = showDeleted } + }); + + AddStep("Trigger ShowDeleted", () => showDeleted.Value = !showDeleted.Value); + AddStep("Select old", () => sort.Value = SortCommentsBy.Old); + AddStep("Select new", () => sort.Value = SortCommentsBy.New); + AddStep("Select top", () => sort.Value = SortCommentsBy.Top); + } + } +} diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs new file mode 100644 index 0000000000..c21ec90048 --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -0,0 +1,137 @@ +// 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.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Framework.Graphics.Sprites; +using osuTK; +using osu.Framework.Input.Events; + +namespace osu.Game.Overlays.Comments +{ + public class CommentsHeader : CompositeDrawable + { + private const int height = 40; + private const int spacing = 10; + private const int padding = 50; + private const int text_size = 14; + + public readonly Bindable Sort = new Bindable(); + public readonly BindableBool ShowDeleted = new BindableBool(); + + private readonly Box background; + + public CommentsHeader() + { + RelativeSizeAxes = Axes.X; + Height = height; + AddRangeInternal(new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = padding }, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(spacing, 0), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Children = new Drawable[] + { + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: text_size), + Text = @"Sort by" + }, + new SortSelector + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Current = Sort + } + } + }, + new ShowDeletedButton + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Checked = { BindTarget = ShowDeleted } + } + } + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray3; + } + + private class ShowDeletedButton : HeaderButton + { + private const int spacing = 5; + + public readonly BindableBool Checked = new BindableBool(); + + private readonly SpriteIcon checkboxIcon; + + public ShowDeletedButton() + { + Add(new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(spacing, 0), + Children = new Drawable[] + { + checkboxIcon = new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(10), + }, + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: text_size), + Text = @"Show deleted" + } + }, + }); + } + + protected override void LoadComplete() + { + Checked.BindValueChanged(onCheckedChanged, true); + base.LoadComplete(); + } + + private void onCheckedChanged(ValueChangedEvent isChecked) + { + checkboxIcon.Icon = isChecked.NewValue ? FontAwesome.Solid.CheckSquare : FontAwesome.Regular.Square; + } + + protected override bool OnClick(ClickEvent e) + { + Checked.Value = !Checked.Value; + return base.OnClick(e); + } + } + } +} diff --git a/osu.Game/Overlays/Comments/HeaderButton.cs b/osu.Game/Overlays/Comments/HeaderButton.cs new file mode 100644 index 0000000000..231a364759 --- /dev/null +++ b/osu.Game/Overlays/Comments/HeaderButton.cs @@ -0,0 +1,72 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Framework.Input.Events; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Comments +{ + public class HeaderButton : Container + { + private const int height = 20; + private const int corner_radius = 3; + private const int margin = 10; + private const int duration = 200; + + protected override Container Content => content; + + private readonly Box background; + private readonly Container content; + + public HeaderButton() + { + AutoSizeAxes = Axes.X; + Height = height; + Masking = true; + CornerRadius = corner_radius; + AddRangeInternal(new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + }, + content = new Container + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Horizontal = margin } + }, + new HoverClickSounds(), + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray4; + } + + protected override bool OnHover(HoverEvent e) + { + FadeInBackground(); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + FadeOutBackground(); + } + + protected void FadeInBackground() => background.FadeIn(duration, Easing.OutQuint); + + protected void FadeOutBackground() => background.FadeOut(duration, Easing.OutQuint); + } +} diff --git a/osu.Game/Overlays/Comments/SortSelector.cs b/osu.Game/Overlays/Comments/SortSelector.cs new file mode 100644 index 0000000000..b4e29477d7 --- /dev/null +++ b/osu.Game/Overlays/Comments/SortSelector.cs @@ -0,0 +1,106 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osuTK; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Framework.Bindables; +using osu.Framework.Allocation; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Comments +{ + public class SortSelector : OsuTabControl + { + private const int spacing = 5; + + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(SortCommentsBy value) => new SortTabItem(value); + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(spacing, 0), + }; + + public SortSelector() + { + AutoSizeAxes = Axes.Both; + } + + private class SortTabItem : TabItem + { + private readonly TabContent content; + + public SortTabItem(SortCommentsBy value) + : base(value) + { + AutoSizeAxes = Axes.Both; + Child = content = new TabContent(value) + { + Active = { BindTarget = Active } + }; + } + + protected override void OnActivated() => content.Activate(); + + protected override void OnDeactivated() => content.Deactivate(); + + private class TabContent : HeaderButton + { + private const int text_size = 14; + + public readonly BindableBool Active = new BindableBool(); + + [Resolved] + private OsuColour colours { get; set; } + + private readonly SpriteText text; + + public TabContent(SortCommentsBy value) + { + Add(text = new SpriteText + { + Font = OsuFont.GetFont(size: text_size), + Text = value.ToString() + }); + } + + public void Activate() + { + FadeInBackground(); + text.Font = text.Font.With(weight: FontWeight.Bold); + text.Colour = colours.BlueLighter; + } + + public void Deactivate() + { + if (!IsHovered) + FadeOutBackground(); + + text.Font = text.Font.With(weight: FontWeight.Medium); + text.Colour = Color4.White; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + if (!Active.Value) base.OnHoverLost(e); + } + } + } + } + + public enum SortCommentsBy + { + New, + Old, + Top + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8cbc8b0af3..28d5dd796c 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -32,4 +32,7 @@ + + + From fe7b4037f79ed180a3ff8f682ffdc41d9e006e8e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 10 Oct 2019 13:24:22 +0300 Subject: [PATCH 32/72] CI fix --- osu.Game/Overlays/Comments/CommentsHeader.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index c21ec90048..fb507e6cb2 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -84,8 +84,6 @@ namespace osu.Game.Overlays.Comments private class ShowDeletedButton : HeaderButton { - private const int spacing = 5; - public readonly BindableBool Checked = new BindableBool(); private readonly SpriteIcon checkboxIcon; @@ -96,7 +94,7 @@ namespace osu.Game.Overlays.Comments { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - Spacing = new Vector2(spacing, 0), + Spacing = new Vector2(5, 0), Children = new Drawable[] { checkboxIcon = new SpriteIcon From b45e7246b85a859fb2a6a2306914b37999d76ff8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 10 Oct 2019 15:56:08 +0300 Subject: [PATCH 33/72] Rename SortCommentsBy to CommentsSortCriteria --- .../Visual/Online/TestSceneCommentsHeader.cs | 8 ++++---- osu.Game/Overlays/Comments/CommentsHeader.cs | 2 +- osu.Game/Overlays/Comments/SortSelector.cs | 14 +++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs index 52318605d9..949dbbe5c4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Online typeof(SortSelector), }; - private readonly Bindable sort = new Bindable(); + private readonly Bindable sort = new Bindable(); private readonly BindableBool showDeleted = new BindableBool(); public TestSceneCommentsHeader() @@ -31,9 +31,9 @@ namespace osu.Game.Tests.Visual.Online }); AddStep("Trigger ShowDeleted", () => showDeleted.Value = !showDeleted.Value); - AddStep("Select old", () => sort.Value = SortCommentsBy.Old); - AddStep("Select new", () => sort.Value = SortCommentsBy.New); - AddStep("Select top", () => sort.Value = SortCommentsBy.Top); + AddStep("Select old", () => sort.Value = CommentsSortCriteria.Old); + AddStep("Select new", () => sort.Value = CommentsSortCriteria.New); + AddStep("Select top", () => sort.Value = CommentsSortCriteria.Top); } } } diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index fb507e6cb2..2bd2bf21a6 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Comments private const int padding = 50; private const int text_size = 14; - public readonly Bindable Sort = new Bindable(); + public readonly Bindable Sort = new Bindable(); public readonly BindableBool ShowDeleted = new BindableBool(); private readonly Box background; diff --git a/osu.Game/Overlays/Comments/SortSelector.cs b/osu.Game/Overlays/Comments/SortSelector.cs index b4e29477d7..100ae83291 100644 --- a/osu.Game/Overlays/Comments/SortSelector.cs +++ b/osu.Game/Overlays/Comments/SortSelector.cs @@ -15,13 +15,13 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Comments { - public class SortSelector : OsuTabControl + public class SortSelector : OsuTabControl { private const int spacing = 5; - protected override Dropdown CreateDropdown() => null; + protected override Dropdown CreateDropdown() => null; - protected override TabItem CreateTabItem(SortCommentsBy value) => new SortTabItem(value); + protected override TabItem CreateTabItem(CommentsSortCriteria value) => new SortTabItem(value); protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer { @@ -35,11 +35,11 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both; } - private class SortTabItem : TabItem + private class SortTabItem : TabItem { private readonly TabContent content; - public SortTabItem(SortCommentsBy value) + public SortTabItem(CommentsSortCriteria value) : base(value) { AutoSizeAxes = Axes.Both; @@ -64,7 +64,7 @@ namespace osu.Game.Overlays.Comments private readonly SpriteText text; - public TabContent(SortCommentsBy value) + public TabContent(CommentsSortCriteria value) { Add(text = new SpriteText { @@ -97,7 +97,7 @@ namespace osu.Game.Overlays.Comments } } - public enum SortCommentsBy + public enum CommentsSortCriteria { New, Old, From f6b138fe6ed3aa230c1753b4ce0bb7bf576dcfef Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 12 Oct 2019 15:03:24 +0300 Subject: [PATCH 34/72] Remove useless ItemGroup --- osu.Game/osu.Game.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4e6511385e..ab7c40116b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -32,7 +32,4 @@ - - - From 4d971e49ff050685a4498cc31b941fd426f41ef1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 13 Oct 2019 11:50:27 +0300 Subject: [PATCH 35/72] Colours update --- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- osu.Game/Overlays/Comments/DrawableComment.cs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 265793226e..b66374cb69 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -113,7 +113,7 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load() { - background.Colour = colours.Gray3; + background.Colour = colours.Gray2; } } } diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index fd7f874304..4617f6f86e 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -13,7 +13,6 @@ using osu.Game.Utils; using osu.Framework.Graphics.Cursor; using osu.Framework.Bindables; using osu.Framework.Graphics.Shapes; -using osuTK.Graphics; using System.Linq; namespace osu.Game.Overlays.Comments @@ -134,6 +133,7 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(10, 0), + Colour = OsuColour.Gray(0.7f), Children = new Drawable[] { new SpriteText @@ -262,6 +262,7 @@ namespace osu.Game.Overlays.Comments Child = icon = new SpriteIcon { Size = new Vector2(12), + Colour = OsuColour.Gray(0.7f) }; } @@ -340,7 +341,7 @@ namespace osu.Game.Overlays.Comments new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black + Colour = OsuColour.Gray(0.05f) }, new SpriteText { From 795ce8146895f435744a41e929a4621d0a212f16 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 13 Oct 2019 12:10:01 +0300 Subject: [PATCH 36/72] Use async loading for comment pages --- .../Overlays/Comments/CommentsContainer.cs | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index b66374cb69..3b997540c4 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -10,6 +10,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; +using System.Threading; namespace osu.Game.Overlays.Comments { @@ -28,6 +29,7 @@ namespace osu.Game.Overlays.Comments private OsuColour colours { get; set; } private GetCommentsRequest request; + private CancellationTokenSource loadCancellation; private readonly Box background; private readonly FillFlowContainer content; @@ -79,7 +81,7 @@ namespace osu.Game.Overlays.Comments private void getComments() { request?.Cancel(); - content.Clear(); + loadCancellation?.Cancel(); request = new GetCommentsRequest(type, id, Sort.Value); request.Success += onSuccess; api.Queue(request); @@ -87,27 +89,43 @@ namespace osu.Game.Overlays.Comments private void onSuccess(APICommentsController response) { + loadCancellation = new CancellationTokenSource(); + + FillFlowContainer page = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + }; + foreach (var c in response.Comments) { if (c.IsTopLevel) - content.Add(new DrawableComment(c) + page.Add(new DrawableComment(c) { ShowDeleted = { BindTarget = ShowDeleted } }); } - int deletedComments = 0; - - response.Comments.ForEach(comment => + LoadComponentAsync(page, loaded => { - if (comment.IsDeleted && comment.IsTopLevel) - deletedComments++; - }); + content.Clear(); - content.Add(new DeletedChildsPlaceholder(deletedComments) - { - ShowDeleted = { BindTarget = ShowDeleted } - }); + content.Add(loaded); + + int deletedComments = 0; + + response.Comments.ForEach(comment => + { + if (comment.IsDeleted && comment.IsTopLevel) + deletedComments++; + }); + + content.Add(new DeletedChildsPlaceholder(deletedComments) + { + ShowDeleted = { BindTarget = ShowDeleted } + }); + }, loadCancellation.Token); } [BackgroundDependencyLoader] From 60954f969d77f6350b0f63903cf2f5696046c248 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 13 Oct 2019 12:38:50 +0300 Subject: [PATCH 37/72] DeletedChildsPlaceholder refactor --- .../Overlays/Comments/CommentsContainer.cs | 33 ++++++++++++++++--- .../Comments/DeletedChildsPlaceholder.cs | 30 ++++++++++++----- osu.Game/Overlays/Comments/DrawableComment.cs | 5 ++- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 3b997540c4..1fca9ca5e5 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -33,6 +33,8 @@ namespace osu.Game.Overlays.Comments private readonly Box background; private readonly FillFlowContainer content; + private readonly FillFlowContainer footer; + private readonly DeletedChildsPlaceholder deletedChildsPlaceholder; public CommentsContainer(CommentableType type, long id) { @@ -64,6 +66,32 @@ namespace osu.Game.Overlays.Comments RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.2f) + }, + footer = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + deletedChildsPlaceholder = new DeletedChildsPlaceholder + { + ShowDeleted = { BindTarget = ShowDeleted } + } + } + } + } } } } @@ -121,10 +149,7 @@ namespace osu.Game.Overlays.Comments deletedComments++; }); - content.Add(new DeletedChildsPlaceholder(deletedComments) - { - ShowDeleted = { BindTarget = ShowDeleted } - }); + deletedChildsPlaceholder.DeletedCount.Value = deletedComments; }, loadCancellation.Token); } diff --git a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs b/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs index 7aae42908e..b5dcf433f1 100644 --- a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs +++ b/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs @@ -17,18 +17,18 @@ namespace osu.Game.Overlays.Comments private const int margin = 10; public readonly BindableBool ShowDeleted = new BindableBool(); + public readonly BindableInt DeletedCount = new BindableInt(); - private readonly bool canBeVisible; + private bool canBeShown; - public DeletedChildsPlaceholder(int count) + private readonly SpriteText countText; + + public DeletedChildsPlaceholder() { - canBeVisible = count != 0; - AutoSizeAxes = Axes.Both; Direction = FillDirection.Horizontal; Spacing = new Vector2(3, 0); Margin = new MarginPadding { Vertical = margin, Left = deleted_placeholder_margin }; - Alpha = 0; Children = new Drawable[] { new SpriteIcon @@ -36,24 +36,38 @@ namespace osu.Game.Overlays.Comments Icon = FontAwesome.Solid.Trash, Size = new Vector2(14), }, - new SpriteText + countText = new SpriteText { Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), - Text = $@"{count} deleted comment{(count.ToString().ToCharArray().Last() == '1' ? "" : "s")}" } }; } protected override void LoadComplete() { + DeletedCount.BindValueChanged(onCountChanged, true); ShowDeleted.BindValueChanged(onShowDeletedChanged, true); base.LoadComplete(); } private void onShowDeletedChanged(ValueChangedEvent showDeleted) { - if (canBeVisible) + if (canBeShown) this.FadeTo(showDeleted.NewValue ? 0 : 1); } + + private void onCountChanged(ValueChangedEvent count) + { + canBeShown = count.NewValue != 0; + + if (!canBeShown) + { + Hide(); + return; + } + + countText.Text = $@"{count.NewValue} deleted comment{(count.NewValue.ToString().ToCharArray().Last() == '1' ? "" : "s")}"; + Show(); + } } } diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 4617f6f86e..8c356a6156 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -32,6 +32,7 @@ namespace osu.Game.Overlays.Comments private readonly FillFlowContainer childCommentsVisibilityContainer; private readonly Comment comment; + private readonly DeletedChildsPlaceholder deletedChildsPlaceholder; public DrawableComment(Comment comment) { @@ -168,7 +169,7 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical }, - new DeletedChildsPlaceholder(comment.GetDeletedChildsCount()) + deletedChildsPlaceholder = new DeletedChildsPlaceholder { ShowDeleted = { BindTarget = ShowDeleted } } @@ -177,6 +178,8 @@ namespace osu.Game.Overlays.Comments } }; + deletedChildsPlaceholder.DeletedCount.Value = comment.GetDeletedChildsCount(); + if (comment.UserId == null) username.AddText(comment.LegacyName); else From a44cc2e70baf13f3f90c6635d23bb2645b06841f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 13 Oct 2019 14:43:30 +0300 Subject: [PATCH 38/72] Implement CommentsShowMoreButton --- .../Online/TestSceneCommentsContainer.cs | 6 ++ .../Visual/Online/TestSceneShowMoreButton.cs | 5 +- .../UserInterface}/ShowMoreButton.cs | 67 ++++++++++--------- .../Overlays/Comments/CommentsContainer.cs | 54 ++++++++++++--- .../Comments/CommentsShowMoreButton.cs | 32 +++++++++ .../Comments/DeletedChildsPlaceholder.cs | 8 ++- .../Profile/Sections/PaginatedContainer.cs | 4 +- .../Profile/Sections/ProfileShowMoreButton.cs | 20 ++++++ 8 files changed, 151 insertions(+), 45 deletions(-) rename osu.Game/{Overlays/Profile/Sections => Graphics/UserInterface}/ShowMoreButton.cs (77%) create mode 100644 osu.Game/Overlays/Comments/CommentsShowMoreButton.cs create mode 100644 osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 342ba487f0..a283663a4a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -47,6 +47,12 @@ namespace osu.Game.Tests.Visual.Online scrollFlow.Clear(); scrollFlow.Add(new CommentsContainer(CommentableType.Beatmapset, 24313)); }); + + AddStep("lazer build comments", () => + { + scrollFlow.Clear(); + scrollFlow.Add(new CommentsContainer(CommentableType.Build, 4772)); + }); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs b/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs index bccb263600..8d4955abf0 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs @@ -5,6 +5,7 @@ using osu.Game.Overlays.Profile.Sections; using System; using System.Collections.Generic; using osu.Framework.Graphics; +using osu.Game.Graphics.UserInterface; namespace osu.Game.Tests.Visual.Online { @@ -17,11 +18,11 @@ namespace osu.Game.Tests.Visual.Online public TestSceneShowMoreButton() { - ShowMoreButton button = null; + ProfileShowMoreButton button = null; int fireCount = 0; - Add(button = new ShowMoreButton + Add(button = new ProfileShowMoreButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs similarity index 77% rename from osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs rename to osu.Game/Graphics/UserInterface/ShowMoreButton.cs index cf4e1c0dde..627ad995e8 100644 --- a/osu.Game/Overlays/Profile/Sections/ShowMoreButton.cs +++ b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs @@ -1,30 +1,36 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; -using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osuTK; +using osuTK.Graphics; using System.Collections.Generic; -namespace osu.Game.Overlays.Profile.Sections +namespace osu.Game.Graphics.UserInterface { public class ShowMoreButton : OsuHoverContainer { private const float fade_duration = 200; - private readonly Box background; - private readonly LoadingAnimation loading; - private readonly FillFlowContainer content; + private Color4 chevronIconColour; - protected override IEnumerable EffectTargets => new[] { background }; + public Color4 ChevronIconColour + { + get => chevronIconColour; + set { chevronIconColour = leftChevron.AccentColour = rightChevron.AccentColour = value; } + } + + public string Text + { + get => text.Text; + set { text.Text = value; } + } private bool isLoading; @@ -33,26 +39,32 @@ namespace osu.Game.Overlays.Profile.Sections get => isLoading; set { - if (isLoading == value) - return; - isLoading = value; Enabled.Value = !isLoading; if (value) { - loading.FadeIn(fade_duration, Easing.OutQuint); + loading.Show(); content.FadeOut(fade_duration, Easing.OutQuint); } else { - loading.FadeOut(fade_duration, Easing.OutQuint); + loading.Hide(); content.FadeIn(fade_duration, Easing.OutQuint); } } } + private readonly Box background; + private readonly LoadingAnimation loading; + private readonly FillFlowContainer content; + private readonly ChevronIcon leftChevron; + private readonly ChevronIcon rightChevron; + private readonly SpriteText text; + + protected override IEnumerable EffectTargets => new[] { background }; + public ShowMoreButton() { AutoSizeAxes = Axes.Both; @@ -77,15 +89,15 @@ namespace osu.Game.Overlays.Profile.Sections Spacing = new Vector2(7), Children = new Drawable[] { - new ChevronIcon(), - new OsuSpriteText + leftChevron = new ChevronIcon(), + text = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), Text = "show more".ToUpper(), }, - new ChevronIcon(), + rightChevron = new ChevronIcon(), } }, loading = new LoadingAnimation @@ -99,13 +111,6 @@ namespace osu.Game.Overlays.Profile.Sections }; } - [BackgroundDependencyLoader] - private void load(OsuColour colors) - { - IdleColour = colors.GreySeafoamDark; - HoverColour = colors.GreySeafoam; - } - protected override bool OnClick(ClickEvent e) { if (!Enabled.Value) @@ -126,6 +131,14 @@ namespace osu.Game.Overlays.Profile.Sections { private const int icon_size = 8; + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set { accentColour = Colour = value; } + } + public ChevronIcon() { Anchor = Anchor.Centre; @@ -133,12 +146,6 @@ namespace osu.Game.Overlays.Profile.Sections Size = new Vector2(icon_size); Icon = FontAwesome.Solid.ChevronDown; } - - [BackgroundDependencyLoader] - private void load(OsuColour colors) - { - Colour = colors.Yellow; - } } } } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 1fca9ca5e5..1111313d7f 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -16,6 +16,8 @@ namespace osu.Game.Overlays.Comments { public class CommentsContainer : CompositeDrawable { + private const int more_button_margin = 5; + private readonly CommentableType type; private readonly long id; @@ -30,11 +32,13 @@ namespace osu.Game.Overlays.Comments private GetCommentsRequest request; private CancellationTokenSource loadCancellation; + private int currentPage; + private int loadedTopLevelComments; private readonly Box background; private readonly FillFlowContainer content; - private readonly FillFlowContainer footer; private readonly DeletedChildsPlaceholder deletedChildsPlaceholder; + private readonly CommentsShowMoreButton moreButton; public CommentsContainer(CommentableType type, long id) { @@ -78,7 +82,7 @@ namespace osu.Game.Overlays.Comments RelativeSizeAxes = Axes.Both, Colour = OsuColour.Gray(0.2f) }, - footer = new FillFlowContainer + new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -88,6 +92,18 @@ namespace osu.Game.Overlays.Comments deletedChildsPlaceholder = new DeletedChildsPlaceholder { ShowDeleted = { BindTarget = ShowDeleted } + }, + new Container + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Child = moreButton = new CommentsShowMoreButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding(more_button_margin), + Action = () => getComments(false), + } } } } @@ -106,16 +122,25 @@ namespace osu.Game.Overlays.Comments private void onSortChanged(ValueChangedEvent sort) => getComments(); - private void getComments() + private void getComments(bool initial = true) { + if (initial) + { + currentPage = 1; + loadedTopLevelComments = 0; + deletedChildsPlaceholder.DeletedCount.Value = 0; + moreButton.IsLoading = true; + content.Clear(); + } + request?.Cancel(); loadCancellation?.Cancel(); - request = new GetCommentsRequest(type, id, Sort.Value); - request.Success += onSuccess; + request = new GetCommentsRequest(type, id, Sort.Value, currentPage++); + request.Success += response => onSuccess(response, initial); api.Queue(request); } - private void onSuccess(APICommentsController response) + private void onSuccess(APICommentsController response, bool initial) { loadCancellation = new CancellationTokenSource(); @@ -137,8 +162,6 @@ namespace osu.Game.Overlays.Comments LoadComponentAsync(page, loaded => { - content.Clear(); - content.Add(loaded); int deletedComments = 0; @@ -149,7 +172,20 @@ namespace osu.Game.Overlays.Comments deletedComments++; }); - deletedChildsPlaceholder.DeletedCount.Value = deletedComments; + deletedChildsPlaceholder.DeletedCount.Value = initial ? deletedComments : deletedChildsPlaceholder.DeletedCount.Value + deletedComments; + + if (response.HasMore) + { + response.Comments.ForEach(comment => + { + if (comment.IsTopLevel) + loadedTopLevelComments++; + }); + moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments; + moreButton.IsLoading = false; + } + moreButton.FadeTo(response.HasMore ? 1 : 0); + }, loadCancellation.Token); } diff --git a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs new file mode 100644 index 0000000000..b0174e7b1a --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Bindables; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Comments +{ + public class CommentsShowMoreButton : ShowMoreButton + { + public readonly BindableInt Current = new BindableInt(); + + public CommentsShowMoreButton() + { + IdleColour = OsuColour.Gray(0.3f); + HoverColour = OsuColour.Gray(0.4f); + ChevronIconColour = OsuColour.Gray(0.5f); + } + + protected override void LoadComplete() + { + Current.BindValueChanged(onCurrentChanged, true); + base.LoadComplete(); + } + + private void onCurrentChanged(ValueChangedEvent count) + { + Text = $@"Show More ({count.NewValue})".ToUpper(); + } + } +} diff --git a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs b/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs index b5dcf433f1..d626c13afd 100644 --- a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs +++ b/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs @@ -7,7 +7,6 @@ using osu.Game.Graphics; using osu.Framework.Graphics.Sprites; using osuTK; using osu.Framework.Bindables; -using System.Linq; namespace osu.Game.Overlays.Comments { @@ -66,7 +65,12 @@ namespace osu.Game.Overlays.Comments return; } - countText.Text = $@"{count.NewValue} deleted comment{(count.NewValue.ToString().ToCharArray().Last() == '1' ? "" : "s")}"; + string str = $@"{count.NewValue} deleted comment"; + + if (!(count.NewValue.ToString().EndsWith("1") && !count.NewValue.ToString().EndsWith("11"))) + str += "s"; + + countText.Text = str; Show(); } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs index bb221bd43a..dc1a847b14 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedContainer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Sections { public abstract class PaginatedContainer : FillFlowContainer { - private readonly ShowMoreButton moreButton; + private readonly ProfileShowMoreButton moreButton; private readonly OsuSpriteText missingText; private APIRequest> retrievalRequest; private CancellationTokenSource loadCancellation; @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Profile.Sections RelativeSizeAxes = Axes.X, Spacing = new Vector2(0, 2), }, - moreButton = new ShowMoreButton + moreButton = new ProfileShowMoreButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs b/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs new file mode 100644 index 0000000000..28486cc743 --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs @@ -0,0 +1,20 @@ +// 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.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Profile.Sections +{ + public class ProfileShowMoreButton : ShowMoreButton + { + [BackgroundDependencyLoader] + private void load(OsuColour colors) + { + IdleColour = colors.GreySeafoamDark; + HoverColour = colors.GreySeafoam; + ChevronIconColour = colors.Yellow; + } + } +} From 328b4d6863a3002b396b65bbcdde32d0a95568ff Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 13 Oct 2019 16:22:10 +0300 Subject: [PATCH 39/72] Cancel request on dispose --- osu.Game/Overlays/Comments/CommentsContainer.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 1111313d7f..4c27c498c3 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -194,5 +194,12 @@ namespace osu.Game.Overlays.Comments { background.Colour = colours.Gray2; } + + protected override void Dispose(bool isDisposing) + { + request?.Cancel(); + loadCancellation?.Cancel(); + base.Dispose(isDisposing); + } } } From 9372526d3af9f42da19442ed21baca4c692a358d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Oct 2019 20:08:05 +0900 Subject: [PATCH 40/72] Don't automatically return to gameplay from map pool if no picks are made Closes #6491. --- osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs index d32c0d6156..ec55bb5b54 100644 --- a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs +++ b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs @@ -196,7 +196,7 @@ namespace osu.Game.Tournament.Screens.MapPool setNextMode(); - if (pickType == ChoiceType.Pick) + if (pickType == ChoiceType.Pick && currentMatch.Value.PicksBans.Any(i => i.Type == ChoiceType.Pick)) { scheduledChange?.Cancel(); scheduledChange = Scheduler.AddDelayed(() => { sceneManager?.SetScreen(typeof(GameplayScreen)); }, 10000); From e191c2c50e5652d32f04b7fccb7a7a57ed5c2e9d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Oct 2019 21:32:16 +0900 Subject: [PATCH 41/72] Tidy up constants and method naming --- osu.Game/Overlays/Comments/CommentsHeader.cs | 16 +++++++--------- osu.Game/Overlays/Comments/HeaderButton.cs | 19 ++++++++----------- osu.Game/Overlays/Comments/SortSelector.cs | 4 ++-- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index 2bd2bf21a6..1df347eb82 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -15,10 +15,7 @@ namespace osu.Game.Overlays.Comments { public class CommentsHeader : CompositeDrawable { - private const int height = 40; - private const int spacing = 10; - private const int padding = 50; - private const int text_size = 14; + private const int font_size = 14; public readonly Bindable Sort = new Bindable(); public readonly BindableBool ShowDeleted = new BindableBool(); @@ -28,7 +25,8 @@ namespace osu.Game.Overlays.Comments public CommentsHeader() { RelativeSizeAxes = Axes.X; - Height = height; + Height = 40; + AddRangeInternal(new Drawable[] { background = new Box @@ -38,14 +36,14 @@ namespace osu.Game.Overlays.Comments new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = padding }, + Padding = new MarginPadding { Horizontal = 50 }, Children = new Drawable[] { new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - Spacing = new Vector2(spacing, 0), + Spacing = new Vector2(10, 0), Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Children = new Drawable[] @@ -54,7 +52,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: text_size), + Font = OsuFont.GetFont(size: font_size), Text = @"Sort by" }, new SortSelector @@ -107,7 +105,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: text_size), + Font = OsuFont.GetFont(size: font_size), Text = @"Show deleted" } }, diff --git a/osu.Game/Overlays/Comments/HeaderButton.cs b/osu.Game/Overlays/Comments/HeaderButton.cs index 231a364759..8789cf5830 100644 --- a/osu.Game/Overlays/Comments/HeaderButton.cs +++ b/osu.Game/Overlays/Comments/HeaderButton.cs @@ -13,10 +13,7 @@ namespace osu.Game.Overlays.Comments { public class HeaderButton : Container { - private const int height = 20; - private const int corner_radius = 3; - private const int margin = 10; - private const int duration = 200; + private const int transition_duration = 200; protected override Container Content => content; @@ -26,9 +23,9 @@ namespace osu.Game.Overlays.Comments public HeaderButton() { AutoSizeAxes = Axes.X; - Height = height; + Height = 20; Masking = true; - CornerRadius = corner_radius; + CornerRadius = 3; AddRangeInternal(new Drawable[] { background = new Box @@ -41,7 +38,7 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, - Margin = new MarginPadding { Horizontal = margin } + Margin = new MarginPadding { Horizontal = 10 } }, new HoverClickSounds(), }); @@ -55,18 +52,18 @@ namespace osu.Game.Overlays.Comments protected override bool OnHover(HoverEvent e) { - FadeInBackground(); + ShowBackground(); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - FadeOutBackground(); + HideBackground(); } - protected void FadeInBackground() => background.FadeIn(duration, Easing.OutQuint); + protected void ShowBackground() => background.FadeIn(transition_duration, Easing.OutQuint); - protected void FadeOutBackground() => background.FadeOut(duration, Easing.OutQuint); + protected void HideBackground() => background.FadeOut(transition_duration, Easing.OutQuint); } } diff --git a/osu.Game/Overlays/Comments/SortSelector.cs b/osu.Game/Overlays/Comments/SortSelector.cs index 100ae83291..90e7defb9a 100644 --- a/osu.Game/Overlays/Comments/SortSelector.cs +++ b/osu.Game/Overlays/Comments/SortSelector.cs @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Comments public void Activate() { - FadeInBackground(); + ShowBackground(); text.Font = text.Font.With(weight: FontWeight.Bold); text.Colour = colours.BlueLighter; } @@ -83,7 +83,7 @@ namespace osu.Game.Overlays.Comments public void Deactivate() { if (!IsHovered) - FadeOutBackground(); + HideBackground(); text.Font = text.Font.With(weight: FontWeight.Medium); text.Colour = Color4.White; From 89f270a19a32df0696cbd244eb9e39d826220f4b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Oct 2019 21:32:41 +0900 Subject: [PATCH 42/72] SortSelector -> SortTabControl --- osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs | 2 +- osu.Game/Overlays/Comments/CommentsHeader.cs | 2 +- .../Overlays/Comments/{SortSelector.cs => SortTabControl.cs} | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Overlays/Comments/{SortSelector.cs => SortTabControl.cs} (96%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs index 949dbbe5c4..bc3e0eff1a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Online { typeof(CommentsHeader), typeof(HeaderButton), - typeof(SortSelector), + typeof(SortTabControl), }; private readonly Bindable sort = new Bindable(); diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index 1df347eb82..81be16967f 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Comments Font = OsuFont.GetFont(size: font_size), Text = @"Sort by" }, - new SortSelector + new SortTabControl { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, diff --git a/osu.Game/Overlays/Comments/SortSelector.cs b/osu.Game/Overlays/Comments/SortTabControl.cs similarity index 96% rename from osu.Game/Overlays/Comments/SortSelector.cs rename to osu.Game/Overlays/Comments/SortTabControl.cs index 90e7defb9a..8dc1f14c3d 100644 --- a/osu.Game/Overlays/Comments/SortSelector.cs +++ b/osu.Game/Overlays/Comments/SortTabControl.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Comments { - public class SortSelector : OsuTabControl + public class SortTabControl : OsuTabControl { private const int spacing = 5; @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Comments Spacing = new Vector2(spacing, 0), }; - public SortSelector() + public SortTabControl() { AutoSizeAxes = Axes.Both; } From 4822496c130880a5f3c20e847942cbab870849a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Oct 2019 21:34:16 +0900 Subject: [PATCH 43/72] Fix more naming --- osu.Game/Overlays/Comments/SortTabControl.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Comments/SortTabControl.cs b/osu.Game/Overlays/Comments/SortTabControl.cs index 8dc1f14c3d..3f1b5c54bd 100644 --- a/osu.Game/Overlays/Comments/SortTabControl.cs +++ b/osu.Game/Overlays/Comments/SortTabControl.cs @@ -37,23 +37,23 @@ namespace osu.Game.Overlays.Comments private class SortTabItem : TabItem { - private readonly TabContent content; + private readonly TabButton button; public SortTabItem(CommentsSortCriteria value) : base(value) { AutoSizeAxes = Axes.Both; - Child = content = new TabContent(value) + Child = button = new TabButton(value) { Active = { BindTarget = Active } }; } - protected override void OnActivated() => content.Activate(); + protected override void OnActivated() => button.Activate(); - protected override void OnDeactivated() => content.Deactivate(); + protected override void OnDeactivated() => button.Deactivate(); - private class TabContent : HeaderButton + private class TabButton : HeaderButton { private const int text_size = 14; @@ -64,7 +64,7 @@ namespace osu.Game.Overlays.Comments private readonly SpriteText text; - public TabContent(CommentsSortCriteria value) + public TabButton(CommentsSortCriteria value) { Add(text = new SpriteText { From 779445755034234c0c986dd8f874b0b2162ea35e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Oct 2019 21:34:43 +0900 Subject: [PATCH 44/72] Remove more constants --- osu.Game/Overlays/Comments/SortTabControl.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Comments/SortTabControl.cs b/osu.Game/Overlays/Comments/SortTabControl.cs index 3f1b5c54bd..596822a86c 100644 --- a/osu.Game/Overlays/Comments/SortTabControl.cs +++ b/osu.Game/Overlays/Comments/SortTabControl.cs @@ -17,8 +17,6 @@ namespace osu.Game.Overlays.Comments { public class SortTabControl : OsuTabControl { - private const int spacing = 5; - protected override Dropdown CreateDropdown() => null; protected override TabItem CreateTabItem(CommentsSortCriteria value) => new SortTabItem(value); @@ -27,7 +25,7 @@ namespace osu.Game.Overlays.Comments { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - Spacing = new Vector2(spacing, 0), + Spacing = new Vector2(5, 0), }; public SortTabControl() @@ -55,8 +53,6 @@ namespace osu.Game.Overlays.Comments private class TabButton : HeaderButton { - private const int text_size = 14; - public readonly BindableBool Active = new BindableBool(); [Resolved] @@ -68,7 +64,7 @@ namespace osu.Game.Overlays.Comments { Add(text = new SpriteText { - Font = OsuFont.GetFont(size: text_size), + Font = OsuFont.GetFont(size: 14), Text = value.ToString() }); } From 4e6ab1dad397f0151861f3fc39bed5c3c9f0617f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Oct 2019 21:42:07 +0900 Subject: [PATCH 45/72] Tidy up state management via bindable usage --- osu.Game/Overlays/Comments/SortTabControl.cs | 51 +++++++++++--------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/Comments/SortTabControl.cs b/osu.Game/Overlays/Comments/SortTabControl.cs index 596822a86c..f5423e692f 100644 --- a/osu.Game/Overlays/Comments/SortTabControl.cs +++ b/osu.Game/Overlays/Comments/SortTabControl.cs @@ -35,21 +35,20 @@ namespace osu.Game.Overlays.Comments private class SortTabItem : TabItem { - private readonly TabButton button; - public SortTabItem(CommentsSortCriteria value) : base(value) { AutoSizeAxes = Axes.Both; - Child = button = new TabButton(value) - { - Active = { BindTarget = Active } - }; + Child = new TabButton(value) { Active = { BindTarget = Active } }; } - protected override void OnActivated() => button.Activate(); + protected override void OnActivated() + { + } - protected override void OnDeactivated() => button.Deactivate(); + protected override void OnDeactivated() + { + } private class TabButton : HeaderButton { @@ -69,25 +68,33 @@ namespace osu.Game.Overlays.Comments }); } - public void Activate() + protected override void LoadComplete() { - ShowBackground(); - text.Font = text.Font.With(weight: FontWeight.Bold); - text.Colour = colours.BlueLighter; + base.LoadComplete(); + + Active.BindValueChanged(active => + { + updateBackgroundState(); + + text.Font = text.Font.With(weight: active.NewValue ? FontWeight.Bold : FontWeight.Medium); + text.Colour = active.NewValue ? colours.BlueLighter : Color4.White; + }, true); } - public void Deactivate() + protected override bool OnHover(HoverEvent e) { - if (!IsHovered) + updateBackgroundState(); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) => updateBackgroundState(); + + private void updateBackgroundState() + { + if (Active.Value || IsHovered) + ShowBackground(); + else HideBackground(); - - text.Font = text.Font.With(weight: FontWeight.Medium); - text.Colour = Color4.White; - } - - protected override void OnHoverLost(HoverLostEvent e) - { - if (!Active.Value) base.OnHoverLost(e); } } } From b7ddf160b46d874e20c928aae44595daccfe692a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Oct 2019 21:48:12 +0900 Subject: [PATCH 46/72] OnClick should actually handle the event --- osu.Game/Overlays/Comments/CommentsHeader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index 81be16967f..1797a36b71 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Comments protected override bool OnClick(ClickEvent e) { Checked.Value = !Checked.Value; - return base.OnClick(e); + return true; } } } From f0e970034950ff034e380be1ecf34947abf806fc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Oct 2019 21:49:02 +0900 Subject: [PATCH 47/72] Inline delegate event --- osu.Game/Overlays/Comments/CommentsHeader.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index 1797a36b71..66fe7ff3fa 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -114,15 +114,10 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { - Checked.BindValueChanged(onCheckedChanged, true); + Checked.BindValueChanged(isChecked => checkboxIcon.Icon = isChecked.NewValue ? FontAwesome.Solid.CheckSquare : FontAwesome.Regular.Square, true); base.LoadComplete(); } - private void onCheckedChanged(ValueChangedEvent isChecked) - { - checkboxIcon.Icon = isChecked.NewValue ? FontAwesome.Solid.CheckSquare : FontAwesome.Regular.Square; - } - protected override bool OnClick(ClickEvent e) { Checked.Value = !Checked.Value; From 7cd3f5656d4c7b482fb995ce9ce4489db0a20d3d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 14 Oct 2019 16:43:43 +0300 Subject: [PATCH 48/72] Cleanups --- .../Online/TestSceneCommentsContainer.cs | 2 +- .../Online/API/Requests/Responses/Comment.cs | 6 ++++- .../Overlays/Comments/CommentsContainer.cs | 4 +-- .../Comments/DeletedChildsPlaceholder.cs | 5 +--- osu.Game/Overlays/Comments/DrawableComment.cs | 27 +++++++------------ .../Overlays/Comments/ShowChildsButton.cs | 2 +- 6 files changed, 18 insertions(+), 28 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index a283663a4a..5e4aa27fae 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual.Online typeof(CommentsHeader), typeof(DrawableComment), typeof(HeaderButton), - typeof(SortSelector), + typeof(SortTabControl), typeof(ShowChildsButton), typeof(DeletedChildsPlaceholder) }; diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 2334c86519..d0f7e4fac5 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -6,6 +6,7 @@ using osu.Game.Users; using System; using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; namespace osu.Game.Online.API.Requests.Responses { @@ -90,7 +91,10 @@ namespace osu.Game.Online.API.Requests.Responses public string GetMessage() { - return IsDeleted ? @"deleted" : MessageHTML.Replace("
", "").Replace("

", "").Replace("
", "").Replace("

", "").Replace("
", "").Replace(""", "\""); + if (IsDeleted) + return @"deleted"; + + return Regex.Replace(MessageHTML, @"\<.*?\>", ""); } public int GetDeletedChildsCount() diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 4c27c498c3..8680234d4b 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -16,8 +16,6 @@ namespace osu.Game.Overlays.Comments { public class CommentsContainer : CompositeDrawable { - private const int more_button_margin = 5; - private readonly CommentableType type; private readonly long id; @@ -101,7 +99,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Margin = new MarginPadding(more_button_margin), + Margin = new MarginPadding(5), Action = () => getComments(false), } } diff --git a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs b/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs index d626c13afd..058f8cc750 100644 --- a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs +++ b/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs @@ -12,9 +12,6 @@ namespace osu.Game.Overlays.Comments { public class DeletedChildsPlaceholder : FillFlowContainer { - private const int deleted_placeholder_margin = 80; - private const int margin = 10; - public readonly BindableBool ShowDeleted = new BindableBool(); public readonly BindableInt DeletedCount = new BindableInt(); @@ -27,7 +24,7 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both; Direction = FillDirection.Horizontal; Spacing = new Vector2(3, 0); - Margin = new MarginPadding { Vertical = margin, Left = deleted_placeholder_margin }; + Margin = new MarginPadding { Vertical = 10, Left = 80 }; Children = new Drawable[] { new SpriteIcon diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 8c356a6156..756eb8caf9 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -21,18 +21,14 @@ namespace osu.Game.Overlays.Comments { private const int avatar_size = 40; private const int margin = 10; - private const int child_margin = 20; - private const int chevron_margin = 30; - private const int message_padding = 40; - private const float separator_height = 1.5f; public readonly BindableBool ShowDeleted = new BindableBool(); private readonly BindableBool childExpanded = new BindableBool(true); private readonly FillFlowContainer childCommentsVisibilityContainer; - private readonly Comment comment; private readonly DeletedChildsPlaceholder deletedChildsPlaceholder; + private readonly Comment comment; public DrawableComment(Comment comment) { @@ -127,7 +123,7 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Right = message_padding } + Padding = new MarginPadding { Right = 40 } }, info = new FillFlowContainer { @@ -164,7 +160,7 @@ namespace osu.Game.Overlays.Comments { childCommentsContainer = new FillFlowContainer { - Margin = new MarginPadding { Left = child_margin }, + Margin = new MarginPadding { Left = 20 }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical @@ -180,10 +176,10 @@ namespace osu.Game.Overlays.Comments deletedChildsPlaceholder.DeletedCount.Value = comment.GetDeletedChildsCount(); - if (comment.UserId == null) - username.AddText(comment.LegacyName); - else + if (comment.UserId.HasValue) username.AddUserLink(comment.User); + else + username.AddText(comment.LegacyName); if (comment.EditedAt.HasValue) { @@ -209,7 +205,7 @@ namespace osu.Game.Overlays.Comments AddInternal(new Container { RelativeSizeAxes = Axes.X, - Height = separator_height, + Height = 1.5f, Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, Child = new Box @@ -225,7 +221,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - Margin = new MarginPadding { Right = chevron_margin, Top = margin }, + Margin = new MarginPadding { Right = 30, Top = margin }, Expanded = { BindTarget = childExpanded } }); } @@ -240,15 +236,10 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { ShowDeleted.BindValueChanged(onShowDeletedChanged, true); - childExpanded.BindValueChanged(onChildExpandedChanged, true); + childExpanded.BindValueChanged(expanded => childCommentsVisibilityContainer.FadeTo(expanded.NewValue ? 1 : 0), true); base.LoadComplete(); } - private void onChildExpandedChanged(ValueChangedEvent expanded) - { - childCommentsVisibilityContainer.FadeTo(expanded.NewValue ? 1 : 0); - } - private void onShowDeletedChanged(ValueChangedEvent show) { if (comment.IsDeleted) diff --git a/osu.Game/Overlays/Comments/ShowChildsButton.cs b/osu.Game/Overlays/Comments/ShowChildsButton.cs index 81280a71b5..b29e316e80 100644 --- a/osu.Game/Overlays/Comments/ShowChildsButton.cs +++ b/osu.Game/Overlays/Comments/ShowChildsButton.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Comments protected override bool OnClick(ClickEvent e) { Expanded.Value = !Expanded.Value; - return base.OnClick(e); + return true; } } } From a81d5cd81968fc113f924552c87f728da17d0ef6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 14 Oct 2019 16:56:07 +0300 Subject: [PATCH 49/72] Handle links in message --- osu.Game/Overlays/Comments/DrawableComment.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 756eb8caf9..c492e48acf 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -14,6 +14,7 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Bindables; using osu.Framework.Graphics.Shapes; using System.Linq; +using osu.Game.Online.Chat; namespace osu.Game.Overlays.Comments { @@ -35,7 +36,7 @@ namespace osu.Game.Overlays.Comments LinkFlowContainer username; FillFlowContainer childCommentsContainer; FillFlowContainer info; - TextFlowContainer message; + LinkFlowContainer message; GridContainer content; VotePill votePill; @@ -119,7 +120,7 @@ namespace osu.Game.Overlays.Comments } } }, - message = new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) + message = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -193,7 +194,10 @@ namespace osu.Game.Overlays.Comments } if (!comment.IsDeleted) - message.Text = comment.GetMessage(); + { + var formattedSource = MessageFormatter.FormatText(comment.GetMessage()); + message.AddLinks(formattedSource.Text, formattedSource.Links); + } else { content.FadeColour(OsuColour.Gray(0.5f)); From a4ffd4798dfc76b516f4da2cb8b2f8f58a5f858f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 14 Oct 2019 17:02:48 +0300 Subject: [PATCH 50/72] Fix escaped html strings not being unescaped --- osu.Game/Online/API/Requests/Responses/Comment.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index d0f7e4fac5..5e67bff859 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -6,6 +6,7 @@ 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 @@ -94,7 +95,7 @@ namespace osu.Game.Online.API.Requests.Responses if (IsDeleted) return @"deleted"; - return Regex.Replace(MessageHTML, @"\<.*?\>", ""); + return WebUtility.HtmlDecode(Regex.Replace(MessageHTML, @"<(.|\n)*?>", string.Empty)); } public int GetDeletedChildsCount() From b53fb0d228ba112044285ca31272432a53938a43 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 14 Oct 2019 17:07:50 +0300 Subject: [PATCH 51/72] Remove empty line --- osu.Game/Overlays/Comments/CommentsContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 8680234d4b..a5e921e2c0 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -183,7 +183,6 @@ namespace osu.Game.Overlays.Comments moreButton.IsLoading = false; } moreButton.FadeTo(response.HasMore ? 1 : 0); - }, loadCancellation.Token); } From 139170cdc859f2689e99b0a940f8334b2b46fa19 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 14 Oct 2019 17:26:12 +0300 Subject: [PATCH 52/72] Fix incorrect padding for nested comments --- osu.Game/Overlays/Comments/DrawableComment.cs | 169 +++++++++--------- 1 file changed, 87 insertions(+), 82 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index c492e48acf..e5258ef3cc 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -51,100 +51,105 @@ namespace osu.Game.Overlays.Comments Direction = FillDirection.Vertical, Children = new Drawable[] { - content = new GridContainer + new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding(margin), - ColumnDimensions = new[] + Padding = new MarginPadding(margin), + Child = content = new GridContainer { - new Dimension(GridSizeMode.AutoSize), - new Dimension(), - }, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize) - }, - Content = new[] - { - new Drawable[] + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + ColumnDimensions = new[] { - new FillFlowContainer + new Dimension(GridSizeMode.AutoSize), + new Dimension(), + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] { - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Horizontal = margin }, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), - Children = new Drawable[] + new FillFlowContainer { - votePill = new VotePill(comment.VotesCount) + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Horizontal = margin }, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AlwaysPresent = true, - }, - new UpdateableAvatar(comment.User) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(avatar_size), - Masking = true, - CornerRadius = avatar_size / 2, - }, - } - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(0, 3), - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(7, 0), - Children = new Drawable[] + votePill = new VotePill(comment.VotesCount) { - username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AlwaysPresent = true, + }, + new UpdateableAvatar(comment.User) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(avatar_size), + Masking = true, + CornerRadius = avatar_size / 2, + }, + } + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(0, 3), + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(7, 0), + Children = new Drawable[] { - AutoSizeAxes = Axes.Both, - }, - new ParentUsername(comment), - new SpriteText - { - Alpha = comment.IsDeleted? 1 : 0, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), - Text = @"deleted", + username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + { + AutoSizeAxes = Axes.Both, + }, + new ParentUsername(comment), + new SpriteText + { + Alpha = comment.IsDeleted? 1 : 0, + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), + Text = @"deleted", + } } - } - }, - message = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Right = 40 } - }, - info = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Colour = OsuColour.Gray(0.7f), - Children = new Drawable[] + }, + message = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) { - new SpriteText + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Right = 40 } + }, + info = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Colour = OsuColour.Gray(0.7f), + Children = new Drawable[] { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12), - Text = HumanizerUtils.Humanize(comment.CreatedAt) - }, - new RepliesButton(comment.RepliesCount) - { - Expanded = { BindTarget = childExpanded } - }, + new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Text = HumanizerUtils.Humanize(comment.CreatedAt) + }, + new RepliesButton(comment.RepliesCount) + { + Expanded = { BindTarget = childExpanded } + }, + } } } } @@ -161,7 +166,7 @@ namespace osu.Game.Overlays.Comments { childCommentsContainer = new FillFlowContainer { - Margin = new MarginPadding { Left = 20 }, + Padding = new MarginPadding { Left = 20 }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical From d4843285dbf091b6756b71e86599a94ffb8bbde0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 14 Oct 2019 17:33:14 +0300 Subject: [PATCH 53/72] CI fixes --- osu.Game/Graphics/UserInterface/ShowMoreButton.cs | 6 +++--- osu.Game/Online/API/Requests/Responses/Comment.cs | 4 ++-- osu.Game/Overlays/Comments/CommentsContainer.cs | 1 + osu.Game/Overlays/Comments/DrawableComment.cs | 15 +++++---------- osu.Game/Overlays/Comments/ShowChildsButton.cs | 2 +- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs index 627ad995e8..8b2eb31d96 100644 --- a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs +++ b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs @@ -23,13 +23,13 @@ namespace osu.Game.Graphics.UserInterface public Color4 ChevronIconColour { get => chevronIconColour; - set { chevronIconColour = leftChevron.AccentColour = rightChevron.AccentColour = value; } + set => chevronIconColour = leftChevron.AccentColour = rightChevron.AccentColour = value; } public string Text { get => text.Text; - set { text.Text = value; } + set => text.Text = value; } private bool isLoading; @@ -136,7 +136,7 @@ namespace osu.Game.Graphics.UserInterface public Color4 AccentColour { get => accentColour; - set { accentColour = Colour = value; } + set => accentColour = Colour = value; } public ChevronIcon() diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 5e67bff859..6243ea4fb6 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -42,7 +42,7 @@ namespace osu.Game.Online.API.Requests.Responses public string Message { get; set; } [JsonProperty(@"message_html")] - public string MessageHTML { get; set; } + public string MessageHtml { get; set; } [JsonProperty(@"replies_count")] public int RepliesCount { get; set; } @@ -95,7 +95,7 @@ namespace osu.Game.Online.API.Requests.Responses if (IsDeleted) return @"deleted"; - return WebUtility.HtmlDecode(Regex.Replace(MessageHTML, @"<(.|\n)*?>", string.Empty)); + return WebUtility.HtmlDecode(Regex.Replace(MessageHtml, @"<(.|\n)*?>", string.Empty)); } public int GetDeletedChildsCount() diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index a5e921e2c0..6c674678df 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -182,6 +182,7 @@ namespace osu.Game.Overlays.Comments moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments; moreButton.IsLoading = false; } + moreButton.FadeTo(response.HasMore ? 1 : 0); }, loadCancellation.Token); } diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index e5258ef3cc..38e45949e1 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -28,13 +28,13 @@ namespace osu.Game.Overlays.Comments private readonly BindableBool childExpanded = new BindableBool(true); private readonly FillFlowContainer childCommentsVisibilityContainer; - private readonly DeletedChildsPlaceholder deletedChildsPlaceholder; private readonly Comment comment; public DrawableComment(Comment comment) { LinkFlowContainer username; FillFlowContainer childCommentsContainer; + DeletedChildsPlaceholder deletedChildsPlaceholder; FillFlowContainer info; LinkFlowContainer message; GridContainer content; @@ -93,7 +93,7 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.Centre, Size = new Vector2(avatar_size), Masking = true, - CornerRadius = avatar_size / 2, + CornerRadius = avatar_size / 2f, }, } }, @@ -118,7 +118,7 @@ namespace osu.Game.Overlays.Comments new ParentUsername(comment), new SpriteText { - Alpha = comment.IsDeleted? 1 : 0, + Alpha = comment.IsDeleted ? 1 : 0, Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), Text = @"deleted", } @@ -299,8 +299,6 @@ namespace osu.Game.Overlays.Comments private class ParentUsername : FillFlowContainer, IHasTooltip { - private const int spacing = 3; - public string TooltipText => comment.ParentComment?.GetMessage() ?? ""; private readonly Comment comment; @@ -311,7 +309,7 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both; Direction = FillDirection.Horizontal; - Spacing = new Vector2(spacing, 0); + Spacing = new Vector2(3, 0); Alpha = comment.ParentId == null ? 0 : 1; Children = new Drawable[] { @@ -331,13 +329,10 @@ namespace osu.Game.Overlays.Comments private class VotePill : CircularContainer { - private const int height = 20; - private const int margin = 10; - public VotePill(int count) { AutoSizeAxes = Axes.X; - Height = height; + Height = 20; Masking = true; Children = new Drawable[] { diff --git a/osu.Game/Overlays/Comments/ShowChildsButton.cs b/osu.Game/Overlays/Comments/ShowChildsButton.cs index b29e316e80..464c0a1503 100644 --- a/osu.Game/Overlays/Comments/ShowChildsButton.cs +++ b/osu.Game/Overlays/Comments/ShowChildsButton.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Comments { public readonly BindableBool Expanded = new BindableBool(true); - public ShowChildsButton() + protected ShowChildsButton() { AutoSizeAxes = Axes.Both; } From b1f7a673e719ede09fd76bd4e2da36658aaa53bc Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 00:10:02 +0300 Subject: [PATCH 54/72] Simplify chevron icon coloring --- osu.Game/Graphics/UserInterface/ShowMoreButton.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs index 8b2eb31d96..854b7abce1 100644 --- a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs +++ b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs @@ -23,7 +23,7 @@ namespace osu.Game.Graphics.UserInterface public Color4 ChevronIconColour { get => chevronIconColour; - set => chevronIconColour = leftChevron.AccentColour = rightChevron.AccentColour = value; + set => chevronIconColour = leftChevron.Colour = rightChevron.Colour = value; } public string Text @@ -131,14 +131,6 @@ namespace osu.Game.Graphics.UserInterface { private const int icon_size = 8; - private Color4 accentColour; - - public Color4 AccentColour - { - get => accentColour; - set => accentColour = Colour = value; - } - public ChevronIcon() { Anchor = Anchor.Centre; From 0676c880b53a612093ef2f0fb8f46c03246f355d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 00:26:31 +0300 Subject: [PATCH 55/72] Simplify IsTopLevel and IsDeleted properties --- .../Online/API/Requests/Responses/Comment.cs | 30 ++++--------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 6243ea4fb6..5accd7fd5b 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -16,20 +16,10 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"id")] public long Id { get; set; } - private long? parentId; - [JsonProperty(@"parent_id")] - public long? ParentId - { - get => parentId; - set - { - parentId = value; - IsTopLevel = value == null; - } - } + public long? ParentId { get; set; } - public List ChildComments = new List(); + public readonly List ChildComments = new List(); public Comment ParentComment { get; set; } @@ -65,18 +55,8 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"updated_at")] public DateTimeOffset? UpdatedAt { get; set; } - private DateTimeOffset? deletedAt; - [JsonProperty(@"deleted_at")] - public DateTimeOffset? DeletedAt - { - get => deletedAt; - set - { - deletedAt = value; - IsDeleted = value != null; - } - } + public DateTimeOffset? DeletedAt { get; set; } [JsonProperty(@"edited_at")] public DateTimeOffset? EditedAt { get; set; } @@ -86,9 +66,9 @@ namespace osu.Game.Online.API.Requests.Responses public User EditedUser { get; set; } - public bool IsTopLevel { get; set; } + public bool IsTopLevel => !ParentId.HasValue; - public bool IsDeleted { get; set; } + public bool IsDeleted => DeletedAt.HasValue; public string GetMessage() { From 09621f066e8fc1ac9b93e755c1fc94b416b8148e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 00:32:21 +0300 Subject: [PATCH 56/72] Childs -> Children --- .../Online/TestSceneCommentsContainer.cs | 4 ++-- .../Online/API/Requests/Responses/Comment.cs | 2 +- .../Overlays/Comments/CommentsContainer.cs | 8 ++++---- ...holder.cs => DeletedChildrenPlaceholder.cs} | 4 ++-- osu.Game/Overlays/Comments/DrawableComment.cs | 18 +++++++++--------- ...owChildsButton.cs => ShowChildrenButton.cs} | 4 ++-- 6 files changed, 20 insertions(+), 20 deletions(-) rename osu.Game/Overlays/Comments/{DeletedChildsPlaceholder.cs => DeletedChildrenPlaceholder.cs} (95%) rename osu.Game/Overlays/Comments/{ShowChildsButton.cs => ShowChildrenButton.cs} (89%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 5e4aa27fae..436e80d6f5 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -21,8 +21,8 @@ namespace osu.Game.Tests.Visual.Online typeof(DrawableComment), typeof(HeaderButton), typeof(SortTabControl), - typeof(ShowChildsButton), - typeof(DeletedChildsPlaceholder) + typeof(ShowChildrenButton), + typeof(DeletedChildrenPlaceholder) }; protected override bool UseOnlineAPI => true; diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 5accd7fd5b..9e8f0cada2 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -78,7 +78,7 @@ namespace osu.Game.Online.API.Requests.Responses return WebUtility.HtmlDecode(Regex.Replace(MessageHtml, @"<(.|\n)*?>", string.Empty)); } - public int GetDeletedChildsCount() + public int GetDeletedChildrenCount() { int count = 0; diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 6c674678df..48b3952093 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Comments private readonly Box background; private readonly FillFlowContainer content; - private readonly DeletedChildsPlaceholder deletedChildsPlaceholder; + private readonly DeletedChildrenPlaceholder deletedChildrenPlaceholder; private readonly CommentsShowMoreButton moreButton; public CommentsContainer(CommentableType type, long id) @@ -87,7 +87,7 @@ namespace osu.Game.Overlays.Comments Direction = FillDirection.Vertical, Children = new Drawable[] { - deletedChildsPlaceholder = new DeletedChildsPlaceholder + deletedChildrenPlaceholder = new DeletedChildrenPlaceholder { ShowDeleted = { BindTarget = ShowDeleted } }, @@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Comments { currentPage = 1; loadedTopLevelComments = 0; - deletedChildsPlaceholder.DeletedCount.Value = 0; + deletedChildrenPlaceholder.DeletedCount.Value = 0; moreButton.IsLoading = true; content.Clear(); } @@ -170,7 +170,7 @@ namespace osu.Game.Overlays.Comments deletedComments++; }); - deletedChildsPlaceholder.DeletedCount.Value = initial ? deletedComments : deletedChildsPlaceholder.DeletedCount.Value + deletedComments; + deletedChildrenPlaceholder.DeletedCount.Value = initial ? deletedComments : deletedChildrenPlaceholder.DeletedCount.Value + deletedComments; if (response.HasMore) { diff --git a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs b/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs similarity index 95% rename from osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs rename to osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs index 058f8cc750..f537141d7f 100644 --- a/osu.Game/Overlays/Comments/DeletedChildsPlaceholder.cs +++ b/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs @@ -10,7 +10,7 @@ using osu.Framework.Bindables; namespace osu.Game.Overlays.Comments { - public class DeletedChildsPlaceholder : FillFlowContainer + public class DeletedChildrenPlaceholder : FillFlowContainer { public readonly BindableBool ShowDeleted = new BindableBool(); public readonly BindableInt DeletedCount = new BindableInt(); @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Comments private readonly SpriteText countText; - public DeletedChildsPlaceholder() + public DeletedChildrenPlaceholder() { AutoSizeAxes = Axes.Both; Direction = FillDirection.Horizontal; diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 38e45949e1..81a6c6a743 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Comments public readonly BindableBool ShowDeleted = new BindableBool(); - private readonly BindableBool childExpanded = new BindableBool(true); + private readonly BindableBool childrenExpanded = new BindableBool(true); private readonly FillFlowContainer childCommentsVisibilityContainer; private readonly Comment comment; @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Comments { LinkFlowContainer username; FillFlowContainer childCommentsContainer; - DeletedChildsPlaceholder deletedChildsPlaceholder; + DeletedChildrenPlaceholder deletedChildrenPlaceholder; FillFlowContainer info; LinkFlowContainer message; GridContainer content; @@ -147,7 +147,7 @@ namespace osu.Game.Overlays.Comments }, new RepliesButton(comment.RepliesCount) { - Expanded = { BindTarget = childExpanded } + Expanded = { BindTarget = childrenExpanded } }, } } @@ -171,7 +171,7 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical }, - deletedChildsPlaceholder = new DeletedChildsPlaceholder + deletedChildrenPlaceholder = new DeletedChildrenPlaceholder { ShowDeleted = { BindTarget = ShowDeleted } } @@ -180,7 +180,7 @@ namespace osu.Game.Overlays.Comments } }; - deletedChildsPlaceholder.DeletedCount.Value = comment.GetDeletedChildsCount(); + deletedChildrenPlaceholder.DeletedCount.Value = comment.GetDeletedChildrenCount(); if (comment.UserId.HasValue) username.AddUserLink(comment.User); @@ -231,7 +231,7 @@ namespace osu.Game.Overlays.Comments Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Margin = new MarginPadding { Right = 30, Top = margin }, - Expanded = { BindTarget = childExpanded } + Expanded = { BindTarget = childrenExpanded } }); } } @@ -245,7 +245,7 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { ShowDeleted.BindValueChanged(onShowDeletedChanged, true); - childExpanded.BindValueChanged(expanded => childCommentsVisibilityContainer.FadeTo(expanded.NewValue ? 1 : 0), true); + childrenExpanded.BindValueChanged(expanded => childCommentsVisibilityContainer.FadeTo(expanded.NewValue ? 1 : 0), true); base.LoadComplete(); } @@ -255,7 +255,7 @@ namespace osu.Game.Overlays.Comments this.FadeTo(show.NewValue ? 1 : 0); } - private class ChevronButton : ShowChildsButton + private class ChevronButton : ShowChildrenButton { private readonly SpriteIcon icon; @@ -275,7 +275,7 @@ namespace osu.Game.Overlays.Comments } } - private class RepliesButton : ShowChildsButton + private class RepliesButton : ShowChildrenButton { private readonly SpriteText text; private readonly int count; diff --git a/osu.Game/Overlays/Comments/ShowChildsButton.cs b/osu.Game/Overlays/Comments/ShowChildrenButton.cs similarity index 89% rename from osu.Game/Overlays/Comments/ShowChildsButton.cs rename to osu.Game/Overlays/Comments/ShowChildrenButton.cs index 464c0a1503..be04b6e5de 100644 --- a/osu.Game/Overlays/Comments/ShowChildsButton.cs +++ b/osu.Game/Overlays/Comments/ShowChildrenButton.cs @@ -8,11 +8,11 @@ using osu.Framework.Bindables; namespace osu.Game.Overlays.Comments { - public abstract class ShowChildsButton : OsuHoverContainer + public abstract class ShowChildrenButton : OsuHoverContainer { public readonly BindableBool Expanded = new BindableBool(true); - protected ShowChildsButton() + protected ShowChildrenButton() { AutoSizeAxes = Axes.Both; } From b84c9dfd84f206d3766b950803116fd687c61c7d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 00:35:44 +0300 Subject: [PATCH 57/72] Use Humanizer.ToQuantity instead of manual parsing --- osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs b/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs index f537141d7f..21cf01f993 100644 --- a/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs +++ b/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs @@ -7,6 +7,7 @@ using osu.Game.Graphics; using osu.Framework.Graphics.Sprites; using osuTK; using osu.Framework.Bindables; +using Humanizer; namespace osu.Game.Overlays.Comments { @@ -62,12 +63,7 @@ namespace osu.Game.Overlays.Comments return; } - string str = $@"{count.NewValue} deleted comment"; - - if (!(count.NewValue.ToString().EndsWith("1") && !count.NewValue.ToString().EndsWith("11"))) - str += "s"; - - countText.Text = str; + countText.Text = @"deleted comment".ToQuantity(count.NewValue); Show(); } } From 0fd6b0c8524912ec9cc4b98cae03434a9db1154c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 00:55:33 +0300 Subject: [PATCH 58/72] Use linq expression to count deleted comments --- osu.Game/Online/API/Requests/Responses/Comment.cs | 14 +------------- osu.Game/Overlays/Comments/CommentsContainer.cs | 9 ++------- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 9e8f0cada2..046de194db 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -78,18 +78,6 @@ namespace osu.Game.Online.API.Requests.Responses return WebUtility.HtmlDecode(Regex.Replace(MessageHtml, @"<(.|\n)*?>", string.Empty)); } - public int GetDeletedChildrenCount() - { - int count = 0; - - if (ChildComments.Any()) - ChildComments.ForEach(child => - { - if (child.IsDeleted) - count++; - }); - - return count; - } + public int GetDeletedChildrenCount => ChildComments.Select(c => c.IsDeleted).Where(c => c).Count(); } } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 48b3952093..318422bedb 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; using System.Threading; +using System.Linq; namespace osu.Game.Overlays.Comments { @@ -162,13 +163,7 @@ namespace osu.Game.Overlays.Comments { content.Add(loaded); - int deletedComments = 0; - - response.Comments.ForEach(comment => - { - if (comment.IsDeleted && comment.IsTopLevel) - deletedComments++; - }); + int deletedComments = response.Comments.Select(c => c.IsDeleted && c.IsTopLevel).Where(c => c).Count(); deletedChildrenPlaceholder.DeletedCount.Value = initial ? deletedComments : deletedChildrenPlaceholder.DeletedCount.Value + deletedComments; diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 81a6c6a743..13c67b9f5b 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -180,7 +180,7 @@ namespace osu.Game.Overlays.Comments } }; - deletedChildrenPlaceholder.DeletedCount.Value = comment.GetDeletedChildrenCount(); + deletedChildrenPlaceholder.DeletedCount.Value = comment.GetDeletedChildrenCount; if (comment.UserId.HasValue) username.AddUserLink(comment.User); From 42a06a54ffb3779c7079e0b8cbd934e7d204fe77 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 01:08:23 +0300 Subject: [PATCH 59/72] Don't use ProfileShowMoreButton in the test scene to avoid confusion --- .../Visual/Online/TestSceneShowMoreButton.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs b/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs index 8d4955abf0..b9fbbfef6b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs @@ -1,11 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Overlays.Profile.Sections; using System; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Framework.Allocation; +using osu.Game.Graphics; namespace osu.Game.Tests.Visual.Online { @@ -18,11 +19,11 @@ namespace osu.Game.Tests.Visual.Online public TestSceneShowMoreButton() { - ProfileShowMoreButton button = null; + TestButton button = null; int fireCount = 0; - Add(button = new ProfileShowMoreButton + Add(button = new TestButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -52,5 +53,16 @@ namespace osu.Game.Tests.Visual.Online AddAssert("action fired twice", () => fireCount == 2); AddAssert("is in loading state", () => button.IsLoading); } + + private class TestButton : ShowMoreButton + { + [BackgroundDependencyLoader] + private void load(OsuColour colors) + { + IdleColour = colors.YellowDark; + HoverColour = colors.Yellow; + ChevronIconColour = colors.Red; + } + } } } From ad32d663652c2432a4f31bb73dc3b555a1e743c4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 01:10:23 +0300 Subject: [PATCH 60/72] CI fix --- osu.Game/Online/API/Requests/Responses/Comment.cs | 2 +- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 046de194db..9d011c49c1 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -78,6 +78,6 @@ namespace osu.Game.Online.API.Requests.Responses return WebUtility.HtmlDecode(Regex.Replace(MessageHtml, @"<(.|\n)*?>", string.Empty)); } - public int GetDeletedChildrenCount => ChildComments.Select(c => c.IsDeleted).Where(c => c).Count(); + public int GetDeletedChildrenCount => ChildComments.Select(c => c.IsDeleted).Count(c => c); } } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 318422bedb..49c479f6e5 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -163,7 +163,7 @@ namespace osu.Game.Overlays.Comments { content.Add(loaded); - int deletedComments = response.Comments.Select(c => c.IsDeleted && c.IsTopLevel).Where(c => c).Count(); + int deletedComments = response.Comments.Select(c => c.IsDeleted && c.IsTopLevel).Count(c => c); deletedChildrenPlaceholder.DeletedCount.Value = initial ? deletedComments : deletedChildrenPlaceholder.DeletedCount.Value + deletedComments; From ccc753a3151b1f8066e5015527d0bba6f448687a Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 14 Oct 2019 16:27:59 -0700 Subject: [PATCH 61/72] Make OverlayContainers with no blocking input VisibilityContainers --- osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/Toolbar/Toolbar.cs | 4 +--- osu.Game/Overlays/VolumeOverlay.cs | 4 +--- osu.Game/Screens/Play/ResumeOverlay.cs | 4 +--- osu.Game/Screens/Play/SkipOverlay.cs | 3 +-- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 4 +--- 6 files changed, 6 insertions(+), 15 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 5742d423bb..4dcc181bea 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -102,7 +102,7 @@ namespace osu.Game private readonly List overlays = new List(); - private readonly List toolbarElements = new List(); + private readonly List toolbarElements = new List(); private readonly List visibleBlockingOverlays = new List(); diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 19038c3981..b044bc4de0 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -16,7 +16,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Toolbar { - public class Toolbar : OverlayContainer + public class Toolbar : VisibilityContainer { public const float HEIGHT = 40; public const float TOOLTIP_HEIGHT = 30; @@ -26,8 +26,6 @@ namespace osu.Game.Overlays.Toolbar private ToolbarUserButton userButton; private ToolbarRulesetSelector rulesetSelector; - protected override bool BlockPositionalInput => false; - private const double transition_time = 500; private const float alpha_hovering = 0.8f; diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index 27e2eef200..ca7665eba5 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class VolumeOverlay : OverlayContainer + public class VolumeOverlay : VisibilityContainer { private const float offset = 10; @@ -28,8 +28,6 @@ namespace osu.Game.Overlays private VolumeMeter volumeMeterMusic; private MuteButton muteButton; - protected override bool BlockPositionalInput => false; - private readonly BindableDouble muteAdjustment = new BindableDouble(); private readonly Bindable isMuted = new Bindable(); diff --git a/osu.Game/Screens/Play/ResumeOverlay.cs b/osu.Game/Screens/Play/ResumeOverlay.cs index 2ef76069c2..641d5358ba 100644 --- a/osu.Game/Screens/Play/ResumeOverlay.cs +++ b/osu.Game/Screens/Play/ResumeOverlay.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Play /// /// An overlay which can be used to require further user actions before gameplay is resumed. /// - public abstract class ResumeOverlay : OverlayContainer + public abstract class ResumeOverlay : VisibilityContainer { public CursorContainer GameplayCursor { get; set; } @@ -29,8 +29,6 @@ namespace osu.Game.Screens.Play protected const float TRANSITION_TIME = 500; - protected override bool BlockPositionalInput => false; - protected abstract string Message { get; } public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index d6c2b59d98..31cdff5fb9 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -23,7 +23,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Screens.Play { - public class SkipOverlay : OverlayContainer, IKeyBindingHandler + public class SkipOverlay : VisibilityContainer, IKeyBindingHandler { private readonly double startTime; @@ -36,7 +36,6 @@ namespace osu.Game.Screens.Play private double displayTime; public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; - protected override bool BlockPositionalInput => false; /// /// Displays a skip overlay, giving the user the ability to skip forward. diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 8b360d4a86..d54c13c7db 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -29,7 +29,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Select { - public class BeatmapInfoWedge : OverlayContainer + public class BeatmapInfoWedge : VisibilityContainer { private const float shear_width = 36.75f; @@ -62,8 +62,6 @@ namespace osu.Game.Screens.Select ruleset.ValueChanged += _ => updateDisplay(); } - protected override bool BlockPositionalInput => false; - protected override void PopIn() { this.MoveToX(0, 800, Easing.OutQuint); From f4924dc3cf876999b027c0bc0e9a89e203999e1b Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 14 Oct 2019 16:37:54 -0700 Subject: [PATCH 62/72] Fix volume scrolling when hovering VersionManager --- osu.Desktop/Overlays/VersionManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index 6eed46867a..8c759f8487 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Desktop.Overlays { - public class VersionManager : OverlayContainer + public class VersionManager : VisibilityContainer { [BackgroundDependencyLoader] private void load(OsuColour colours, TextureStore textures, OsuGameBase game) From efc201ec852561e3ab31491c4e171d9767a93665 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 14 Oct 2019 16:40:53 -0700 Subject: [PATCH 63/72] Make PlaylistOverlay a VisibilityContainer --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index bb88960280..b89a577282 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Music { - public class PlaylistOverlay : OverlayContainer + public class PlaylistOverlay : VisibilityContainer { private const float transition_duration = 600; private const float playlist_height = 510; From 3c714dc01307216b23250329c5bc3bf0560138fe Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 11:20:06 +0300 Subject: [PATCH 64/72] APICommentsController -> CommentBundle --- osu.Game/Online/API/Requests/GetCommentsRequest.cs | 2 +- .../Responses/{APICommentsController.cs => CommentBundle.cs} | 2 +- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename osu.Game/Online/API/Requests/Responses/{APICommentsController.cs => CommentBundle.cs} (98%) diff --git a/osu.Game/Online/API/Requests/GetCommentsRequest.cs b/osu.Game/Online/API/Requests/GetCommentsRequest.cs index 834a5106a0..7763501860 100644 --- a/osu.Game/Online/API/Requests/GetCommentsRequest.cs +++ b/osu.Game/Online/API/Requests/GetCommentsRequest.cs @@ -8,7 +8,7 @@ using osu.Game.Overlays.Comments; namespace osu.Game.Online.API.Requests { - public class GetCommentsRequest : APIRequest + public class GetCommentsRequest : APIRequest { private readonly long id; private readonly int page; diff --git a/osu.Game/Online/API/Requests/Responses/APICommentsController.cs b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs similarity index 98% rename from osu.Game/Online/API/Requests/Responses/APICommentsController.cs rename to osu.Game/Online/API/Requests/Responses/CommentBundle.cs index ca6062e371..7063581605 100644 --- a/osu.Game/Online/API/Requests/Responses/APICommentsController.cs +++ b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; namespace osu.Game.Online.API.Requests.Responses { - public class APICommentsController + public class CommentBundle { private List comments; diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 49c479f6e5..62f0ce947b 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -139,7 +139,7 @@ namespace osu.Game.Overlays.Comments api.Queue(request); } - private void onSuccess(APICommentsController response, bool initial) + private void onSuccess(CommentBundle response, bool initial) { loadCancellation = new CancellationTokenSource(); From eb5dad08aa6a8560d544358776c8e6ab3e18e2ea Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 11:25:58 +0300 Subject: [PATCH 65/72] Remove initial filed --- .../Online/API/Requests/Responses/Comment.cs | 2 +- .../Overlays/Comments/CommentsContainer.cs | 36 ++++++++++--------- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 9d011c49c1..68a4c28726 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -78,6 +78,6 @@ namespace osu.Game.Online.API.Requests.Responses return WebUtility.HtmlDecode(Regex.Replace(MessageHtml, @"<(.|\n)*?>", string.Empty)); } - public int GetDeletedChildrenCount => ChildComments.Select(c => c.IsDeleted).Count(c => c); + public int DeletedChildrenCount => ChildComments.Count(c => c.IsDeleted); } } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 62f0ce947b..824d9822be 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -101,7 +101,7 @@ namespace osu.Game.Overlays.Comments Anchor = Anchor.Centre, Origin = Anchor.Centre, Margin = new MarginPadding(5), - Action = () => getComments(false), + Action = getComments } } } @@ -119,27 +119,31 @@ namespace osu.Game.Overlays.Comments base.LoadComplete(); } - private void onSortChanged(ValueChangedEvent sort) => getComments(); - - private void getComments(bool initial = true) + private void onSortChanged(ValueChangedEvent sort) { - if (initial) - { - currentPage = 1; - loadedTopLevelComments = 0; - deletedChildrenPlaceholder.DeletedCount.Value = 0; - moreButton.IsLoading = true; - content.Clear(); - } + clearComments(); + getComments(); + } + private void getComments() + { request?.Cancel(); loadCancellation?.Cancel(); request = new GetCommentsRequest(type, id, Sort.Value, currentPage++); - request.Success += response => onSuccess(response, initial); + request.Success += response => onSuccess(response); api.Queue(request); } - private void onSuccess(CommentBundle response, bool initial) + private void clearComments() + { + currentPage = 1; + loadedTopLevelComments = 0; + deletedChildrenPlaceholder.DeletedCount.Value = 0; + moreButton.IsLoading = true; + content.Clear(); + } + + private void onSuccess(CommentBundle response) { loadCancellation = new CancellationTokenSource(); @@ -163,9 +167,7 @@ namespace osu.Game.Overlays.Comments { content.Add(loaded); - int deletedComments = response.Comments.Select(c => c.IsDeleted && c.IsTopLevel).Count(c => c); - - deletedChildrenPlaceholder.DeletedCount.Value = initial ? deletedComments : deletedChildrenPlaceholder.DeletedCount.Value + deletedComments; + deletedChildrenPlaceholder.DeletedCount.Value += response.Comments.Count(c => c.IsDeleted && c.IsTopLevel); if (response.HasMore) { diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 13c67b9f5b..b22bd6d426 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -180,7 +180,7 @@ namespace osu.Game.Overlays.Comments } }; - deletedChildrenPlaceholder.DeletedCount.Value = comment.GetDeletedChildrenCount; + deletedChildrenPlaceholder.DeletedCount.Value = comment.DeletedChildrenCount; if (comment.UserId.HasValue) username.AddUserLink(comment.User); From b2885e7b139b8def41fc532181d2d19f4a871fc3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 11:26:58 +0300 Subject: [PATCH 66/72] Move load() under the ctor --- osu.Game/Overlays/Comments/CommentsContainer.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 824d9822be..bd1a8562d3 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -113,6 +113,12 @@ namespace osu.Game.Overlays.Comments }); } + [BackgroundDependencyLoader] + private void load() + { + background.Colour = colours.Gray2; + } + protected override void LoadComplete() { Sort.BindValueChanged(onSortChanged, true); @@ -184,12 +190,6 @@ namespace osu.Game.Overlays.Comments }, loadCancellation.Token); } - [BackgroundDependencyLoader] - private void load() - { - background.Colour = colours.Gray2; - } - protected override void Dispose(bool isDisposing) { request?.Cancel(); From 213f00556d30b3f4bededf2c57832bb6e5182802 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 11:30:50 +0300 Subject: [PATCH 67/72] Remove onShowDeletedChanged function --- osu.Game/Overlays/Comments/DrawableComment.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index b22bd6d426..59d3d08122 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -244,17 +244,15 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { - ShowDeleted.BindValueChanged(onShowDeletedChanged, true); + ShowDeleted.BindValueChanged(show => + { + if (comment.IsDeleted) + this.FadeTo(show.NewValue ? 1 : 0); + }, true); childrenExpanded.BindValueChanged(expanded => childCommentsVisibilityContainer.FadeTo(expanded.NewValue ? 1 : 0), true); base.LoadComplete(); } - private void onShowDeletedChanged(ValueChangedEvent show) - { - if (comment.IsDeleted) - this.FadeTo(show.NewValue ? 1 : 0); - } - private class ChevronButton : ShowChildrenButton { private readonly SpriteIcon icon; From 96e31b9cca2b62147354b6608c11857280a7cade Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 12:07:01 +0300 Subject: [PATCH 68/72] Add support for deleted comments with message --- .../Online/API/Requests/Responses/Comment.cs | 8 ++----- osu.Game/Overlays/Comments/DrawableComment.cs | 23 +++++++++++++------ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 68a4c28726..29abaa74e5 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -70,13 +70,9 @@ namespace osu.Game.Online.API.Requests.Responses public bool IsDeleted => DeletedAt.HasValue; - public string GetMessage() - { - if (IsDeleted) - return @"deleted"; + public bool HasMessage => !string.IsNullOrEmpty(MessageHtml); - return WebUtility.HtmlDecode(Regex.Replace(MessageHtml, @"<(.|\n)*?>", string.Empty)); - } + 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/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 59d3d08122..89abda92cf 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -198,12 +198,13 @@ namespace osu.Game.Overlays.Comments }); } - if (!comment.IsDeleted) + if (comment.HasMessage) { - var formattedSource = MessageFormatter.FormatText(comment.GetMessage()); + var formattedSource = MessageFormatter.FormatText(comment.GetMessage); message.AddLinks(formattedSource.Text, formattedSource.Links); } - else + + if (comment.IsDeleted) { content.FadeColour(OsuColour.Gray(0.5f)); votePill.Hide(); @@ -297,13 +298,13 @@ namespace osu.Game.Overlays.Comments private class ParentUsername : FillFlowContainer, IHasTooltip { - public string TooltipText => comment.ParentComment?.GetMessage() ?? ""; + public string TooltipText => getParentMessage(); - private readonly Comment comment; + private readonly Comment parentComment; public ParentUsername(Comment comment) { - this.comment = comment; + parentComment = comment.ParentComment; AutoSizeAxes = Axes.Both; Direction = FillDirection.Horizontal; @@ -319,10 +320,18 @@ namespace osu.Game.Overlays.Comments new SpriteText { Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), - Text = comment.ParentComment?.User?.Username ?? comment.ParentComment?.LegacyName + Text = parentComment?.User?.Username ?? parentComment?.LegacyName } }; } + + private string getParentMessage() + { + if (parentComment == null) + return string.Empty; + + return parentComment.HasMessage ? parentComment.GetMessage : parentComment.IsDeleted ? @"deleted" : string.Empty; + } } private class VotePill : CircularContainer From d321794ef5b0fefbb2330a3f9e35ef42457e0299 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 12:26:16 +0300 Subject: [PATCH 69/72] Make loadedTopLevelComments a local filed --- osu.Game/Overlays/Comments/CommentsContainer.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index bd1a8562d3..6ac31b258f 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -12,6 +12,7 @@ using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; using System.Threading; using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; namespace osu.Game.Overlays.Comments { @@ -32,7 +33,6 @@ namespace osu.Game.Overlays.Comments private GetCommentsRequest request; private CancellationTokenSource loadCancellation; private int currentPage; - private int loadedTopLevelComments; private readonly Box background; private readonly FillFlowContainer content; @@ -143,7 +143,6 @@ namespace osu.Game.Overlays.Comments private void clearComments() { currentPage = 1; - loadedTopLevelComments = 0; deletedChildrenPlaceholder.DeletedCount.Value = 0; moreButton.IsLoading = true; content.Clear(); @@ -177,11 +176,9 @@ namespace osu.Game.Overlays.Comments if (response.HasMore) { - response.Comments.ForEach(comment => - { - if (comment.IsTopLevel) - loadedTopLevelComments++; - }); + int loadedTopLevelComments = 0; + content.Children.OfType().ForEach(p => loadedTopLevelComments += p.Children.OfType().Count()); + moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments; moreButton.IsLoading = false; } From 7ba15df0c07f193016e3e4f0a71c00ccd7b99c15 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 12:27:32 +0300 Subject: [PATCH 70/72] Convert to method group --- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 6ac31b258f..abc1b7233d 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -136,7 +136,7 @@ namespace osu.Game.Overlays.Comments request?.Cancel(); loadCancellation?.Cancel(); request = new GetCommentsRequest(type, id, Sort.Value, currentPage++); - request.Success += response => onSuccess(response); + request.Success += onSuccess; api.Queue(request); } From 2543de22bd4f2bf5c8fe95f46944419312cb9361 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Oct 2019 12:47:35 +0300 Subject: [PATCH 71/72] Simplify DeletedChildrenPlaceholder behavior --- .../Comments/DeletedChildrenPlaceholder.cs | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs b/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs index 21cf01f993..e849691597 100644 --- a/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs +++ b/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs @@ -16,8 +16,6 @@ namespace osu.Game.Overlays.Comments public readonly BindableBool ShowDeleted = new BindableBool(); public readonly BindableInt DeletedCount = new BindableInt(); - private bool canBeShown; - private readonly SpriteText countText; public DeletedChildrenPlaceholder() @@ -42,29 +40,22 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { - DeletedCount.BindValueChanged(onCountChanged, true); - ShowDeleted.BindValueChanged(onShowDeletedChanged, true); + DeletedCount.BindValueChanged(_ => updateDisplay(), true); + ShowDeleted.BindValueChanged(_ => updateDisplay(), true); base.LoadComplete(); } - private void onShowDeletedChanged(ValueChangedEvent showDeleted) + private void updateDisplay() { - if (canBeShown) - this.FadeTo(showDeleted.NewValue ? 0 : 1); - } - - private void onCountChanged(ValueChangedEvent count) - { - canBeShown = count.NewValue != 0; - - if (!canBeShown) + if (DeletedCount.Value != 0) + { + countText.Text = @"deleted comment".ToQuantity(DeletedCount.Value); + this.FadeTo(ShowDeleted.Value ? 0 : 1); + } + else { Hide(); - return; } - - countText.Text = @"deleted comment".ToQuantity(count.NewValue); - Show(); } } } From 350d139cbf22fef749454d867b3b716f8e947bf4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 Oct 2019 15:54:00 +0900 Subject: [PATCH 72/72] Make chevron icon colour protected --- osu.Game/Graphics/UserInterface/ShowMoreButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs index 854b7abce1..5296b9dd7f 100644 --- a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs +++ b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs @@ -20,7 +20,7 @@ namespace osu.Game.Graphics.UserInterface private Color4 chevronIconColour; - public Color4 ChevronIconColour + protected Color4 ChevronIconColour { get => chevronIconColour; set => chevronIconColour = leftChevron.Colour = rightChevron.Colour = value;