mirror of
https://github.com/ppy/osu.git
synced 2026-05-13 20:33:35 +08:00
199bcd7fdb
This is in response to feedback in https://osu.ppy.sh/community/forums/topics/2056547?n=1. Upon examining the button further, there was indeed some rather weird... almost hysteresis in how the button behaved with respect to the area on the screen that activated it. Because of the following scourge of a method that continues to haunt us to this day: https://github.com/ppy/osu/blob/31487545d0d17c4337d4b4cc5d4afb3ba1dae838/osu.Game/Graphics/Containers/OsuClickableContainer.cs#L24-L25 the button would effectively only be activated by 80% of its drawable area when it was not hovered, because of the scale applied to the `content` container which `Container.Content` redirected to. This is resolved here by various rearrangements of paddings and sizes such that the clickable area of any of the buttons of the card is always the full top or bottom half of the button area. Also included are some cosmetic touch-ups which happened to be convenient like folding the loading spinner into the base `BeatmapCardIconButton`, adding loading support for the favourite button, using BDL more, and resolving some "virtual member call in constructor" inspections.
90 lines
2.9 KiB
C#
90 lines
2.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.
|
|
|
|
#nullable disable
|
|
|
|
using osu.Framework.Allocation;
|
|
using osu.Framework.Bindables;
|
|
using osu.Framework.Graphics.Sprites;
|
|
using osu.Framework.Graphics.UserInterface;
|
|
using osu.Game.Online.API.Requests.Responses;
|
|
using osu.Framework.Logging;
|
|
using osu.Game.Online.API;
|
|
using osu.Game.Online.API.Requests;
|
|
using osu.Game.Resources.Localisation.Web;
|
|
|
|
namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
|
|
{
|
|
public partial class FavouriteButton : BeatmapCardIconButton, IHasCurrentValue<BeatmapSetFavouriteState>
|
|
{
|
|
private readonly BindableWithCurrent<BeatmapSetFavouriteState> current;
|
|
|
|
public Bindable<BeatmapSetFavouriteState> Current
|
|
{
|
|
get => current.Current;
|
|
set => current.Current = value;
|
|
}
|
|
|
|
private readonly APIBeatmapSet beatmapSet;
|
|
|
|
private PostBeatmapFavouriteRequest favouriteRequest;
|
|
|
|
[Resolved]
|
|
private IAPIProvider api { get; set; }
|
|
|
|
public FavouriteButton(APIBeatmapSet beatmapSet)
|
|
{
|
|
current = new BindableWithCurrent<BeatmapSetFavouriteState>(new BeatmapSetFavouriteState(beatmapSet.HasFavourited, beatmapSet.FavouriteCount));
|
|
this.beatmapSet = beatmapSet;
|
|
}
|
|
|
|
protected override void LoadComplete()
|
|
{
|
|
base.LoadComplete();
|
|
|
|
Action = toggleFavouriteStatus;
|
|
current.BindValueChanged(_ => updateState(), true);
|
|
}
|
|
|
|
private void toggleFavouriteStatus()
|
|
{
|
|
var actionType = current.Value.Favourited ? BeatmapFavouriteAction.UnFavourite : BeatmapFavouriteAction.Favourite;
|
|
|
|
favouriteRequest?.Cancel();
|
|
favouriteRequest = new PostBeatmapFavouriteRequest(beatmapSet.OnlineID, actionType);
|
|
|
|
SetLoading(true);
|
|
|
|
favouriteRequest.Success += () =>
|
|
{
|
|
bool favourited = actionType == BeatmapFavouriteAction.Favourite;
|
|
|
|
current.Value = new BeatmapSetFavouriteState(favourited, current.Value.FavouriteCount + (favourited ? 1 : -1));
|
|
|
|
SetLoading(false);
|
|
};
|
|
favouriteRequest.Failure += e =>
|
|
{
|
|
Logger.Error(e, $"Failed to {actionType.ToString().ToLowerInvariant()} beatmap: {e.Message}");
|
|
SetLoading(false);
|
|
};
|
|
|
|
api.Queue(favouriteRequest);
|
|
}
|
|
|
|
private void updateState()
|
|
{
|
|
if (current.Value.Favourited)
|
|
{
|
|
Icon.Icon = FontAwesome.Solid.Heart;
|
|
TooltipText = BeatmapsetsStrings.ShowDetailsUnfavourite;
|
|
}
|
|
else
|
|
{
|
|
Icon.Icon = FontAwesome.Regular.Heart;
|
|
TooltipText = BeatmapsetsStrings.ShowDetailsFavourite;
|
|
}
|
|
}
|
|
}
|
|
}
|