1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-16 23:43:27 +08:00
Files
osu-lazer/osu.Game/Overlays/Profile/Header/Components/UserActionsButton.cs
T
Krzysztof Gutkowski 2006485d60 Allow reporting users from their profile page (#36335)
This PR refactors the report popover to have an optional confirmation
message after completing the request. This was initially meant for
#32584, but then I realized I can first test it out on the user
profiles, so I've implemented it here as well. Can be reviewed commit by
commit.



https://github.com/user-attachments/assets/cd59c560-c824-4a5e-bab6-5ecbf5125af1

---------

Co-authored-by: Dean Herbert <pe@ppy.sh>
2026-05-05 19:49:24 +09:00

105 lines
3.9 KiB
C#

// 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;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Resources.Localisation.Web;
using osu.Game.Users;
namespace osu.Game.Overlays.Profile.Header.Components
{
public partial class UserActionsButton : ProfileActionsButton
{
public readonly Bindable<UserProfileData?> User = new Bindable<UserProfileData?>();
private UserReportPopoverTarget reportPopoverTarget = null!;
[Resolved]
private IAPIProvider api { get; set; } = null!;
[BackgroundDependencyLoader]
private void load()
{
// This is a bit of a dirty hack. Because `ReportUserPopover` is spawned from `UserActionsPopover`,
// and that they both share the same `PopoverContainer`, the former will get destroyed when the latter
// is opened, causing it to get destroyed as well.
//
// This is worked around by having an additional dummy popover target on the actions button,
// which is then passed to `UserActionsPopover` and the user report action. This way the popover
// can remain attached to it once the actions popover is destroyed.
Add(reportPopoverTarget = new UserReportPopoverTarget
{
RelativeSizeAxes = Axes.Both
});
}
protected override void LoadComplete()
{
base.LoadComplete();
User.BindValueChanged(_ =>
{
Alpha = User.Value?.User.OnlineID == api.LocalUser.Value.OnlineID ? 0 : 1;
reportPopoverTarget.User = User.Value?.User;
}, true);
}
public override Popover GetPopover() => new UserActionPopover(User.Value!.User, reportPopoverTarget);
private partial class UserActionPopover : ProfileActionPopover
{
private readonly APIUser user;
private readonly IHasPopover reportPopoverTarget;
public UserActionPopover(APIUser user, IHasPopover reportPopoverTarget)
{
this.user = user;
this.reportPopoverTarget = reportPopoverTarget;
}
[BackgroundDependencyLoader]
private void load(IAPIProvider api, IDialogOverlay? dialogOverlay)
{
bool userBlocked = api.LocalUserState.Blocks.Any(b => b.TargetID == user.Id);
Actions = new[]
{
new ProfilePopoverAction(FontAwesome.Solid.Ban, userBlocked ? UsersStrings.BlocksButtonUnblock : UsersStrings.BlocksButtonBlock)
{
Action = () =>
{
dialogOverlay?.Push(userBlocked ? ConfirmBlockActionDialog.Unblock(user) : ConfirmBlockActionDialog.Block(user));
this.HidePopover();
}
},
new ProfilePopoverAction(FontAwesome.Solid.ExclamationTriangle, ReportStrings.UserButton)
{
Action = () =>
{
this.HidePopover();
reportPopoverTarget.ShowPopover();
}
},
};
}
}
private partial class UserReportPopoverTarget : Container, IHasPopover
{
public APIUser? User;
public Popover? GetPopover() => User != null ? new ReportUserPopover(User) : null;
}
}
}