1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 18:47:25 +08:00
osu-lazer/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs
Dean Herbert 54982dcdd7 Refactor LoadingLayer to avoid applying effects to external drawables
In theory this seemed like a good idea (and an optimisation in some
cases, due to lower fill rate), but in practice this leads to weird edge
cases.

This aims to do away with the operations on external drawables by
applying a dim to the area behind the `LoadingLayer` when required.
I went over each usage and ensured they look as good or better than
previously.

The specific bad usage here was the restoration of the colour on dispose
(if the `LoadingLayer` was disposed in a still-visible state).

I'm aware that the `BeatmapListingOverlay` will now dim completely during
load. I think this is fine for the time being.
2021-01-05 17:31:45 +09:00

113 lines
3.6 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.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Notifications;
using osu.Game.Users;
using osuTK;
namespace osu.Game.Overlays.BeatmapSet.Buttons
{
public class FavouriteButton : HeaderButton, IHasTooltip
{
public readonly Bindable<BeatmapSetInfo> BeatmapSet = new Bindable<BeatmapSetInfo>();
private readonly BindableBool favourited = new BindableBool();
private PostBeatmapFavouriteRequest request;
private LoadingLayer loading;
private readonly IBindable<User> localUser = new Bindable<User>();
public string TooltipText
{
get
{
if (!Enabled.Value) return string.Empty;
return (favourited.Value ? "Unfavourite" : "Favourite") + " this beatmapset";
}
}
[BackgroundDependencyLoader(true)]
private void load(IAPIProvider api, NotificationOverlay notifications)
{
SpriteIcon icon;
AddRange(new Drawable[]
{
icon = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Regular.Heart,
Size = new Vector2(18),
Shadow = false,
},
loading = new LoadingLayer(true, false),
});
Action = () =>
{
// guaranteed by disabled state above.
Debug.Assert(BeatmapSet.Value.OnlineBeatmapSetID != null);
loading.Show();
request?.Cancel();
request = new PostBeatmapFavouriteRequest(BeatmapSet.Value.OnlineBeatmapSetID.Value, favourited.Value ? BeatmapFavouriteAction.UnFavourite : BeatmapFavouriteAction.Favourite);
request.Success += () =>
{
favourited.Toggle();
loading.Hide();
};
request.Failure += e =>
{
notifications?.Post(new SimpleNotification
{
Text = e.Message,
Icon = FontAwesome.Solid.Times,
});
loading.Hide();
};
api.Queue(request);
};
favourited.ValueChanged += favourited => icon.Icon = favourited.NewValue ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart;
localUser.BindTo(api.LocalUser);
localUser.BindValueChanged(_ => updateEnabled());
// must be run after setting the Action to ensure correct enabled state (setting an Action forces a button to be enabled).
BeatmapSet.BindValueChanged(setInfo =>
{
updateEnabled();
favourited.Value = setInfo.NewValue?.OnlineInfo?.HasFavourited ?? false;
}, true);
}
private void updateEnabled() => Enabled.Value = !(localUser.Value is GuestUser) && BeatmapSet.Value?.OnlineBeatmapSetID > 0;
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
Width = DrawHeight;
}
}
}