1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-25 16:30:15 +08:00
Files
osu-lazer/osu.Game/Overlays/Profile/Header/Components/UserActionsButton.cs
T
Bartłomiej Dach b47988e899 Add block / unblock option to user profile overlay
This is not doing the thing that the website does wherein the entire
user profile is replaced by the message that the user is blocked if
they're blocked. Someone else can try doing that.

I'm also not adding report button to this because it's going to be
annoying to make happen because currently reporting is only available as
a popover and not as a dialog. Someone else can pick that up as well.
2025-06-13 14:53:18 +02:00

211 lines
7.1 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.Collections.Generic;
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.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Resources.Localisation.Web;
using osu.Game.Users;
using osuTK;
namespace osu.Game.Overlays.Profile.Header.Components
{
public partial class UserActionsButton : OsuHoverContainer, IHasPopover
{
public readonly Bindable<UserProfileData?> User = new Bindable<UserProfileData?>();
private Box background = null!;
protected override IEnumerable<Drawable> EffectTargets => [background];
[Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!;
[Resolved]
private IAPIProvider api { get; set; } = null!;
[BackgroundDependencyLoader]
private void load()
{
IdleColour = colourProvider.Background2;
HoverColour = colourProvider.Background1;
Size = new Vector2(40);
Masking = true;
CornerRadius = 20;
Child = new CircularContainer
{
Masking = true,
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
},
new SpriteIcon
{
Size = new Vector2(12),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.EllipsisV,
},
}
};
Action = this.ShowPopover;
}
protected override void LoadComplete()
{
base.LoadComplete();
User.BindValueChanged(_ => Alpha = User.Value?.User.OnlineID == api.LocalUser.Value.OnlineID ? 0 : 1, true);
}
public Popover GetPopover() => new UserActionPopover(User.Value!.User);
private partial class UserActionPopover : OsuPopover
{
private readonly APIUser user;
public UserActionPopover(APIUser user)
: base(false)
{
this.user = user;
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider, IAPIProvider api, IDialogOverlay? dialogOverlay)
{
Background.Colour = colourProvider.Background6;
bool userBlocked = api.Blocks.Any(b => b.TargetID == user.Id);
AllowableAnchors = [Anchor.BottomCentre, Anchor.TopCentre];
Child = new FillFlowContainer
{
Width = 160,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Horizontal = 5, Vertical = 10 },
Children = new Drawable[]
{
new UserAction(FontAwesome.Solid.Ban, userBlocked ? UsersStrings.BlocksButtonUnblock : UsersStrings.BlocksButtonBlock)
{
Action = () =>
{
dialogOverlay?.Push(userBlocked ? ConfirmBlockActionDialog.Unblock(user) : ConfirmBlockActionDialog.Block(user));
this.HidePopover();
}
}
}
};
}
}
private partial class UserAction : OsuClickableContainer
{
private readonly IconUsage icon;
private readonly LocalisableString caption;
private Box background = null!;
private CircularContainer indicator = null!;
public UserAction(IconUsage icon, LocalisableString caption)
{
this.icon = icon;
this.caption = caption;
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
RelativeSizeAxes = Content.RelativeSizeAxes = Axes.X;
AutoSizeAxes = Content.AutoSizeAxes = Axes.Y;
Masking = true;
CornerRadius = 4;
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background5,
Alpha = 0,
},
indicator = new Circle
{
Width = 4,
Height = 14,
X = 10,
Colour = colourProvider.Highlight1,
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,
Alpha = 0,
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Padding = new MarginPadding { Horizontal = 25, Vertical = 5 },
Direction = FillDirection.Horizontal,
Spacing = new Vector2(3, 0),
Children = new Drawable[]
{
new SpriteIcon
{
Icon = icon,
Size = new Vector2(14),
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
},
new OsuSpriteText
{
Text = caption,
Font = OsuFont.Style.Caption1,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
}
}
}
};
}
protected override bool OnHover(HoverEvent e)
{
updateState();
return true;
}
protected override void OnHoverLost(HoverLostEvent e)
{
updateState();
base.OnHoverLost(e);
}
private void updateState()
{
background.Alpha = indicator.Alpha = IsHovered ? 1 : 0;
}
}
}
}