mirror of
https://github.com/ppy/osu.git
synced 2025-02-03 18:12:56 +08:00
Merge pull request #30467 from cdwcgt/friend-add
Add the ability to add/remove friends in `UserProfileHeader`
This commit is contained in:
commit
2bd12e14db
@ -155,7 +155,13 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
var api = (DummyAPIAccess)API;
|
||||
|
||||
api.Friends.Clear();
|
||||
api.Friends.Add(friend);
|
||||
api.Friends.Add(new APIRelation
|
||||
{
|
||||
Mutual = true,
|
||||
RelationType = RelationType.Friend,
|
||||
TargetID = friend.OnlineID,
|
||||
TargetUser = friend
|
||||
});
|
||||
});
|
||||
|
||||
int playerNumber = 1;
|
||||
|
@ -30,14 +30,20 @@ namespace osu.Game.Tests.Visual.Online
|
||||
if (supportLevel > 3)
|
||||
supportLevel = 0;
|
||||
|
||||
((DummyAPIAccess)API).Friends.Add(new APIUser
|
||||
((DummyAPIAccess)API).Friends.Add(new APIRelation
|
||||
{
|
||||
Username = @"peppy",
|
||||
Id = 2,
|
||||
Colour = "99EB47",
|
||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
||||
IsSupporter = supportLevel > 0,
|
||||
SupportLevel = supportLevel
|
||||
TargetID = 2,
|
||||
RelationType = RelationType.Friend,
|
||||
Mutual = true,
|
||||
TargetUser = new APIUser
|
||||
{
|
||||
Username = @"peppy",
|
||||
Id = 2,
|
||||
Colour = "99EB47",
|
||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
||||
IsSupporter = supportLevel > 0,
|
||||
SupportLevel = supportLevel
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -3,15 +3,20 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Profile;
|
||||
using osu.Game.Overlays.Profile.Header.Components;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Users;
|
||||
|
||||
@ -22,6 +27,10 @@ namespace osu.Game.Tests.Visual.Online
|
||||
[Cached]
|
||||
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
|
||||
|
||||
private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
|
||||
|
||||
private readonly ManualResetEventSlim requestLock = new ManualResetEventSlim();
|
||||
|
||||
[Resolved]
|
||||
private OsuConfigManager configManager { get; set; } = null!;
|
||||
|
||||
@ -400,5 +409,97 @@ namespace osu.Game.Tests.Visual.Online
|
||||
}
|
||||
}, new OsuRuleset().RulesetInfo));
|
||||
}
|
||||
|
||||
private APIUser nonFriend => new APIUser
|
||||
{
|
||||
Id = 727,
|
||||
Username = "Whatever",
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void TestAddFriend()
|
||||
{
|
||||
AddStep("Setup request", () =>
|
||||
{
|
||||
requestLock.Reset();
|
||||
|
||||
dummyAPI.HandleRequest = request =>
|
||||
{
|
||||
if (request is not AddFriendRequest req)
|
||||
return false;
|
||||
|
||||
if (req.TargetId != nonFriend.OnlineID)
|
||||
return false;
|
||||
|
||||
var apiRelation = new APIRelation
|
||||
{
|
||||
TargetID = nonFriend.OnlineID,
|
||||
Mutual = true,
|
||||
RelationType = RelationType.Friend,
|
||||
TargetUser = nonFriend
|
||||
};
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
requestLock.Wait(3000);
|
||||
dummyAPI.Friends.Add(apiRelation);
|
||||
req.TriggerSuccess(new AddFriendResponse
|
||||
{
|
||||
UserRelation = apiRelation
|
||||
});
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
});
|
||||
AddStep("clear friend list", () => dummyAPI.Friends.Clear());
|
||||
AddStep("Show non-friend user", () => header.User.Value = new UserProfileData(nonFriend, new OsuRuleset().RulesetInfo));
|
||||
AddStep("Click followers button", () => this.ChildrenOfType<FollowersButton>().First().TriggerClick());
|
||||
AddStep("Complete request", () => requestLock.Set());
|
||||
AddUntilStep("Friend added", () => API.Friends.Any(f => f.TargetID == nonFriend.OnlineID));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddFriendNonMutual()
|
||||
{
|
||||
AddStep("Setup request", () =>
|
||||
{
|
||||
requestLock.Reset();
|
||||
|
||||
dummyAPI.HandleRequest = request =>
|
||||
{
|
||||
if (request is not AddFriendRequest req)
|
||||
return false;
|
||||
|
||||
if (req.TargetId != nonFriend.OnlineID)
|
||||
return false;
|
||||
|
||||
var apiRelation = new APIRelation
|
||||
{
|
||||
TargetID = nonFriend.OnlineID,
|
||||
Mutual = false,
|
||||
RelationType = RelationType.Friend,
|
||||
TargetUser = nonFriend
|
||||
};
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
requestLock.Wait(3000);
|
||||
dummyAPI.Friends.Add(apiRelation);
|
||||
req.TriggerSuccess(new AddFriendResponse
|
||||
{
|
||||
UserRelation = apiRelation
|
||||
});
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
});
|
||||
AddStep("clear friend list", () => dummyAPI.Friends.Clear());
|
||||
AddStep("Show non-friend user", () => header.User.Value = new UserProfileData(nonFriend, new OsuRuleset().RulesetInfo));
|
||||
AddStep("Click followers button", () => this.ChildrenOfType<FollowersButton>().First().TriggerClick());
|
||||
AddStep("Complete request", () => requestLock.Set());
|
||||
AddUntilStep("Friend added", () => API.Friends.Any(f => f.TargetID == nonFriend.OnlineID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Online.API
|
||||
private string password;
|
||||
|
||||
public IBindable<APIUser> LocalUser => localUser;
|
||||
public IBindableList<APIUser> Friends => friends;
|
||||
public IBindableList<APIRelation> Friends => friends;
|
||||
public IBindable<UserActivity> Activity => activity;
|
||||
public IBindable<UserStatistics> Statistics => statistics;
|
||||
|
||||
@ -67,7 +67,7 @@ namespace osu.Game.Online.API
|
||||
|
||||
private Bindable<APIUser> localUser { get; } = new Bindable<APIUser>(createGuestUser());
|
||||
|
||||
private BindableList<APIUser> friends { get; } = new BindableList<APIUser>();
|
||||
private BindableList<APIRelation> friends { get; } = new BindableList<APIRelation>();
|
||||
|
||||
private Bindable<UserActivity> activity { get; } = new Bindable<UserActivity>();
|
||||
|
||||
@ -360,19 +360,7 @@ namespace osu.Game.Online.API
|
||||
}
|
||||
}
|
||||
|
||||
var friendsReq = new GetFriendsRequest();
|
||||
friendsReq.Failure += _ => state.Value = APIState.Failing;
|
||||
friendsReq.Success += res =>
|
||||
{
|
||||
friends.Clear();
|
||||
friends.AddRange(res);
|
||||
};
|
||||
|
||||
if (!handleRequest(friendsReq))
|
||||
{
|
||||
state.Value = APIState.Failing;
|
||||
return;
|
||||
}
|
||||
UpdateLocalFriends();
|
||||
|
||||
// The Success callback event is fired on the main thread, so we should wait for that to run before proceeding.
|
||||
// Without this, we will end up circulating this Connecting loop multiple times and queueing up many web requests
|
||||
@ -624,6 +612,22 @@ namespace osu.Game.Online.API
|
||||
localUser.Value.Statistics = newStatistics;
|
||||
}
|
||||
|
||||
public void UpdateLocalFriends()
|
||||
{
|
||||
if (!IsLoggedIn)
|
||||
return;
|
||||
|
||||
var friendsReq = new GetFriendsRequest();
|
||||
friendsReq.Failure += _ => state.Value = APIState.Failing;
|
||||
friendsReq.Success += res =>
|
||||
{
|
||||
friends.Clear();
|
||||
friends.AddRange(res);
|
||||
};
|
||||
|
||||
Queue(friendsReq);
|
||||
}
|
||||
|
||||
private static APIUser createGuestUser() => new GuestUser();
|
||||
|
||||
private void setLocalUser(APIUser user) => Scheduler.Add(() =>
|
||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Online.API
|
||||
Id = DUMMY_USER_ID,
|
||||
});
|
||||
|
||||
public BindableList<APIUser> Friends { get; } = new BindableList<APIUser>();
|
||||
public BindableList<APIRelation> Friends { get; } = new BindableList<APIRelation>();
|
||||
|
||||
public Bindable<UserActivity> Activity { get; } = new Bindable<UserActivity>();
|
||||
|
||||
@ -201,6 +201,10 @@ namespace osu.Game.Online.API
|
||||
LocalUser.Value.Statistics = newStatistics;
|
||||
}
|
||||
|
||||
public void UpdateLocalFriends()
|
||||
{
|
||||
}
|
||||
|
||||
public IHubClientConnector? GetHubConnector(string clientName, string endpoint, bool preferMessagePack) => null;
|
||||
|
||||
public IChatClient GetChatClient() => new TestChatClientConnector(this);
|
||||
@ -214,7 +218,7 @@ namespace osu.Game.Online.API
|
||||
public void SetState(APIState newState) => state.Value = newState;
|
||||
|
||||
IBindable<APIUser> IAPIProvider.LocalUser => LocalUser;
|
||||
IBindableList<APIUser> IAPIProvider.Friends => Friends;
|
||||
IBindableList<APIRelation> IAPIProvider.Friends => Friends;
|
||||
IBindable<UserActivity> IAPIProvider.Activity => Activity;
|
||||
IBindable<UserStatistics?> IAPIProvider.Statistics => Statistics;
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Online.API
|
||||
/// <summary>
|
||||
/// The user's friends.
|
||||
/// </summary>
|
||||
IBindableList<APIUser> Friends { get; }
|
||||
IBindableList<APIRelation> Friends { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The current user's activity.
|
||||
@ -134,6 +134,11 @@ namespace osu.Game.Online.API
|
||||
/// </summary>
|
||||
void UpdateStatistics(UserStatistics newStatistics);
|
||||
|
||||
/// <summary>
|
||||
/// Update the friends status of the current user.
|
||||
/// </summary>
|
||||
void UpdateLocalFriends();
|
||||
|
||||
/// <summary>
|
||||
/// Schedule a callback to run on the update thread.
|
||||
/// </summary>
|
||||
|
30
osu.Game/Online/API/Requests/AddFriendRequest.cs
Normal file
30
osu.Game/Online/API/Requests/AddFriendRequest.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// 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.
|
||||
|
||||
using System.Net.Http;
|
||||
using osu.Framework.IO.Network;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class AddFriendRequest : APIRequest<AddFriendResponse>
|
||||
{
|
||||
public readonly int TargetId;
|
||||
|
||||
public AddFriendRequest(int targetId)
|
||||
{
|
||||
TargetId = targetId;
|
||||
}
|
||||
|
||||
protected override WebRequest CreateWebRequest()
|
||||
{
|
||||
var req = base.CreateWebRequest();
|
||||
|
||||
req.Method = HttpMethod.Post;
|
||||
req.AddParameter("target", TargetId.ToString(), RequestParameterType.Query);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
protected override string Target => @"friends";
|
||||
}
|
||||
}
|
14
osu.Game/Online/API/Requests/AddFriendResponse.cs
Normal file
14
osu.Game/Online/API/Requests/AddFriendResponse.cs
Normal file
@ -0,0 +1,14 @@
|
||||
// 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.
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class AddFriendResponse
|
||||
{
|
||||
[JsonProperty("user_relation")]
|
||||
public APIRelation UserRelation = null!;
|
||||
}
|
||||
}
|
27
osu.Game/Online/API/Requests/DeleteFriendRequest.cs
Normal file
27
osu.Game/Online/API/Requests/DeleteFriendRequest.cs
Normal file
@ -0,0 +1,27 @@
|
||||
// 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.
|
||||
|
||||
using System.Net.Http;
|
||||
using osu.Framework.IO.Network;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class DeleteFriendRequest : APIRequest
|
||||
{
|
||||
public readonly int TargetId;
|
||||
|
||||
public DeleteFriendRequest(int targetId)
|
||||
{
|
||||
TargetId = targetId;
|
||||
}
|
||||
|
||||
protected override WebRequest CreateWebRequest()
|
||||
{
|
||||
var req = base.CreateWebRequest();
|
||||
req.Method = HttpMethod.Delete;
|
||||
return req;
|
||||
}
|
||||
|
||||
protected override string Target => $@"friends/{TargetId}";
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetFriendsRequest : APIRequest<List<APIUser>>
|
||||
public class GetFriendsRequest : APIRequest<List<APIRelation>>
|
||||
{
|
||||
protected override string Target => @"friends";
|
||||
}
|
||||
|
30
osu.Game/Online/API/Requests/Responses/APIRelation.cs
Normal file
30
osu.Game/Online/API/Requests/Responses/APIRelation.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// 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.
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APIRelation
|
||||
{
|
||||
[JsonProperty("target_id")]
|
||||
public int TargetID { get; set; }
|
||||
|
||||
[JsonProperty("relation_type")]
|
||||
public RelationType RelationType { get; set; }
|
||||
|
||||
[JsonProperty("mutual")]
|
||||
public bool Mutual { get; set; }
|
||||
|
||||
[JsonProperty("target")]
|
||||
public APIUser? TargetUser { get; set; }
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum RelationType
|
||||
{
|
||||
Friend,
|
||||
Block,
|
||||
}
|
||||
}
|
@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Dashboard.Friends
|
||||
private LoadingLayer loading;
|
||||
private BasicSearchTextBox searchTextBox;
|
||||
|
||||
private readonly IBindableList<APIUser> apiFriends = new BindableList<APIUser>();
|
||||
private readonly IBindableList<APIRelation> apiFriends = new BindableList<APIRelation>();
|
||||
|
||||
public FriendDisplay()
|
||||
{
|
||||
@ -177,7 +177,7 @@ namespace osu.Game.Overlays.Dashboard.Friends
|
||||
controlBackground.Colour = colourProvider.Background5;
|
||||
|
||||
apiFriends.BindTo(api.Friends);
|
||||
apiFriends.BindCollectionChanged((_, _) => Schedule(() => Users = apiFriends.ToList()), true);
|
||||
apiFriends.BindCollectionChanged((_, _) => Schedule(() => Users = apiFriends.Select(f => f.TargetUser).ToList()), true);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
@ -1,11 +1,21 @@
|
||||
// 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.
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
using SharpCompress;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Header.Components
|
||||
{
|
||||
@ -13,15 +23,201 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
||||
{
|
||||
public readonly Bindable<UserProfileData?> User = new Bindable<UserProfileData?>();
|
||||
|
||||
public override LocalisableString TooltipText => FriendsStrings.ButtonsDisabled;
|
||||
// Because it is impossible to update the number of friends after the operation,
|
||||
// the number of friends obtained is stored and modified locally.
|
||||
private int followerCount;
|
||||
|
||||
public override LocalisableString TooltipText
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (status.Value)
|
||||
{
|
||||
case FriendStatus.Self:
|
||||
return FriendsStrings.ButtonsDisabled;
|
||||
|
||||
case FriendStatus.None:
|
||||
return FriendsStrings.ButtonsAdd;
|
||||
|
||||
case FriendStatus.NotMutual:
|
||||
case FriendStatus.Mutual:
|
||||
return FriendsStrings.ButtonsRemove;
|
||||
}
|
||||
|
||||
return FriendsStrings.TitleCompact;
|
||||
}
|
||||
}
|
||||
|
||||
protected override IconUsage Icon => FontAwesome.Solid.User;
|
||||
|
||||
private readonly IBindableList<APIRelation> apiFriends = new BindableList<APIRelation>();
|
||||
private readonly IBindable<APIUser> localUser = new Bindable<APIUser>();
|
||||
|
||||
private readonly Bindable<FriendStatus> status = new Bindable<FriendStatus>();
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colour { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private OverlayColourProvider colourProvider { get; set; } = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
private void load(IAPIProvider api, INotificationOverlay? notifications)
|
||||
{
|
||||
// todo: when friending/unfriending is implemented, the APIAccess.Friends list should be updated accordingly.
|
||||
User.BindValueChanged(user => SetValue(user.NewValue?.User.FollowerCount ?? 0), true);
|
||||
localUser.BindTo(api.LocalUser);
|
||||
|
||||
status.BindValueChanged(_ =>
|
||||
{
|
||||
updateIcon();
|
||||
updateColor();
|
||||
});
|
||||
|
||||
User.BindValueChanged(u =>
|
||||
{
|
||||
followerCount = u.NewValue?.User.FollowerCount ?? 0;
|
||||
updateStatus();
|
||||
}, true);
|
||||
|
||||
apiFriends.BindTo(api.Friends);
|
||||
apiFriends.BindCollectionChanged((_, _) => Schedule(updateStatus));
|
||||
|
||||
Action += () =>
|
||||
{
|
||||
if (User.Value == null)
|
||||
return;
|
||||
|
||||
if (status.Value == FriendStatus.Self)
|
||||
return;
|
||||
|
||||
ShowLoadingLayer();
|
||||
|
||||
APIRequest req = status.Value == FriendStatus.None ? new AddFriendRequest(User.Value.User.OnlineID) : new DeleteFriendRequest(User.Value.User.OnlineID);
|
||||
|
||||
req.Success += () =>
|
||||
{
|
||||
if (req is AddFriendRequest addedRequest)
|
||||
{
|
||||
SetValue(++followerCount);
|
||||
status.Value = addedRequest.Response?.UserRelation.Mutual == true ? FriendStatus.Mutual : FriendStatus.NotMutual;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetValue(--followerCount);
|
||||
status.Value = FriendStatus.None;
|
||||
}
|
||||
|
||||
api.UpdateLocalFriends();
|
||||
HideLoadingLayer();
|
||||
};
|
||||
|
||||
req.Failure += e =>
|
||||
{
|
||||
notifications?.Post(new SimpleNotification
|
||||
{
|
||||
Text = e.Message,
|
||||
Icon = FontAwesome.Solid.Times,
|
||||
});
|
||||
|
||||
HideLoadingLayer();
|
||||
};
|
||||
|
||||
api.Queue(req);
|
||||
};
|
||||
}
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
if (status.Value > FriendStatus.None)
|
||||
{
|
||||
SetIcon(FontAwesome.Solid.UserTimes);
|
||||
}
|
||||
|
||||
return base.OnHover(e);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
base.OnHoverLost(e);
|
||||
|
||||
updateIcon();
|
||||
}
|
||||
|
||||
private void updateStatus()
|
||||
{
|
||||
SetValue(followerCount);
|
||||
|
||||
if (localUser.Value.OnlineID == User.Value?.User.OnlineID)
|
||||
{
|
||||
status.Value = FriendStatus.Self;
|
||||
return;
|
||||
}
|
||||
|
||||
var friend = apiFriends.FirstOrDefault(u => User.Value?.User.OnlineID == u.TargetID);
|
||||
|
||||
if (friend != null)
|
||||
{
|
||||
status.Value = friend.Mutual ? FriendStatus.Mutual : FriendStatus.NotMutual;
|
||||
}
|
||||
else
|
||||
{
|
||||
status.Value = FriendStatus.None;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateIcon()
|
||||
{
|
||||
switch (status.Value)
|
||||
{
|
||||
case FriendStatus.Self:
|
||||
SetIcon(FontAwesome.Solid.User);
|
||||
break;
|
||||
|
||||
case FriendStatus.None:
|
||||
SetIcon(FontAwesome.Solid.UserPlus);
|
||||
break;
|
||||
|
||||
case FriendStatus.NotMutual:
|
||||
SetIcon(FontAwesome.Solid.User);
|
||||
break;
|
||||
|
||||
case FriendStatus.Mutual:
|
||||
SetIcon(FontAwesome.Solid.UserFriends);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateColor()
|
||||
{
|
||||
// https://github.com/ppy/osu-web/blob/0a5367a4a68a6cdf450eb483251b3cf03b3ac7d2/resources/css/bem/user-action-button.less
|
||||
|
||||
switch (status.Value)
|
||||
{
|
||||
case FriendStatus.Self:
|
||||
case FriendStatus.None:
|
||||
IdleColour = colourProvider.Background6;
|
||||
HoverColour = colourProvider.Background5;
|
||||
break;
|
||||
|
||||
case FriendStatus.NotMutual:
|
||||
IdleColour = colour.Green.Opacity(0.7f);
|
||||
HoverColour = IdleColour.Lighten(0.1f);
|
||||
break;
|
||||
|
||||
case FriendStatus.Mutual:
|
||||
IdleColour = colour.Pink.Opacity(0.7f);
|
||||
HoverColour = IdleColour.Lighten(0.1f);
|
||||
break;
|
||||
}
|
||||
|
||||
EffectTargets.ForEach(d => d.FadeColour(IsHovered ? HoverColour : IdleColour, FADE_DURATION, Easing.OutQuint));
|
||||
}
|
||||
|
||||
private enum FriendStatus
|
||||
{
|
||||
Self,
|
||||
None,
|
||||
NotMutual,
|
||||
Mutual,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Header.Components
|
||||
{
|
||||
@ -14,6 +15,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
||||
{
|
||||
private readonly Box background;
|
||||
private readonly Container content;
|
||||
private readonly LoadingLayer loading;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
@ -40,11 +42,22 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
||||
AutoSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Horizontal = 10 },
|
||||
}
|
||||
},
|
||||
loading = new LoadingLayer(true, false)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void ShowLoadingLayer()
|
||||
{
|
||||
loading.Show();
|
||||
}
|
||||
|
||||
protected void HideLoadingLayer()
|
||||
{
|
||||
loading.Hide();
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
|
@ -14,6 +14,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
||||
public abstract partial class ProfileHeaderStatisticsButton : ProfileHeaderButton
|
||||
{
|
||||
private readonly OsuSpriteText drawableText;
|
||||
private readonly Container iconContainer;
|
||||
|
||||
protected ProfileHeaderStatisticsButton()
|
||||
{
|
||||
@ -26,13 +27,11 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SpriteIcon
|
||||
iconContainer = new Container
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Icon = Icon,
|
||||
FillMode = FillMode.Fit,
|
||||
Size = new Vector2(50, 14)
|
||||
AutoSizeAxes = Axes.Both,
|
||||
},
|
||||
drawableText = new OsuSpriteText
|
||||
{
|
||||
@ -43,10 +42,24 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SetIcon(Icon);
|
||||
}
|
||||
|
||||
protected abstract IconUsage Icon { get; }
|
||||
|
||||
protected void SetIcon(IconUsage icon)
|
||||
{
|
||||
iconContainer.Child = new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Icon = icon,
|
||||
FillMode = FillMode.Fit,
|
||||
Size = new Vector2(50, 14)
|
||||
};
|
||||
}
|
||||
|
||||
protected void SetValue(int value) => drawableText.Text = value.ToLocalisableString("#,##0");
|
||||
}
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ namespace osu.Game.Screens.Play.HUD
|
||||
|
||||
HasQuit.BindValueChanged(_ => updateState());
|
||||
|
||||
isFriend = User != null && api.Friends.Any(u => User.OnlineID == u.Id);
|
||||
isFriend = User != null && api.Friends.Any(u => User.OnlineID == u.TargetID);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
Loading…
Reference in New Issue
Block a user