diff --git a/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs index fe8437be17..e60adcee34 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs @@ -41,6 +41,7 @@ namespace osu.Game.Tests.Visual.Online private class TestFullscreenOverlay : FullscreenOverlay { public TestFullscreenOverlay() + : base(OverlayColourScheme.Pink) { Children = new Drawable[] { diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index b4408343c4..523de4e38f 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -31,6 +31,9 @@ namespace osu.Game.Tests.Visual.Online typeof(ProfileHeaderButton) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + [Resolved] private IAPIProvider api { get; set; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs index 814a9ebf10..be0933e9d4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Allocation; using osu.Framework.Graphics.Textures; using osu.Game.Graphics.UserInterface; -using osu.Game.Graphics; using osu.Framework.Graphics.Shapes; using osuTK.Graphics; @@ -53,13 +52,13 @@ namespace osu.Game.Tests.Visual.UserInterface } }); - addHeader("Blue OverlayHeader", new TestNoControlHeader(OverlayColourScheme.Blue)); - addHeader("Green TabControlOverlayHeader (string)", new TestStringTabControlHeader(OverlayColourScheme.Green)); - addHeader("Pink TabControlOverlayHeader (enum)", new TestEnumTabControlHeader(OverlayColourScheme.Pink)); - addHeader("Red BreadcrumbControlOverlayHeader", new TestBreadcrumbControlHeader(OverlayColourScheme.Red)); + addHeader("Blue OverlayHeader", new TestNoControlHeader(), OverlayColourScheme.Blue); + addHeader("Green TabControlOverlayHeader (string)", new TestStringTabControlHeader(), OverlayColourScheme.Green); + addHeader("Pink TabControlOverlayHeader (enum)", new TestEnumTabControlHeader(), OverlayColourScheme.Pink); + addHeader("Red BreadcrumbControlOverlayHeader", new TestBreadcrumbControlHeader(), OverlayColourScheme.Red); } - private void addHeader(string name, OverlayHeader header) + private void addHeader(string name, OverlayHeader header, OverlayColourScheme colourScheme) { flow.Add(new FillFlowContainer { @@ -75,25 +74,35 @@ namespace osu.Game.Tests.Visual.UserInterface Margin = new MarginPadding(20), Text = name, }, - header.With(h => + new ColourProvidedContainer(colourScheme, header) { - h.Anchor = Anchor.TopCentre; - h.Origin = Anchor.TopCentre; - }) + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + } } }); } + private class ColourProvidedContainer : Container + { + [Cached] + private readonly OverlayColourProvider colourProvider; + + public ColourProvidedContainer(OverlayColourScheme colourScheme, OverlayHeader header) + { + colourProvider = new OverlayColourProvider(colourScheme); + + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + Add(header); + } + } + private class TestNoControlHeader : OverlayHeader { protected override Drawable CreateBackground() => new TestBackground(); protected override ScreenTitle CreateTitle() => new TestTitle(); - - public TestNoControlHeader(OverlayColourScheme colourScheme) - : base(colourScheme) - { - } } private class TestStringTabControlHeader : TabControlOverlayHeader @@ -102,8 +111,7 @@ namespace osu.Game.Tests.Visual.UserInterface protected override ScreenTitle CreateTitle() => new TestTitle(); - public TestStringTabControlHeader(OverlayColourScheme colourScheme) - : base(colourScheme) + public TestStringTabControlHeader() { TabControl.AddItem("tab1"); TabControl.AddItem("tab2"); @@ -112,11 +120,6 @@ namespace osu.Game.Tests.Visual.UserInterface private class TestEnumTabControlHeader : TabControlOverlayHeader { - public TestEnumTabControlHeader(OverlayColourScheme colourScheme) - : base(colourScheme) - { - } - protected override Drawable CreateBackground() => new TestBackground(); protected override ScreenTitle CreateTitle() => new TestTitle(); @@ -135,8 +138,7 @@ namespace osu.Game.Tests.Visual.UserInterface protected override ScreenTitle CreateTitle() => new TestTitle(); - public TestBreadcrumbControlHeader(OverlayColourScheme colourScheme) - : base(colourScheme) + public TestBreadcrumbControlHeader() { TabControl.AddItem("tab1"); TabControl.AddItem("tab2"); diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 53a40f5613..c8298543a1 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -3,7 +3,6 @@ using System; using osu.Game.Beatmaps; -using osuTK; using osuTK.Graphics; namespace osu.Game.Graphics @@ -78,46 +77,6 @@ namespace osu.Game.Graphics } } - public Color4 ForOverlayElement(OverlayColourScheme colourScheme, float saturation, float lightness, float opacity = 1) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, opacity)); - - // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 - private static float getBaseHue(OverlayColourScheme colourScheme) - { - float hue; - - switch (colourScheme) - { - default: - throw new ArgumentException($@"{colourScheme} colour scheme does not provide a hue value in {nameof(getBaseHue)}."); - - case OverlayColourScheme.Red: - hue = 0; - break; - - case OverlayColourScheme.Pink: - hue = 333; - break; - - case OverlayColourScheme.Orange: - hue = 46; - break; - - case OverlayColourScheme.Green: - hue = 115; - break; - - case OverlayColourScheme.Purple: - hue = 255; - break; - - case OverlayColourScheme.Blue: - hue = 200; - break; - } - - return hue / 360f; - } - // See https://github.com/ppy/osu-web/blob/master/resources/assets/less/colors.less public readonly Color4 PurpleLighter = FromHex(@"eeeeff"); public readonly Color4 PurpleLight = FromHex(@"aa88ff"); @@ -220,14 +179,4 @@ namespace osu.Game.Graphics public readonly Color4 ContextMenuGray = FromHex(@"223034"); } - - public enum OverlayColourScheme - { - Red, - Pink, - Orange, - Green, - Purple, - Blue - } } diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 50fb2782d4..e4e928df18 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -34,6 +34,7 @@ namespace osu.Game.Overlays public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; public BeatmapSetOverlay() + : base(OverlayColourScheme.Blue) { OsuScrollContainer scroll; Info info; diff --git a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs index bc9108929d..1d8411dfcc 100644 --- a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs +++ b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs @@ -3,7 +3,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays @@ -12,11 +11,6 @@ namespace osu.Game.Overlays { protected override OsuTabControl CreateTabControl() => new OverlayHeaderBreadcrumbControl(); - protected BreadcrumbControlOverlayHeader(OverlayColourScheme colourScheme) - : base(colourScheme) - { - } - public class OverlayHeaderBreadcrumbControl : BreadcrumbControl { public OverlayHeaderBreadcrumbControl() diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 484a800992..b1e4bcb7c1 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; @@ -26,7 +25,6 @@ namespace osu.Game.Overlays.Changelog private const string listing_string = "listing"; public ChangelogHeader() - : base(OverlayColourScheme.Purple) { TabControl.AddItem(listing_string); TabControl.Current.ValueChanged += e => diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 15b0079277..412e29735a 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -36,14 +36,14 @@ namespace osu.Game.Overlays private List streams; + public ChangelogOverlay() + : base(OverlayColourScheme.Purple) + { + } + [BackgroundDependencyLoader] private void load(AudioManager audio, OsuColour colour) { - Waves.FirstWaveColour = colour.GreyVioletLight; - Waves.SecondWaveColour = colour.GreyViolet; - Waves.ThirdWaveColour = colour.GreyVioletDark; - Waves.FourthWaveColour = colour.GreyVioletDarker; - Children = new Drawable[] { new Box diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 9daf55c796..e4cef319fe 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -84,14 +84,8 @@ namespace osu.Game.Overlays } public DirectOverlay() + : base(OverlayColourScheme.Blue) { - // osu!direct colours are not part of the standard palette - - Waves.FirstWaveColour = OsuColour.FromHex(@"19b0e2"); - Waves.SecondWaveColour = OsuColour.FromHex(@"2280a2"); - Waves.ThirdWaveColour = OsuColour.FromHex(@"005774"); - Waves.FourthWaveColour = OsuColour.FromHex(@"003a4e"); - ScrollFlow.Children = new Drawable[] { resultCountsContainer = new FillFlowContainer diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 0911ee84de..959f6749d2 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -6,7 +6,6 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; -using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API; using osuTK.Graphics; @@ -18,12 +17,12 @@ namespace osu.Game.Overlays [Resolved] protected IAPIProvider API { get; private set; } - protected FullscreenOverlay() + [Cached] + private readonly OverlayColourProvider colourProvider; + + protected FullscreenOverlay(OverlayColourScheme colourScheme) { - Waves.FirstWaveColour = OsuColour.Gray(0.4f); - Waves.SecondWaveColour = OsuColour.Gray(0.3f); - Waves.ThirdWaveColour = OsuColour.Gray(0.2f); - Waves.FourthWaveColour = OsuColour.Gray(0.1f); + colourProvider = new OverlayColourProvider(colourScheme); RelativeSizeAxes = Axes.Both; RelativePositionAxes = Axes.Both; @@ -41,6 +40,15 @@ namespace osu.Game.Overlays }; } + [BackgroundDependencyLoader] + private void load() + { + Waves.FirstWaveColour = colourProvider.Light4; + Waves.SecondWaveColour = colourProvider.Light3; + Waves.ThirdWaveColour = colourProvider.Dark4; + Waves.FourthWaveColour = colourProvider.Dark3; + } + public override void Show() { if (State.Value == Visibility.Visible) diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index 7d9fce11f1..2f9cde1687 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using System; @@ -23,7 +22,6 @@ namespace osu.Game.Overlays.News public Action ShowFrontPage; public NewsHeader() - : base(OverlayColourScheme.Purple) { TabControl.AddItem(front_page_string); diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index e7471cb21d..6dde300556 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -21,6 +21,11 @@ namespace osu.Game.Overlays public readonly Bindable Current = new Bindable(null); + public NewsOverlay() + : base(OverlayColourScheme.Purple) + { + } + [BackgroundDependencyLoader] private void load(OsuColour colours) { diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs new file mode 100644 index 0000000000..9816f313ad --- /dev/null +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -0,0 +1,80 @@ +// 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 osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays +{ + public class OverlayColourProvider + { + private readonly OverlayColourScheme colourScheme; + + public OverlayColourProvider(OverlayColourScheme colourScheme) + { + this.colourScheme = colourScheme; + } + + public Color4 Highlight1 => getColour(1, 0.7f); + public Color4 Content1 => getColour(0.4f, 1); + public Color4 Content2 => getColour(0.4f, 0.9f); + public Color4 Light1 => getColour(0.4f, 0.8f); + public Color4 Light2 => getColour(0.4f, 0.75f); + public Color4 Light3 => getColour(0.4f, 0.7f); + public Color4 Light4 => getColour(0.4f, 0.5f); + public Color4 Dark1 => getColour(0.2f, 0.35f); + public Color4 Dark2 => getColour(0.2f, 0.3f); + public Color4 Dark3 => getColour(0.2f, 0.25f); + public Color4 Dark4 => getColour(0.2f, 0.2f); + public Color4 Dark5 => getColour(0.2f, 0.15f); + public Color4 Dark6 => getColour(0.2f, 0.1f); + public Color4 Foreground1 => getColour(0.1f, 0.6f); + public Color4 Background1 => getColour(0.1f, 0.4f); + public Color4 Background2 => getColour(0.1f, 0.3f); + public Color4 Background3 => getColour(0.1f, 0.25f); + public Color4 Background4 => getColour(0.1f, 0.2f); + public Color4 Background5 => getColour(0.1f, 0.15f); + public Color4 Background6 => getColour(0.1f, 0.1f); + + private Color4 getColour(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); + + // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 + private static float getBaseHue(OverlayColourScheme colourScheme) + { + switch (colourScheme) + { + default: + throw new ArgumentException($@"{colourScheme} colour scheme does not provide a hue value in {nameof(getBaseHue)}."); + + case OverlayColourScheme.Red: + return 0; + + case OverlayColourScheme.Pink: + return 333 / 360f; + + case OverlayColourScheme.Orange: + return 46 / 360f; + + case OverlayColourScheme.Green: + return 115 / 360f; + + case OverlayColourScheme.Purple: + return 255 / 360f; + + case OverlayColourScheme.Blue: + return 200 / 360f; + } + } + } + + public enum OverlayColourScheme + { + Red, + Pink, + Orange, + Green, + Purple, + Blue + } +} diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index 353e14c20d..509aa175ed 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -25,12 +25,8 @@ namespace osu.Game.Overlays set => background.Height = value; } - protected OverlayColourScheme ColourScheme { get; } - - protected OverlayHeader(OverlayColourScheme colourScheme) + protected OverlayHeader() { - ColourScheme = colourScheme; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -85,10 +81,10 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - titleBackground.Colour = colours.ForOverlayElement(ColourScheme, 0.2f, 0.15f); - title.AccentColour = colours.ForOverlayElement(ColourScheme, 1, 0.7f); + titleBackground.Colour = colourProvider.Dark5; + title.AccentColour = colourProvider.Highlight1; } protected abstract Drawable CreateBackground(); diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 2ad852a29f..203df2ec12 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -24,7 +24,6 @@ namespace osu.Game.Overlays.Profile private DetailHeaderContainer detailHeaderContainer; public ProfileHeader() - : base(OverlayColourScheme.Green) { BackgroundHeight = 150; diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index c8874ef891..1ab18b8c15 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -25,7 +25,6 @@ namespace osu.Game.Overlays private readonly Bindable ruleset = new Bindable(); private readonly BasicScrollContainer scrollFlow; - private readonly Box background; private readonly Container tableContainer; private readonly DimmedLoadingLayer loading; @@ -36,12 +35,14 @@ namespace osu.Game.Overlays private IAPIProvider api { get; set; } public RankingsOverlay() + : base(OverlayColourScheme.Green) { Children = new Drawable[] { - background = new Box + new Box { RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.1f), }, scrollFlow = new BasicScrollContainer { @@ -85,17 +86,6 @@ namespace osu.Game.Overlays }; } - [BackgroundDependencyLoader] - private void load(OsuColour colour) - { - Waves.FirstWaveColour = colour.Green; - Waves.SecondWaveColour = colour.GreenLight; - Waves.ThirdWaveColour = colour.GreenDark; - Waves.FourthWaveColour = colour.GreenDarker; - - background.Colour = OsuColour.Gray(0.1f); - } - protected override void LoadComplete() { Country.BindValueChanged(_ => diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 5975e94ffc..0783c64c20 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -16,6 +16,11 @@ namespace osu.Game.Overlays.SearchableList public abstract class SearchableListOverlay : FullscreenOverlay { public const float WIDTH_PADDING = 80; + + protected SearchableListOverlay(OverlayColourScheme colourScheme) + : base(colourScheme) + { + } } public abstract class SearchableListOverlay : SearchableListOverlay @@ -35,7 +40,8 @@ namespace osu.Game.Overlays.SearchableList protected abstract SearchableListHeader CreateHeader(); protected abstract SearchableListFilterControl CreateFilterControl(); - protected SearchableListOverlay() + protected SearchableListOverlay(OverlayColourScheme colourScheme) + : base(colourScheme) { Children = new Drawable[] { diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 0c99962def..9a523bc1bc 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -52,12 +52,8 @@ namespace osu.Game.Overlays } public SocialOverlay() + : base(OverlayColourScheme.Pink) { - Waves.FirstWaveColour = OsuColour.FromHex(@"cb5fa0"); - Waves.SecondWaveColour = OsuColour.FromHex(@"b04384"); - Waves.ThirdWaveColour = OsuColour.FromHex(@"9b2b6e"); - Waves.FourthWaveColour = OsuColour.FromHex(@"6d214d"); - Add(loading = new LoadingAnimation()); Filter.Search.Current.ValueChanged += text => diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index d5017fb4d7..b410739b25 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -23,8 +23,7 @@ namespace osu.Game.Overlays private readonly Box controlBackground; - protected TabControlOverlayHeader(OverlayColourScheme colourScheme) - : base(colourScheme) + protected TabControlOverlayHeader() { HeaderInfo.Add(new Container { @@ -42,10 +41,10 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - TabControl.AccentColour = colours.ForOverlayElement(ColourScheme, 1, 0.75f); - controlBackground.Colour = colours.ForOverlayElement(ColourScheme, 0.2f, 0.2f); + TabControl.AccentColour = colourProvider.Highlight1; + controlBackground.Colour = colourProvider.Dark4; } [NotNull] diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index a34fc619a8..07c0dbed43 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -29,6 +29,11 @@ namespace osu.Game.Overlays public const float CONTENT_X_MARGIN = 70; + public UserProfileOverlay() + : base(OverlayColourScheme.Green) + { + } + public void ShowUser(long userId) => ShowUser(new User { Id = userId }); public void ShowUser(User user, bool fetchOnline = true)