diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentRepliesButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentRepliesButton.cs new file mode 100644 index 0000000000..c2ac5179c9 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentRepliesButton.cs @@ -0,0 +1,67 @@ +// 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.Comments.Buttons; +using osu.Framework.Graphics; +using osu.Framework.Allocation; +using osu.Game.Overlays; +using osu.Framework.Graphics.Containers; +using osuTK; +using NUnit.Framework; +using System.Linq; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Testing; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneCommentRepliesButton : OsuTestScene + { + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + + private readonly TestButton button; + + public TestSceneCommentRepliesButton() + { + Child = new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + button = new TestButton(), + new LoadRepliesButton + { + Action = () => { } + }, + new ShowRepliesButton(1), + new ShowRepliesButton(2) + } + }; + } + + [Test] + public void TestArrowDirection() + { + AddStep("Set upwards", () => button.SetIconDirection(true)); + AddAssert("Icon facing upwards", () => button.Icon.Scale.Y == -1); + AddStep("Set downwards", () => button.SetIconDirection(false)); + AddAssert("Icon facing downwards", () => button.Icon.Scale.Y == 1); + } + + private class TestButton : CommentRepliesButton + { + public SpriteIcon Icon => this.ChildrenOfType().First(); + + public TestButton() + { + Text = "sample text"; + } + + public new void SetIconDirection(bool upwards) => base.SetIconDirection(upwards); + } + } +} diff --git a/osu.Game/Overlays/Comments/Buttons/CommentRepliesButton.cs b/osu.Game/Overlays/Comments/Buttons/CommentRepliesButton.cs new file mode 100644 index 0000000000..f7e0cb0a6c --- /dev/null +++ b/osu.Game/Overlays/Comments/Buttons/CommentRepliesButton.cs @@ -0,0 +1,117 @@ +// 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.Sprites; +using osu.Game.Graphics.UserInterface; +using osuTK; + +namespace osu.Game.Overlays.Comments.Buttons +{ + public abstract class CommentRepliesButton : CompositeDrawable + { + protected string Text + { + get => text.Text; + set => text.Text = value; + } + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + + private readonly SpriteIcon icon; + private readonly Box background; + private readonly OsuSpriteText text; + + protected CommentRepliesButton() + { + AutoSizeAxes = Axes.Both; + Margin = new MarginPadding + { + Vertical = 2 + }; + InternalChildren = new Drawable[] + { + new CircularContainer + { + AutoSizeAxes = Axes.Both, + Masking = true, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new Container + { + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding + { + Vertical = 5, + Horizontal = 10, + }, + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(15, 0), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AlwaysPresent = true, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold) + }, + icon = new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(7.5f), + Icon = FontAwesome.Solid.ChevronDown + } + } + } + } + } + }, + new HoverClickSounds(), + }; + } + + [BackgroundDependencyLoader] + private void load() + { + background.Colour = colourProvider.Background2; + icon.Colour = colourProvider.Foreground1; + } + + protected void SetIconDirection(bool upwards) => icon.ScaleTo(new Vector2(1, upwards ? -1 : 1)); + + public void ToggleTextVisibility(bool visible) => text.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); + + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + background.FadeColour(colourProvider.Background1, 200, Easing.OutQuint); + icon.FadeColour(colourProvider.Light1, 200, Easing.OutQuint); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + background.FadeColour(colourProvider.Background2, 200, Easing.OutQuint); + icon.FadeColour(colourProvider.Foreground1, 200, Easing.OutQuint); + } + } +} diff --git a/osu.Game/Overlays/Comments/Buttons/LoadRepliesButton.cs b/osu.Game/Overlays/Comments/Buttons/LoadRepliesButton.cs new file mode 100644 index 0000000000..4998e5391e --- /dev/null +++ b/osu.Game/Overlays/Comments/Buttons/LoadRepliesButton.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.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Comments.Buttons +{ + public class LoadRepliesButton : LoadingButton + { + private ButtonContent content; + + public LoadRepliesButton() + { + AutoSizeAxes = Axes.Both; + } + + protected override Drawable CreateContent() => content = new ButtonContent(); + + protected override void OnLoadStarted() => content.ToggleTextVisibility(false); + + protected override void OnLoadFinished() => content.ToggleTextVisibility(true); + + private class ButtonContent : CommentRepliesButton + { + public ButtonContent() + { + Text = "load replies"; + } + } + } +} diff --git a/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs b/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs new file mode 100644 index 0000000000..04e7e25cc5 --- /dev/null +++ b/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs @@ -0,0 +1,31 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Humanizer; +using osu.Framework.Bindables; +using osu.Framework.Input.Events; + +namespace osu.Game.Overlays.Comments.Buttons +{ + public class ShowRepliesButton : CommentRepliesButton + { + public readonly BindableBool Expanded = new BindableBool(true); + + public ShowRepliesButton(int count) + { + Text = "reply".ToQuantity(count); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Expanded.BindValueChanged(expanded => SetIconDirection(expanded.NewValue), true); + } + + protected override bool OnClick(ClickEvent e) + { + Expanded.Toggle(); + return true; + } + } +} diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 46f600615a..3cdc0a0cbd 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -16,12 +16,12 @@ using System.Linq; using osu.Game.Graphics.Sprites; using osu.Game.Online.Chat; using osu.Framework.Allocation; -using osuTK.Graphics; using System.Collections.Generic; using System; using osu.Framework.Graphics.Shapes; using osu.Framework.Extensions.IEnumerableExtensions; using System.Collections.Specialized; +using osu.Game.Overlays.Comments.Buttons; namespace osu.Game.Overlays.Comments { @@ -46,9 +46,9 @@ namespace osu.Game.Overlays.Comments private FillFlowContainer childCommentsVisibilityContainer; private FillFlowContainer childCommentsContainer; - private LoadMoreCommentsButton loadMoreCommentsButton; + private LoadRepliesButton loadRepliesButton; private ShowMoreButton showMoreButton; - private RepliesButton repliesButton; + private ShowRepliesButton showRepliesButton; private ChevronButton chevronButton; private DeletedCommentsCounter deletedCommentsCounter; @@ -81,7 +81,7 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(margin) { Left = margin + 5 }, + Padding = new MarginPadding(margin) { Left = margin + 5, Top = Comment.IsTopLevel ? 10 : 0 }, Child = content = new GridContainer { RelativeSizeAxes = Axes.X, @@ -163,26 +163,34 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Right = 40 } }, - info = new FillFlowContainer + new FillFlowContainer { AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), + Direction = FillDirection.Vertical, Children = new Drawable[] { - new OsuSpriteText + info = new FillFlowContainer { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12), - Colour = OsuColour.Gray(0.7f), - Text = HumanizerUtils.Humanize(Comment.CreatedAt) + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Colour = OsuColour.Gray(0.7f), + Text = HumanizerUtils.Humanize(Comment.CreatedAt) + }, + } }, - repliesButton = new RepliesButton(Comment.RepliesCount) + showRepliesButton = new ShowRepliesButton(Comment.RepliesCount) { Expanded = { BindTarget = childrenExpanded } }, - loadMoreCommentsButton = new LoadMoreCommentsButton + loadRepliesButton = new LoadRepliesButton { Action = () => RepliesRequested(this, ++currentPage) } @@ -339,14 +347,14 @@ namespace osu.Game.Overlays.Comments var loadedReplesCount = loadedReplies.Count; var hasUnloadedReplies = loadedReplesCount != Comment.RepliesCount; - loadMoreCommentsButton.FadeTo(hasUnloadedReplies && loadedReplesCount == 0 ? 1 : 0); + loadRepliesButton.FadeTo(hasUnloadedReplies && loadedReplesCount == 0 ? 1 : 0); showMoreButton.FadeTo(hasUnloadedReplies && loadedReplesCount > 0 ? 1 : 0); - repliesButton.FadeTo(loadedReplesCount != 0 ? 1 : 0); + showRepliesButton.FadeTo(loadedReplesCount != 0 ? 1 : 0); if (Comment.IsTopLevel) chevronButton.FadeTo(loadedReplesCount != 0 ? 1 : 0); - showMoreButton.IsLoading = loadMoreCommentsButton.IsLoading = false; + showMoreButton.IsLoading = loadRepliesButton.IsLoading = false; } private class ChevronButton : ShowChildrenButton @@ -367,38 +375,6 @@ namespace osu.Game.Overlays.Comments } } - private class RepliesButton : ShowChildrenButton - { - private readonly SpriteText text; - private readonly int count; - - public RepliesButton(int count) - { - this.count = count; - - Child = text = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - }; - } - - protected override void OnExpandedChanged(ValueChangedEvent expanded) - { - text.Text = $@"{(expanded.NewValue ? "[-]" : "[+]")} replies ({count})"; - } - } - - private class LoadMoreCommentsButton : GetCommentRepliesButton - { - public LoadMoreCommentsButton() - { - IdleColour = OsuColour.Gray(0.7f); - HoverColour = Color4.White; - } - - protected override string GetText() => @"[+] load replies"; - } - private class ShowMoreButton : GetCommentRepliesButton { [BackgroundDependencyLoader]