diff --git a/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs index 31eab7f74e..a53a818065 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs @@ -54,7 +54,7 @@ namespace osu.Game.Tests.Visual.Online API.Logout(); localUser = API.LocalUser.GetBoundCopy(); - localUser.BindValueChanged(user => { userPanelArea.Child = new UserPanel(user.NewValue) { Width = 200 }; }, true); + localUser.BindValueChanged(user => { userPanelArea.Child = new UserGridPanel(user.NewValue) { Width = 200 }; }, true); AddStep("logout", API.Logout); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneSocialOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneSocialOverlay.cs index dbd7544b38..24341cbd05 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneSocialOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneSocialOverlay.cs @@ -18,10 +18,9 @@ namespace osu.Game.Tests.Visual.Online public override IReadOnlyList RequiredTypes => new[] { typeof(UserPanel), - typeof(SocialPanel), typeof(FilterControl), - typeof(SocialGridPanel), - typeof(SocialListPanel) + typeof(UserGridPanel), + typeof(UserListPanel) }; public TestSceneSocialOverlay() diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs index 54f06d6ad2..f4c96ac251 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -13,6 +15,13 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestSceneUserPanel : OsuTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(UserPanel), + typeof(UserListPanel), + typeof(UserGridPanel), + }; + private readonly UserPanel peppy; public TestSceneUserPanel() @@ -23,18 +32,19 @@ namespace osu.Game.Tests.Visual.Online { Anchor = Anchor.Centre, Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, Spacing = new Vector2(10f), Children = new[] { - flyte = new UserPanel(new User + flyte = new UserGridPanel(new User { Username = @"flyte", Id = 3103765, Country = new Country { FlagName = @"JP" }, CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg" }) { Width = 300 }, - peppy = new UserPanel(new User + peppy = new UserGridPanel(new User { Username = @"peppy", Id = 2, @@ -43,6 +53,15 @@ namespace osu.Game.Tests.Visual.Online IsSupporter = true, SupportLevel = 3, }) { Width = 300 }, + new UserListPanel(new User + { + Username = @"Evast", + Id = 8195163, + Country = new Country { FlagName = @"BY" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/8195163/4a8e2ad5a02a2642b631438cfa6c6bd7e2f9db289be881cb27df18331f64144c.jpeg", + IsOnline = false, + LastVisit = DateTimeOffset.Now + }) }, }); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneUserCard.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneUserCard.cs deleted file mode 100644 index 0d5967b5a8..0000000000 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneUserCard.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics.Cursor; -using osu.Game.Graphics.UserInterfaceV2.Users; -using osu.Game.Overlays; -using osu.Game.Users; -using osuTK; - -namespace osu.Game.Tests.Visual.UserInterface -{ - public class TestSceneUserCard : OsuTestScene - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(UserCard), - typeof(UserGridCard), - typeof(UserListCard) - }; - - [Cached] - private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); - - public TestSceneUserCard() - { - Add(new OsuContextMenuContainer - { - RelativeSizeAxes = Axes.Both, - Child = new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Spacing = new Vector2(0, 10), - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10), - Children = new Drawable[] - { - new UserGridCard(new User - { - Username = @"flyte", - Id = 3103765, - Country = new Country { FlagName = @"JP" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg", - IsOnline = true, - IsSupporter = true, - SupportLevel = 3, - }), - new UserGridCard(new User - { - Username = @"Evast", - Id = 8195163, - Country = new Country { FlagName = @"BY" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/8195163/4a8e2ad5a02a2642b631438cfa6c6bd7e2f9db289be881cb27df18331f64144c.jpeg", - IsOnline = false, - LastVisit = DateTimeOffset.Now - }) - } - }, - new UserListCard(new User - { - Username = @"peppy", - Id = 2, - Country = new Country { FlagName = @"AU" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg", - IsSupporter = true, - SupportLevel = 3, - IsOnline = false, - LastVisit = DateTimeOffset.Now - }), - new UserListCard(new User - { - Username = @"chocomint", - Id = 124493, - Country = new Country { FlagName = @"KR" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c5.jpg", - IsOnline = true, - }), - } - } - }); - } - } -} diff --git a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs index ca8bce1cca..bbbc948811 100644 --- a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs @@ -311,7 +311,7 @@ namespace osu.Game.Tournament.Screens.Editors private void updatePanel() { - drawableContainer.Child = new UserPanel(user) { Width = 300 }; + drawableContainer.Child = new UserGridPanel(user) { Width = 300 }; } } } diff --git a/osu.Game/Graphics/UserInterfaceV2/Users/UserCard.cs b/osu.Game/Graphics/UserInterfaceV2/Users/UserCard.cs deleted file mode 100644 index 4808990c70..0000000000 --- a/osu.Game/Graphics/UserInterfaceV2/Users/UserCard.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Game.Overlays; -using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics.UserInterface; -using osu.Framework.Graphics.Cursor; -using osu.Game.Graphics.Containers; -using osu.Game.Users; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using System.Collections.Generic; -using osu.Framework.Input.Events; -using osu.Framework.Graphics.Shapes; -using JetBrains.Annotations; -using osu.Game.Users.Drawables; -using osuTK; -using osu.Game.Graphics.Sprites; -using osu.Framework.Graphics.Sprites; -using osuTK.Graphics; -using osu.Game.Online.Chat; - -namespace osu.Game.Graphics.UserInterfaceV2.Users -{ - public abstract class UserCard : OsuHoverContainer, IHasContextMenu - { - public User User { get; } - - protected override IEnumerable EffectTargets => null; - - protected DelayedLoadUnloadWrapper Background; - - protected UserCard(User user) - { - if (user == null) - throw new ArgumentNullException(nameof(user)); - - User = user; - } - - [Resolved(canBeNull: true)] - private UserProfileOverlay profileOverlay { get; set; } - - [Resolved(canBeNull: true)] - private ChannelManager channelManager { get; set; } - - [Resolved(canBeNull: true)] - private ChatOverlay chatOverlay { get; set; } - - [Resolved] - private OsuColour colours { get; set; } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - Action = () => profileOverlay?.ShowUser(User); - - Masking = true; - BorderColour = colours.GreyVioletLighter; - - AddRange(new[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background5 - }, - Background = new DelayedLoadUnloadWrapper(() => new UserCoverBackground - { - RelativeSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - User = User, - }, 300, 5000) - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Both, - }, - CreateLayout() - }); - } - - [NotNull] - protected abstract Drawable CreateLayout(); - - protected UpdateableAvatar CreateAvatar() => new UpdateableAvatar - { - User = User, - OpenOnClick = { Value = false } - }; - - protected UpdateableFlag CreateFlag() => new UpdateableFlag(User.Country) - { - Size = new Vector2(39, 26) - }; - - protected OsuSpriteText CreateUsername() => new OsuSpriteText - { - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold, italics: true), - Text = User.Username, - }; - - protected SpriteIcon CreateStatusIcon() => new SpriteIcon - { - Icon = FontAwesome.Regular.Circle, - Size = new Vector2(25), - Colour = User.IsOnline ? colours.GreenLight : Color4.Black - }; - - protected FillFlowContainer CreateStatusMessage(bool rightAlignedChildren) - { - var status = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical - }; - - var alignment = rightAlignedChildren ? Anchor.x2 : Anchor.x0; - - if (!User.IsOnline && User.LastVisit.HasValue) - { - status.Add(new TextFlowContainer(t => t.Font = OsuFont.GetFont(size: 15)).With(text => - { - text.Anchor = Anchor.y1 | alignment; - text.Origin = Anchor.y1 | alignment; - text.AutoSizeAxes = Axes.Both; - text.AddText(@"Last seen "); - text.AddText(new DrawableDate(User.LastVisit.Value, italic: false)); - })); - } - - status.Add(new OsuSpriteText - { - Anchor = Anchor.y1 | alignment, - Origin = Anchor.y1 | alignment, - Font = OsuFont.GetFont(size: 17), - Text = User.IsOnline ? @"Online" : @"Offline" - }); - - return status; - } - - protected override bool OnHover(HoverEvent e) - { - BorderThickness = 2; - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - BorderThickness = 0; - base.OnHoverLost(e); - } - - public MenuItem[] ContextMenuItems => new MenuItem[] - { - new OsuMenuItem("View Profile", MenuItemType.Highlighted, Action), - new OsuMenuItem("Send message", MenuItemType.Standard, () => - { - channelManager?.OpenPrivateChannel(User); - chatOverlay?.Show(); - }) - }; - } -} diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index bf0e073350..3ab64786a2 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -143,7 +143,7 @@ namespace osu.Game.Overlays.Settings.Sections.General }, }, }, - panel = new UserPanel(api.LocalUser.Value) + panel = new UserGridPanel(api.LocalUser.Value) { RelativeSizeAxes = Axes.X, Action = RequestHide diff --git a/osu.Game/Overlays/Social/SocialGridPanel.cs b/osu.Game/Overlays/Social/SocialGridPanel.cs deleted file mode 100644 index 6f707d640b..0000000000 --- a/osu.Game/Overlays/Social/SocialGridPanel.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Users; - -namespace osu.Game.Overlays.Social -{ - public class SocialGridPanel : SocialPanel - { - public SocialGridPanel(User user) - : base(user) - { - Width = 300; - } - } -} diff --git a/osu.Game/Overlays/Social/SocialListPanel.cs b/osu.Game/Overlays/Social/SocialListPanel.cs deleted file mode 100644 index 1ba91e9204..0000000000 --- a/osu.Game/Overlays/Social/SocialListPanel.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Game.Users; - -namespace osu.Game.Overlays.Social -{ - public class SocialListPanel : SocialPanel - { - public SocialListPanel(User user) - : base(user) - { - RelativeSizeAxes = Axes.X; - } - } -} diff --git a/osu.Game/Overlays/Social/SocialPanel.cs b/osu.Game/Overlays/Social/SocialPanel.cs deleted file mode 100644 index 555527670a..0000000000 --- a/osu.Game/Overlays/Social/SocialPanel.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osuTK; -using osuTK.Graphics; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Effects; -using osu.Framework.Input.Events; -using osu.Game.Users; - -namespace osu.Game.Overlays.Social -{ - public class SocialPanel : UserPanel - { - private const double hover_transition_time = 400; - - public SocialPanel(User user) - : base(user) - { - } - - private readonly EdgeEffectParameters edgeEffectNormal = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 1f), - Radius = 2f, - Colour = Color4.Black.Opacity(0.25f), - }; - - private readonly EdgeEffectParameters edgeEffectHovered = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 5f), - Radius = 10f, - Colour = Color4.Black.Opacity(0.3f), - }; - - protected override bool OnHover(HoverEvent e) - { - Content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint); - Content.MoveToY(-4, hover_transition_time, Easing.OutQuint); - - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - Content.TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint); - Content.MoveToY(0, hover_transition_time, Easing.OutQuint); - - base.OnHoverLost(e); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - this.FadeInFromZero(200, Easing.Out); - } - } -} diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 54c978738d..5a9dd54d53 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays public class SocialOverlay : SearchableListOverlay { private readonly LoadingSpinner loading; - private FillFlowContainer panels; + private FillFlowContainer panels; protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b"); protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51"); @@ -158,7 +158,7 @@ namespace osu.Game.Overlays if (Filter.DisplayStyleControl.Dropdown.Current.Value == SortDirection.Descending) sortedUsers = sortedUsers.Reverse(); - var newPanels = new FillFlowContainer + var newPanels = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -166,20 +166,21 @@ namespace osu.Game.Overlays Margin = new MarginPadding { Top = 10 }, ChildrenEnumerable = sortedUsers.Select(u => { - SocialPanel panel; + UserPanel panel; switch (Filter.DisplayStyleControl.DisplayStyle.Value) { case PanelDisplayStyle.Grid: - panel = new SocialGridPanel(u) + panel = new UserGridPanel(u) { Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre + Origin = Anchor.TopCentre, + Width = 290, }; break; default: - panel = new SocialListPanel(u); + panel = new UserListPanel(u); break; } diff --git a/osu.Game/Graphics/UserInterfaceV2/Users/UserGridCard.cs b/osu.Game/Users/UserGridPanel.cs similarity index 93% rename from osu.Game/Graphics/UserInterfaceV2/Users/UserGridCard.cs rename to osu.Game/Users/UserGridPanel.cs index b6e704e901..f9c5c2b0cc 100644 --- a/osu.Game/Graphics/UserInterfaceV2/Users/UserGridCard.cs +++ b/osu.Game/Users/UserGridPanel.cs @@ -5,26 +5,25 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays.Profile.Header.Components; -using osu.Game.Users; using osuTK; -namespace osu.Game.Graphics.UserInterfaceV2.Users +namespace osu.Game.Users { - public class UserGridCard : UserCard + public class UserGridPanel : UserPanel { private const int margin = 10; - public UserGridCard(User user) + public UserGridPanel(User user) : base(user) { - Size = new Vector2(290, 120); + Height = 120; CornerRadius = 10; } [BackgroundDependencyLoader] private void load() { - Background.FadeTo(User.IsOnline ? 0.6f : 0.7f); + Background.FadeTo(0.6f); } protected override Drawable CreateLayout() diff --git a/osu.Game/Graphics/UserInterfaceV2/Users/UserListCard.cs b/osu.Game/Users/UserListPanel.cs similarity index 94% rename from osu.Game/Graphics/UserInterfaceV2/Users/UserListCard.cs rename to osu.Game/Users/UserListPanel.cs index 685556035e..087de13706 100644 --- a/osu.Game/Graphics/UserInterfaceV2/Users/UserListCard.cs +++ b/osu.Game/Users/UserListPanel.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.Users; using osu.Framework.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics.Colour; @@ -11,11 +10,11 @@ using osu.Framework.Graphics.Containers; using osuTK; using osu.Game.Overlays.Profile.Header.Components; -namespace osu.Game.Graphics.UserInterfaceV2.Users +namespace osu.Game.Users { - public class UserListCard : UserCard + public class UserListPanel : UserPanel { - public UserListCard(User user) + public UserListPanel(User user) : base(user) { RelativeSizeAxes = Axes.X; @@ -27,7 +26,7 @@ namespace osu.Game.Graphics.UserInterfaceV2.Users private void load() { Background.Width = 0.5f; - Background.Colour = ColourInfo.GradientHorizontal(Color4.White.Opacity(1), Color4.White.Opacity(User.IsOnline ? 0.6f : 0.7f)); + Background.Colour = ColourInfo.GradientHorizontal(Color4.White.Opacity(1), Color4.White.Opacity(0.6f)); } protected override Drawable CreateLayout() diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 6f34466e94..5a5f18dcfe 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -3,10 +3,8 @@ using System; using osuTK; -using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -16,32 +14,18 @@ using osu.Game.Overlays; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.Containers; -using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users.Drawables; +using JetBrains.Annotations; +using osu.Framework.Input.Events; namespace osu.Game.Users { - public class UserPanel : OsuClickableContainer, IHasContextMenu + public abstract class UserPanel : OsuClickableContainer, IHasContextMenu { - private const float height = 100; - private const float content_padding = 10; - private const float status_height = 30; - public readonly User User; - [Resolved(canBeNull: true)] - private OsuColour colours { get; set; } - - private Container statusBar; - private Box statusBg; - private OsuSpriteText statusMessage; - - private Container content; - protected override Container Content => content; - public readonly Bindable Status = new Bindable(); public readonly IBindable Activity = new Bindable(); @@ -50,164 +34,63 @@ namespace osu.Game.Users protected Action ViewProfile; - public UserPanel(User user) + protected DelayedLoadUnloadWrapper Background; + + private SpriteIcon statusIcon; + private OsuSpriteText statusMessage; + private TextFlowContainer lastVisitMessage; + + protected UserPanel(User user) { if (user == null) throw new ArgumentNullException(nameof(user)); User = user; - - Height = height - status_height; } - [BackgroundDependencyLoader(permitNulls: true)] - private void load(UserProfileOverlay profile) + [Resolved(canBeNull: true)] + private UserProfileOverlay profileOverlay { get; set; } + + [Resolved] + private OsuColour colours { get; set; } + + [BackgroundDependencyLoader] + private void load() { - if (colours == null) - throw new InvalidOperationException($"{nameof(colours)} not initialized!"); + Action = () => profileOverlay?.ShowUser(User); - FillFlowContainer infoContainer; + Masking = true; + BorderColour = colours.GreyVioletLighter; - AddInternal(content = new Container + AddRange(new[] { - RelativeSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 5, - EdgeEffect = new EdgeEffectParameters + new Box { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.25f), - Radius = 4, + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1 }, - - Children = new Drawable[] + Background = new DelayedLoadUnloadWrapper(() => new UserCoverBackground { - new DelayedLoadUnloadWrapper(() => new UserCoverBackground - { - RelativeSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - User = User, - }, 300, 5000) - { - RelativeSizeAxes = Axes.Both, - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.7f), - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Top = content_padding, Horizontal = content_padding }, - Children = new Drawable[] - { - new UpdateableAvatar - { - Size = new Vector2(height - status_height - content_padding * 2), - User = User, - Masking = true, - CornerRadius = 5, - OpenOnClick = { Value = false }, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.25f), - Radius = 4, - }, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = height - status_height - content_padding }, - Children = new Drawable[] - { - new OsuSpriteText - { - Text = User.Username, - Font = OsuFont.GetFont(weight: FontWeight.SemiBold, size: 18, italics: true), - }, - infoContainer = new FillFlowContainer - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - AutoSizeAxes = Axes.X, - Height = 20f, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5f, 0f), - Children = new Drawable[] - { - new UpdateableFlag(User.Country) - { - Width = 30f, - RelativeSizeAxes = Axes.Y, - }, - }, - }, - }, - }, - }, - }, - statusBar = new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - Alpha = 0f, - Children = new Drawable[] - { - statusBg = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0.5f, - }, - new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Spacing = new Vector2(5f, 0f), - Children = new Drawable[] - { - new SpriteIcon - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Icon = FontAwesome.Regular.Circle, - Shadow = true, - Size = new Vector2(14), - }, - statusMessage = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(weight: FontWeight.SemiBold), - }, - }, - }, - }, - }, - } + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + User = User, + }, 300, 5000) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Both, + }, + CreateLayout() }); - if (User.IsSupporter) - { - infoContainer.Add(new SupporterIcon - { - Height = 20f, - SupportLevel = User.SupportLevel - }); - } - Status.ValueChanged += status => displayStatus(status.NewValue, Activity.Value); Activity.ValueChanged += activity => displayStatus(Status.Value, activity.NewValue); base.Action = ViewProfile = () => { Action?.Invoke(); - profile?.ShowUser(User); + profileOverlay?.ShowUser(User); }; } @@ -217,33 +100,105 @@ namespace osu.Game.Users Status.TriggerChange(); } + protected override bool OnHover(HoverEvent e) + { + BorderThickness = 2; + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + BorderThickness = 0; + base.OnHoverLost(e); + } + + [NotNull] + protected abstract Drawable CreateLayout(); + + protected UpdateableAvatar CreateAvatar() => new UpdateableAvatar + { + User = User, + OpenOnClick = { Value = false } + }; + + protected UpdateableFlag CreateFlag() => new UpdateableFlag(User.Country) + { + Size = new Vector2(39, 26) + }; + + protected OsuSpriteText CreateUsername() => new OsuSpriteText + { + Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold, italics: true), + Text = User.Username, + }; + + protected SpriteIcon CreateStatusIcon() => statusIcon = new SpriteIcon + { + Icon = FontAwesome.Regular.Circle, + Size = new Vector2(25) + }; + + protected FillFlowContainer CreateStatusMessage(bool rightAlignedChildren) + { + var statusContainer = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical + }; + + var alignment = rightAlignedChildren ? Anchor.x2 : Anchor.x0; + + statusContainer.Add(lastVisitMessage = new TextFlowContainer(t => t.Font = OsuFont.GetFont(size: 15)).With(text => + { + text.Anchor = Anchor.y1 | alignment; + text.Origin = Anchor.y1 | alignment; + text.AutoSizeAxes = Axes.Both; + text.Alpha = 0; + + if (User.LastVisit.HasValue) + { + text.AddText(@"Last seen "); + text.AddText(new DrawableDate(User.LastVisit.Value, italic: false)); + } + })); + + statusContainer.Add(statusMessage = new OsuSpriteText + { + Anchor = Anchor.y1 | alignment, + Origin = Anchor.y1 | alignment, + Font = OsuFont.GetFont(size: 17) + }); + + return statusContainer; + } + private void displayStatus(UserStatus status, UserActivity activity = null) { - const float transition_duration = 500; + if (status != null) + { + if (activity != null && !(status is UserStatusOffline)) + { + statusMessage.Text = activity.Status; + statusIcon.FadeColour(activity.GetAppropriateColour(colours), 500, Easing.OutQuint); + } + else + { + lastVisitMessage.FadeTo(status is UserStatusOffline && User.LastVisit.HasValue ? 1 : 0); + statusMessage.Text = status.Message; + statusIcon.FadeColour(status.GetAppropriateColour(colours), 500, Easing.OutQuint); + } - if (status == null) - { - statusBar.ResizeHeightTo(0f, transition_duration, Easing.OutQuint); - statusBar.FadeOut(transition_duration, Easing.OutQuint); - this.ResizeHeightTo(height - status_height, transition_duration, Easing.OutQuint); - } - else - { - statusBar.ResizeHeightTo(status_height, transition_duration, Easing.OutQuint); - statusBar.FadeIn(transition_duration, Easing.OutQuint); - this.ResizeHeightTo(height, transition_duration, Easing.OutQuint); + return; } - if (status is UserStatusOnline && activity != null) + // Set local status according to web if it's null + if (User.IsOnline) { - statusMessage.Text = activity.Status; - statusBg.FadeColour(activity.GetAppropriateColour(colours), 500, Easing.OutQuint); - } - else - { - statusMessage.Text = status?.Message; - statusBg.FadeColour(status?.GetAppropriateColour(colours) ?? colours.Gray5, 500, Easing.OutQuint); + Status.Value = new UserStatusOnline(); + return; } + + Status.Value = new UserStatusOffline(); } public MenuItem[] ContextMenuItems => new MenuItem[] diff --git a/osu.Game/Users/UserStatus.cs b/osu.Game/Users/UserStatus.cs index cf372560af..21c18413f4 100644 --- a/osu.Game/Users/UserStatus.cs +++ b/osu.Game/Users/UserStatus.cs @@ -15,7 +15,7 @@ namespace osu.Game.Users public class UserStatusOnline : UserStatus { public override string Message => @"Online"; - public override Color4 GetAppropriateColour(OsuColour colours) => colours.BlueDarker; + public override Color4 GetAppropriateColour(OsuColour colours) => colours.GreenLight; } public abstract class UserStatusBusy : UserStatusOnline @@ -26,7 +26,7 @@ namespace osu.Game.Users public class UserStatusOffline : UserStatus { public override string Message => @"Offline"; - public override Color4 GetAppropriateColour(OsuColour colours) => colours.Gray7; + public override Color4 GetAppropriateColour(OsuColour colours) => Color4.Black; } public class UserStatusDoNotDisturb : UserStatus