1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-13 21:12:55 +08:00

Merge pull request #22006 from bdach/user-profile/ruleset-switching

Add ruleset switching to user profile overlay
This commit is contained in:
Dean Herbert 2023-01-12 13:54:13 +09:00 committed by GitHub
commit 7cf58190a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 141 additions and 57 deletions

View File

@ -11,6 +11,7 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile;
using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections;
using osu.Game.Rulesets.Osu;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
{ {
@ -38,8 +39,8 @@ namespace osu.Game.Tests.Visual.Online
Child = section = new HistoricalSection(), Child = section = new HistoricalSection(),
}); });
AddStep("Show peppy", () => section.User.Value = new UserProfileData(new APIUser { Id = 2 })); AddStep("Show peppy", () => section.User.Value = new UserProfileData(new APIUser { Id = 2 }, new OsuRuleset().RulesetInfo));
AddStep("Show WubWoofWolf", () => section.User.Value = new UserProfileData(new APIUser { Id = 39828 })); AddStep("Show WubWoofWolf", () => section.User.Value = new UserProfileData(new APIUser { Id = 39828 }, new OsuRuleset().RulesetInfo));
} }
} }
} }

View File

@ -13,6 +13,7 @@ using osu.Framework.Testing;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile;
using osu.Game.Rulesets.Osu;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
{ {
@ -44,49 +45,49 @@ namespace osu.Game.Tests.Visual.Online
[Test] [Test]
public void TestNullValues() public void TestNullValues()
{ {
AddStep("Load user", () => user.Value = new UserProfileData(user_with_null_values)); AddStep("Load user", () => user.Value = new UserProfileData(user_with_null_values, new OsuRuleset().RulesetInfo));
AddAssert("Section is hidden", () => section.Alpha == 0); AddAssert("Section is hidden", () => section.Alpha == 0);
} }
[Test] [Test]
public void TestEmptyValues() public void TestEmptyValues()
{ {
AddStep("Load user", () => user.Value = new UserProfileData(user_with_empty_values)); AddStep("Load user", () => user.Value = new UserProfileData(user_with_empty_values, new OsuRuleset().RulesetInfo));
AddAssert("Section is hidden", () => section.Alpha == 0); AddAssert("Section is hidden", () => section.Alpha == 0);
} }
[Test] [Test]
public void TestOneValue() public void TestOneValue()
{ {
AddStep("Load user", () => user.Value = new UserProfileData(user_with_one_value)); AddStep("Load user", () => user.Value = new UserProfileData(user_with_one_value, new OsuRuleset().RulesetInfo));
AddAssert("Section is hidden", () => section.Alpha == 0); AddAssert("Section is hidden", () => section.Alpha == 0);
} }
[Test] [Test]
public void TestTwoValues() public void TestTwoValues()
{ {
AddStep("Load user", () => user.Value = new UserProfileData(user_with_two_values)); AddStep("Load user", () => user.Value = new UserProfileData(user_with_two_values, new OsuRuleset().RulesetInfo));
AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Section is visible", () => section.Alpha == 1);
} }
[Test] [Test]
public void TestConstantValues() public void TestConstantValues()
{ {
AddStep("Load user", () => user.Value = new UserProfileData(user_with_constant_values)); AddStep("Load user", () => user.Value = new UserProfileData(user_with_constant_values, new OsuRuleset().RulesetInfo));
AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Section is visible", () => section.Alpha == 1);
} }
[Test] [Test]
public void TestConstantZeroValues() public void TestConstantZeroValues()
{ {
AddStep("Load user", () => user.Value = new UserProfileData(user_with_zero_values)); AddStep("Load user", () => user.Value = new UserProfileData(user_with_zero_values, new OsuRuleset().RulesetInfo));
AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Section is visible", () => section.Alpha == 1);
} }
[Test] [Test]
public void TestFilledValues() public void TestFilledValues()
{ {
AddStep("Load user", () => user.Value = new UserProfileData(user_with_filled_values)); AddStep("Load user", () => user.Value = new UserProfileData(user_with_filled_values, new OsuRuleset().RulesetInfo));
AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Section is visible", () => section.Alpha == 1);
AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength());
} }
@ -94,7 +95,7 @@ namespace osu.Game.Tests.Visual.Online
[Test] [Test]
public void TestMissingValues() public void TestMissingValues()
{ {
AddStep("Load user", () => user.Value = new UserProfileData(user_with_missing_values)); AddStep("Load user", () => user.Value = new UserProfileData(user_with_missing_values, new OsuRuleset().RulesetInfo));
AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Section is visible", () => section.Alpha == 1);
AddAssert("Array length is 7", () => getChartValuesLength() == 7); AddAssert("Array length is 7", () => getChartValuesLength() == 7);
} }

View File

@ -11,6 +11,7 @@ using osu.Framework.Bindables;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Profile;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
{ {
@ -21,25 +22,24 @@ namespace osu.Game.Tests.Visual.Online
public TestSceneProfileRulesetSelector() public TestSceneProfileRulesetSelector()
{ {
ProfileRulesetSelector selector; var user = new Bindable<UserProfileData?>();
var user = new Bindable<APIUser?>();
Child = selector = new ProfileRulesetSelector Child = new ProfileRulesetSelector
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
User = { BindTarget = user } User = { BindTarget = user }
}; };
AddStep("User on osu ruleset", () => user.Value = new UserProfileData(new APIUser { Id = 0, PlayMode = "osu" }, new OsuRuleset().RulesetInfo));
AddStep("User on taiko ruleset", () => user.Value = new UserProfileData(new APIUser { Id = 1, PlayMode = "osu" }, new TaikoRuleset().RulesetInfo));
AddStep("User on catch ruleset", () => user.Value = new UserProfileData(new APIUser { Id = 2, PlayMode = "osu" }, new CatchRuleset().RulesetInfo));
AddStep("User on mania ruleset", () => user.Value = new UserProfileData(new APIUser { Id = 3, PlayMode = "osu" }, new ManiaRuleset().RulesetInfo));
AddStep("set osu! as default", () => selector.SetDefaultRuleset(new OsuRuleset().RulesetInfo)); AddStep("User with osu as default", () => user.Value = new UserProfileData(new APIUser { Id = 0, PlayMode = "osu" }, new OsuRuleset().RulesetInfo));
AddStep("set taiko as default", () => selector.SetDefaultRuleset(new TaikoRuleset().RulesetInfo)); AddStep("User with taiko as default", () => user.Value = new UserProfileData(new APIUser { Id = 1, PlayMode = "taiko" }, new OsuRuleset().RulesetInfo));
AddStep("set catch as default", () => selector.SetDefaultRuleset(new CatchRuleset().RulesetInfo)); AddStep("User with catch as default", () => user.Value = new UserProfileData(new APIUser { Id = 2, PlayMode = "fruits" }, new OsuRuleset().RulesetInfo));
AddStep("set mania as default", () => selector.SetDefaultRuleset(new ManiaRuleset().RulesetInfo)); AddStep("User with mania as default", () => user.Value = new UserProfileData(new APIUser { Id = 3, PlayMode = "mania" }, new OsuRuleset().RulesetInfo));
AddStep("User with osu as default", () => user.Value = new APIUser { Id = 0, PlayMode = "osu" });
AddStep("User with taiko as default", () => user.Value = new APIUser { Id = 1, PlayMode = "taiko" });
AddStep("User with catch as default", () => user.Value = new APIUser { Id = 2, PlayMode = "fruits" });
AddStep("User with mania as default", () => user.Value = new APIUser { Id = 3, PlayMode = "mania" });
AddStep("null user", () => user.Value = null); AddStep("null user", () => user.Value = null);
} }
} }

View File

@ -9,6 +9,7 @@ using osu.Framework.Testing;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile;
using osu.Game.Rulesets.Osu;
using osu.Game.Users; using osu.Game.Users;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
@ -29,7 +30,7 @@ namespace osu.Game.Tests.Visual.Online
[Test] [Test]
public void TestBasic() public void TestBasic()
{ {
AddStep("Show example user", () => header.User.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); AddStep("Show example user", () => header.User.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER, new OsuRuleset().RulesetInfo));
} }
[Test] [Test]
@ -41,7 +42,7 @@ namespace osu.Game.Tests.Visual.Online
Username = "IAmOnline", Username = "IAmOnline",
LastVisit = DateTimeOffset.Now, LastVisit = DateTimeOffset.Now,
IsOnline = true, IsOnline = true,
})); }, new OsuRuleset().RulesetInfo));
AddStep("Show offline user", () => header.User.Value = new UserProfileData(new APIUser AddStep("Show offline user", () => header.User.Value = new UserProfileData(new APIUser
{ {
@ -49,7 +50,7 @@ namespace osu.Game.Tests.Visual.Online
Username = "IAmOffline", Username = "IAmOffline",
LastVisit = DateTimeOffset.Now.AddDays(-10), LastVisit = DateTimeOffset.Now.AddDays(-10),
IsOnline = false, IsOnline = false,
})); }, new OsuRuleset().RulesetInfo));
} }
[Test] [Test]
@ -71,7 +72,7 @@ namespace osu.Game.Tests.Visual.Online
Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray()
}, },
} }
})); }, new OsuRuleset().RulesetInfo));
AddStep("Show unranked user", () => header.User.Value = new UserProfileData(new APIUser AddStep("Show unranked user", () => header.User.Value = new UserProfileData(new APIUser
{ {
@ -87,7 +88,7 @@ namespace osu.Game.Tests.Visual.Online
Data = Enumerable.Range(2345, 85).ToArray() Data = Enumerable.Range(2345, 85).ToArray()
}, },
} }
})); }, new OsuRuleset().RulesetInfo));
} }
} }
} }

View File

@ -51,6 +51,31 @@ namespace osu.Game.Tests.Visual.Online
}); });
AddStep("show user", () => profile.ShowUser(new APIUser { Id = 1 })); AddStep("show user", () => profile.ShowUser(new APIUser { Id = 1 }));
AddToggleStep("toggle visibility", visible => profile.State.Value = visible ? Visibility.Visible : Visibility.Hidden); AddToggleStep("toggle visibility", visible => profile.State.Value = visible ? Visibility.Visible : Visibility.Hidden);
AddStep("log out", () => dummyAPI.Logout());
AddStep("log back in", () => dummyAPI.Login("username", "password"));
}
[Test]
public void TestLoading()
{
GetUserRequest pendingRequest = null!;
AddStep("set up request handling", () =>
{
dummyAPI.HandleRequest = req =>
{
if (req is GetUserRequest getUserRequest)
{
pendingRequest = getUserRequest;
return true;
}
return false;
};
});
AddStep("show user", () => profile.ShowUser(new APIUser { Id = 1 }));
AddWaitStep("wait some", 3);
AddStep("complete request", () => pendingRequest.TriggerSuccess(TEST_USER));
} }
public static readonly APIUser TEST_USER = new APIUser public static readonly APIUser TEST_USER = new APIUser
@ -103,6 +128,7 @@ namespace osu.Game.Tests.Visual.Online
Title = "osu!volunteer", Title = "osu!volunteer",
Colour = "ff0000", Colour = "ff0000",
Achievements = Array.Empty<APIUserAchievement>(), Achievements = Array.Empty<APIUserAchievement>(),
PlayMode = "osu"
}; };
} }
} }

View File

@ -12,6 +12,7 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile;
using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections;
using osu.Game.Rulesets.Osu;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
{ {
@ -45,7 +46,7 @@ namespace osu.Game.Tests.Visual.Online
} }
}); });
AddStep("Show cookiezi", () => ranks.User.Value = new UserProfileData(new APIUser { Id = 124493 })); AddStep("Show cookiezi", () => ranks.User.Value = new UserProfileData(new APIUser { Id = 124493 }, new OsuRuleset().RulesetInfo));
} }
} }
} }

View File

@ -1,22 +1,39 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Extensions;
using osu.Game.Rulesets; using osu.Game.Rulesets;
namespace osu.Game.Overlays.Profile.Header.Components namespace osu.Game.Overlays.Profile.Header.Components
{ {
public partial class ProfileRulesetSelector : OverlayRulesetSelector public partial class ProfileRulesetSelector : OverlayRulesetSelector
{ {
public readonly Bindable<APIUser?> User = new Bindable<APIUser?>(); [Resolved]
private UserProfileOverlay? profileOverlay { get; set; }
public readonly Bindable<UserProfileData?> User = new Bindable<UserProfileData?>();
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.LoadComplete(); base.LoadComplete();
User.BindValueChanged(u => SetDefaultRuleset(Rulesets.GetRuleset(u.NewValue?.PlayMode ?? "osu").AsNonNull()), true);
User.BindValueChanged(user => updateState(user.NewValue), true);
Current.BindValueChanged(ruleset =>
{
if (User.Value != null && !ruleset.NewValue.Equals(User.Value.Ruleset))
profileOverlay?.ShowUser(User.Value.User, ruleset.NewValue);
});
}
private void updateState(UserProfileData? user)
{
Current.Value = Items.SingleOrDefault(ruleset => user?.Ruleset.MatchesOnlineID(ruleset) == true);
SetDefaultRuleset(Rulesets.GetRuleset(user?.User.PlayMode ?? @"osu").AsNonNull());
} }
public void SetDefaultRuleset(RulesetInfo ruleset) public void SetDefaultRuleset(RulesetInfo ruleset)

View File

@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Overlays.Profile.Header; using osu.Game.Overlays.Profile.Header;
using osu.Game.Overlays.Profile.Header.Components;
using osu.Game.Resources.Localisation.Web; using osu.Game.Resources.Localisation.Web;
using osu.Game.Users; using osu.Game.Users;
@ -35,6 +36,13 @@ namespace osu.Game.Overlays.Profile
// todo: pending implementation. // todo: pending implementation.
// TabControl.AddItem(LayoutStrings.HeaderUsersModding); // TabControl.AddItem(LayoutStrings.HeaderUsersModding);
TabControlContainer.Add(new ProfileRulesetSelector
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
User = { BindTarget = User }
});
// Haphazardly guaranteed by OverlayHeader constructor (see CreateBackground / CreateContent). // Haphazardly guaranteed by OverlayHeader constructor (see CreateBackground / CreateContent).
Debug.Assert(centreHeaderContainer != null); Debug.Assert(centreHeaderContainer != null);
Debug.Assert(detailHeaderContainer != null); Debug.Assert(detailHeaderContainer != null);

View File

@ -64,8 +64,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps
} }
} }
protected override APIRequest<List<APIBeatmapSet>> CreateRequest(APIUser user, PaginationParameters pagination) => protected override APIRequest<List<APIBeatmapSet>> CreateRequest(UserProfileData user, PaginationParameters pagination) =>
new GetUserBeatmapsRequest(user.Id, type, pagination); new GetUserBeatmapsRequest(user.User.Id, type, pagination);
protected override Drawable? CreateDrawableItem(APIBeatmapSet model) => model.OnlineID > 0 protected override Drawable? CreateDrawableItem(APIBeatmapSet model) => model.OnlineID > 0
? new BeatmapCardNormal(model) ? new BeatmapCardNormal(model)

View File

@ -29,8 +29,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
protected override int GetCount(APIUser user) => user.BeatmapPlayCountsCount; protected override int GetCount(APIUser user) => user.BeatmapPlayCountsCount;
protected override APIRequest<List<APIUserMostPlayedBeatmap>> CreateRequest(APIUser user, PaginationParameters pagination) => protected override APIRequest<List<APIUserMostPlayedBeatmap>> CreateRequest(UserProfileData user, PaginationParameters pagination) =>
new GetUserMostPlayedBeatmapsRequest(user.Id, pagination); new GetUserMostPlayedBeatmapsRequest(user.User.Id, pagination);
protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap mostPlayed) => protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap mostPlayed) =>
new DrawableMostPlayedBeatmap(mostPlayed); new DrawableMostPlayedBeatmap(mostPlayed);

View File

@ -8,7 +8,6 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.API; using osu.Game.Online.API;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Resources.Localisation.Web; using osu.Game.Resources.Localisation.Web;
using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Overlays.Profile.Sections.Kudosu namespace osu.Game.Overlays.Profile.Sections.Kudosu
{ {
@ -19,8 +18,8 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu
{ {
} }
protected override APIRequest<List<APIKudosuHistory>> CreateRequest(APIUser user, PaginationParameters pagination) protected override APIRequest<List<APIKudosuHistory>> CreateRequest(UserProfileData user, PaginationParameters pagination)
=> new GetUserKudosuHistoryRequest(user.Id, pagination); => new GetUserKudosuHistoryRequest(user.User.Id, pagination);
protected override Drawable CreateDrawableItem(APIKudosuHistory item) => new DrawableKudosuHistoryItem(item); protected override Drawable CreateDrawableItem(APIKudosuHistory item) => new DrawableKudosuHistoryItem(item);
} }

View File

@ -109,14 +109,14 @@ namespace osu.Game.Overlays.Profile.Sections
private void showMore() private void showMore()
{ {
if (User.Value?.User == null) if (User.Value == null)
return; return;
loadCancellation = new CancellationTokenSource(); loadCancellation = new CancellationTokenSource();
CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount); CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount);
retrievalRequest = CreateRequest(User.Value.User, CurrentPage.Value); retrievalRequest = CreateRequest(User.Value, CurrentPage.Value);
retrievalRequest.Success += items => UpdateItems(items, loadCancellation); retrievalRequest.Success += items => UpdateItems(items, loadCancellation);
api.Queue(retrievalRequest); api.Queue(retrievalRequest);
@ -154,7 +154,7 @@ namespace osu.Game.Overlays.Profile.Sections
{ {
} }
protected abstract APIRequest<List<TModel>> CreateRequest(APIUser user, PaginationParameters pagination); protected abstract APIRequest<List<TModel>> CreateRequest(UserProfileData user, PaginationParameters pagination);
protected abstract Drawable? CreateDrawableItem(TModel model); protected abstract Drawable? CreateDrawableItem(TModel model);

View File

@ -60,8 +60,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
base.OnItemsReceived(items); base.OnItemsReceived(items);
} }
protected override APIRequest<List<SoloScoreInfo>> CreateRequest(APIUser user, PaginationParameters pagination) => protected override APIRequest<List<SoloScoreInfo>> CreateRequest(UserProfileData user, PaginationParameters pagination) =>
new GetUserScoresRequest(user.Id, type, pagination); new GetUserScoresRequest(user.User.Id, type, pagination, user.Ruleset);
private int drawableItemIndex; private int drawableItemIndex;

View File

@ -10,7 +10,6 @@ using System.Collections.Generic;
using osuTK; using osuTK;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Game.Resources.Localisation.Web; using osu.Game.Resources.Localisation.Web;
using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Overlays.Profile.Sections.Recent namespace osu.Game.Overlays.Profile.Sections.Recent
{ {
@ -27,8 +26,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
ItemsContainer.Spacing = new Vector2(0, 8); ItemsContainer.Spacing = new Vector2(0, 8);
} }
protected override APIRequest<List<APIRecentActivity>> CreateRequest(APIUser user, PaginationParameters pagination) => protected override APIRequest<List<APIRecentActivity>> CreateRequest(UserProfileData user, PaginationParameters pagination) =>
new GetUserRecentActivitiesRequest(user.Id, pagination); new GetUserRecentActivitiesRequest(user.User.Id, pagination);
protected override Drawable CreateDrawableItem(APIRecentActivity model) => new DrawableRecentActivity(model); protected override Drawable CreateDrawableItem(APIRecentActivity model) => new DrawableRecentActivity(model);
} }

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
namespace osu.Game.Overlays.Profile namespace osu.Game.Overlays.Profile
{ {
@ -15,11 +16,15 @@ namespace osu.Game.Overlays.Profile
/// </summary> /// </summary>
public APIUser User { get; } public APIUser User { get; }
// TODO: add ruleset /// <summary>
/// The ruleset that the user profile is being shown with.
/// </summary>
public RulesetInfo Ruleset { get; }
public UserProfileData(APIUser user) public UserProfileData(APIUser user, RulesetInfo ruleset)
{ {
User = user; User = user;
Ruleset = ruleset;
} }
} }
} }

View File

@ -23,10 +23,10 @@ namespace osu.Game.Overlays
/// <typeparam name="T">The type of item to be represented by tabs.</typeparam> /// <typeparam name="T">The type of item to be represented by tabs.</typeparam>
public abstract partial class TabControlOverlayHeader<T> : OverlayHeader, IHasCurrentValue<T> public abstract partial class TabControlOverlayHeader<T> : OverlayHeader, IHasCurrentValue<T>
{ {
protected OsuTabControl<T> TabControl; protected OsuTabControl<T> TabControl { get; }
protected Container TabControlContainer { get; }
private readonly Box controlBackground; private readonly Box controlBackground;
private readonly Container tabControlContainer;
private readonly BindableWithCurrent<T> current = new BindableWithCurrent<T>(); private readonly BindableWithCurrent<T> current = new BindableWithCurrent<T>();
public Bindable<T> Current public Bindable<T> Current
@ -41,7 +41,7 @@ namespace osu.Game.Overlays
set set
{ {
base.ContentSidePadding = value; base.ContentSidePadding = value;
tabControlContainer.Padding = new MarginPadding { Horizontal = value }; TabControlContainer.Padding = new MarginPadding { Horizontal = value };
} }
} }
@ -57,7 +57,7 @@ namespace osu.Game.Overlays
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, },
tabControlContainer = new Container TabControlContainer = new Container
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,

View File

@ -5,16 +5,21 @@ using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Extensions;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile;
using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections;
using osu.Game.Rulesets;
using osu.Game.Users; using osu.Game.Users;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -23,31 +28,47 @@ namespace osu.Game.Overlays
{ {
public partial class UserProfileOverlay : FullscreenOverlay<ProfileHeader> public partial class UserProfileOverlay : FullscreenOverlay<ProfileHeader>
{ {
protected override Container<Drawable> Content => onlineViewContainer;
private readonly OnlineViewContainer onlineViewContainer;
private readonly LoadingLayer loadingLayer;
private ProfileSection? lastSection; private ProfileSection? lastSection;
private ProfileSection[]? sections; private ProfileSection[]? sections;
private GetUserRequest? userReq; private GetUserRequest? userReq;
private ProfileSectionsContainer? sectionsContainer; private ProfileSectionsContainer? sectionsContainer;
private ProfileSectionTabControl? tabs; private ProfileSectionTabControl? tabs;
[Resolved]
private RulesetStore rulesets { get; set; } = null!;
public const float CONTENT_X_MARGIN = 70; public const float CONTENT_X_MARGIN = 70;
public UserProfileOverlay() public UserProfileOverlay()
: base(OverlayColourScheme.Pink) : base(OverlayColourScheme.Pink)
{ {
base.Content.AddRange(new Drawable[]
{
onlineViewContainer = new OnlineViewContainer($"Sign in to view the {Header.Title.Title}")
{
RelativeSizeAxes = Axes.Both
},
loadingLayer = new LoadingLayer(true)
});
} }
protected override ProfileHeader CreateHeader() => new ProfileHeader(); protected override ProfileHeader CreateHeader() => new ProfileHeader();
protected override Color4 BackgroundColour => ColourProvider.Background6; protected override Color4 BackgroundColour => ColourProvider.Background6;
public void ShowUser(IUser user) public void ShowUser(IUser user, IRulesetInfo? ruleset = null)
{ {
if (user.OnlineID == APIUser.SYSTEM_USER_ID) if (user.OnlineID == APIUser.SYSTEM_USER_ID)
return; return;
Show(); Show();
if (user.OnlineID == Header?.User.Value?.User.Id) if (user.OnlineID == Header.User.Value?.User.Id && ruleset?.MatchesOnlineID(Header.User.Value?.Ruleset) == true)
return; return;
if (sectionsContainer != null) if (sectionsContainer != null)
@ -116,16 +137,19 @@ namespace osu.Game.Overlays
sectionsContainer.ScrollToTop(); sectionsContainer.ScrollToTop();
userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID) : new GetUserRequest(user.Username); userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID, ruleset) : new GetUserRequest(user.Username, ruleset);
userReq.Success += userLoadComplete; userReq.Success += u => userLoadComplete(u, ruleset);
API.Queue(userReq); API.Queue(userReq);
loadingLayer.Show();
} }
private void userLoadComplete(APIUser user) private void userLoadComplete(APIUser user, IRulesetInfo? ruleset)
{ {
Debug.Assert(sections != null && sectionsContainer != null && tabs != null); Debug.Assert(sections != null && sectionsContainer != null && tabs != null);
var userProfile = new UserProfileData(user); var actualRuleset = rulesets.GetRuleset(ruleset?.ShortName ?? user.PlayMode).AsNonNull();
var userProfile = new UserProfileData(user, actualRuleset);
Header.User.Value = userProfile; Header.User.Value = userProfile;
if (user.ProfileOrder != null) if (user.ProfileOrder != null)
@ -143,6 +167,8 @@ namespace osu.Game.Overlays
} }
} }
} }
loadingLayer.Hide();
} }
private partial class ProfileSectionTabControl : OverlayTabControl<ProfileSection> private partial class ProfileSectionTabControl : OverlayTabControl<ProfileSection>