// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; using osu.Game.Users; using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays { public class UserProfileOverlay : WaveOverlayContainer { private ProfileSection lastSection; private ProfileSection[] sections; private GetUserRequest userReq; private APIAccess api; protected ProfileHeader Header; private SectionsContainer sectionsContainer; private ProfileTabControl tabs; public const float CONTENT_X_MARGIN = 50; public UserProfileOverlay() { Waves.FirstWaveColour = OsuColour.Gray(0.4f); Waves.SecondWaveColour = OsuColour.Gray(0.3f); Waves.ThirdWaveColour = OsuColour.Gray(0.2f); Waves.FourthWaveColour = OsuColour.Gray(0.1f); RelativeSizeAxes = Axes.Both; RelativePositionAxes = Axes.Both; Width = 0.85f; Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; Masking = true; EdgeEffect = new EdgeEffectParameters { Colour = Color4.Black.Opacity(0), Type = EdgeEffectType.Shadow, Radius = 10 }; } [BackgroundDependencyLoader] private void load(APIAccess api) { this.api = api; } protected override void PopIn() { base.PopIn(); FadeEdgeEffectTo(0.5f, WaveContainer.APPEAR_DURATION, Easing.In); } protected override void PopOut() { base.PopOut(); FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out); } public void ShowUser(long userId) => ShowUser(new User { Id = userId }); public void ShowUser(User user, bool fetchOnline = true) { if (user == User.SYSTEM_USER) return; Show(); if (user.Id == Header?.User?.Id) return; userReq?.Cancel(); Clear(); lastSection = null; sections = new ProfileSection[] { //new AboutSection(), new RecentSection(), new RanksSection(), //new MedalsSection(), new HistoricalSection(), new BeatmapsSection(), new KudosuSection() }; tabs = new ProfileTabControl { RelativeSizeAxes = Axes.X, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Height = 30 }; Add(new Box { RelativeSizeAxes = Axes.Both, Colour = OsuColour.Gray(0.2f) }); Header = new ProfileHeader(user); Add(sectionsContainer = new SectionsContainer { RelativeSizeAxes = Axes.Both, ExpandableHeader = Header, FixedHeader = tabs, HeaderBackground = new Box { Colour = OsuColour.Gray(34), RelativeSizeAxes = Axes.Both } }); sectionsContainer.SelectedSection.ValueChanged += section => { if (lastSection != section.NewValue) { lastSection = section.NewValue; tabs.Current.Value = lastSection; } }; tabs.Current.ValueChanged += section => { if (lastSection == null) { lastSection = sectionsContainer.Children.FirstOrDefault(); if (lastSection != null) tabs.Current.Value = lastSection; return; } if (lastSection != section.NewValue) { lastSection = section.NewValue; sectionsContainer.ScrollTo(lastSection); } }; if (fetchOnline) { userReq = new GetUserRequest(user.Id); userReq.Success += userLoadComplete; api.Queue(userReq); } else { userReq = null; userLoadComplete(user); } sectionsContainer.ScrollToTop(); } private void userLoadComplete(User user) { Header.User = user; if (user.ProfileOrder != null) { foreach (string id in user.ProfileOrder) { var sec = sections.FirstOrDefault(s => s.Identifier == id); if (sec != null) { sec.User.Value = user; sectionsContainer.Add(sec); tabs.AddItem(sec); } } } } private class ProfileTabControl : PageTabControl { private readonly Box bottom; public ProfileTabControl() { TabContainer.RelativeSizeAxes &= ~Axes.X; TabContainer.AutoSizeAxes |= Axes.X; TabContainer.Anchor |= Anchor.x1; TabContainer.Origin |= Anchor.x1; AddInternal(bottom = new Box { RelativeSizeAxes = Axes.X, Height = 1, Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, EdgeSmoothness = new Vector2(1) }); } protected override TabItem CreateTabItem(ProfileSection value) => new ProfileTabItem(value); protected override Dropdown CreateDropdown() => null; private class ProfileTabItem : PageTabItem { public ProfileTabItem(ProfileSection value) : base(value) { Text.Text = value.Title; } } [BackgroundDependencyLoader] private void load(OsuColour colours) { bottom.Colour = colours.Yellow; } } } }