mirror of
https://github.com/ppy/osu.git
synced 2024-12-17 20:52:54 +08:00
Add favourite button to results screen
This commit is contained in:
parent
d32fef8aee
commit
0bc14ba646
145
osu.Game/Screens/Ranking/FavouriteButton.cs
Normal file
145
osu.Game/Screens/Ranking/FavouriteButton.cs
Normal file
@ -0,0 +1,145 @@
|
||||
// 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;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Beatmaps.Drawables.Cards;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Resources.Localisation.Web;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
public partial class FavouriteButton : OsuAnimatedButton
|
||||
{
|
||||
private readonly Box background;
|
||||
private readonly SpriteIcon icon;
|
||||
private readonly BindableWithCurrent<BeatmapSetFavouriteState> current;
|
||||
|
||||
public Bindable<BeatmapSetFavouriteState> Current
|
||||
{
|
||||
get => current.Current;
|
||||
set => current.Current = value;
|
||||
}
|
||||
|
||||
private readonly APIBeatmapSet beatmapSet;
|
||||
|
||||
private PostBeatmapFavouriteRequest favouriteRequest;
|
||||
private LoadingLayer loading;
|
||||
|
||||
private readonly IBindable<APIUser> localUser = new Bindable<APIUser>();
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
public FavouriteButton(APIBeatmapSet beatmapSet)
|
||||
{
|
||||
this.beatmapSet = beatmapSet;
|
||||
current = new BindableWithCurrent<BeatmapSetFavouriteState>(new BeatmapSetFavouriteState(this.beatmapSet.HasFavourited, this.beatmapSet.FavouriteCount));
|
||||
|
||||
Size = new Vector2(50, 30);
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
background = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Depth = float.MaxValue
|
||||
},
|
||||
icon = new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(13),
|
||||
Icon = FontAwesome.Regular.Heart,
|
||||
},
|
||||
loading = new LoadingLayer(true, false),
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, IAPIProvider api)
|
||||
{
|
||||
this.api = api;
|
||||
|
||||
updateState();
|
||||
|
||||
localUser.BindTo(api.LocalUser);
|
||||
localUser.BindValueChanged(_ => updateEnabled());
|
||||
|
||||
Action = () => toggleFavouriteStatus();
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Action = toggleFavouriteStatus;
|
||||
current.BindValueChanged(_ => updateState(), true);
|
||||
}
|
||||
|
||||
private void toggleFavouriteStatus()
|
||||
{
|
||||
|
||||
Enabled.Value = false;
|
||||
loading.Show();
|
||||
|
||||
var actionType = current.Value.Favourited ? BeatmapFavouriteAction.UnFavourite : BeatmapFavouriteAction.Favourite;
|
||||
|
||||
favouriteRequest?.Cancel();
|
||||
favouriteRequest = new PostBeatmapFavouriteRequest(beatmapSet.OnlineID, actionType);
|
||||
|
||||
favouriteRequest.Success += () =>
|
||||
{
|
||||
bool favourited = actionType == BeatmapFavouriteAction.Favourite;
|
||||
|
||||
current.Value = new BeatmapSetFavouriteState(favourited, current.Value.FavouriteCount + (favourited ? 1 : -1));
|
||||
|
||||
Enabled.Value = true;
|
||||
loading.Hide();
|
||||
};
|
||||
favouriteRequest.Failure += e =>
|
||||
{
|
||||
Logger.Error(e, $"Failed to {actionType.ToString().ToLowerInvariant()} beatmap: {e.Message}");
|
||||
Enabled.Value = true;
|
||||
loading.Hide();
|
||||
};
|
||||
|
||||
api.Queue(favouriteRequest);
|
||||
}
|
||||
|
||||
private void updateEnabled() => Enabled.Value = !(localUser.Value is GuestUser) && beatmapSet.OnlineID > 0;
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
if (current?.Value == null)
|
||||
return;
|
||||
|
||||
if (current.Value.Favourited)
|
||||
{
|
||||
background.Colour = colours.Green;
|
||||
icon.Icon = FontAwesome.Solid.Heart;
|
||||
TooltipText = BeatmapsetsStrings.ShowDetailsUnfavourite;
|
||||
}
|
||||
else
|
||||
{
|
||||
background.Colour = colours.Gray4;
|
||||
icon.Icon = FontAwesome.Regular.Heart;
|
||||
TooltipText = BeatmapsetsStrings.ShowDetailsFavourite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
@ -22,6 +23,7 @@ using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.Placeholders;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Scoring;
|
||||
@ -76,7 +78,7 @@ namespace osu.Game.Screens.Ranking
|
||||
|
||||
/// <summary>
|
||||
/// Whether the user's personal statistics should be shown on the extended statistics panel
|
||||
/// after clicking the score panel associated with the <see cref="ResultsScreen.Score"/> being presented.
|
||||
/// after clicking the score panel associated with the <see cref="Score"/> being presented.
|
||||
/// Requires <see cref="Score"/> to be present.
|
||||
/// </summary>
|
||||
public bool ShowUserStatistics { get; init; }
|
||||
@ -202,6 +204,27 @@ namespace osu.Game.Screens.Ranking
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Do not render if user is not logged in or the mapset does not have a valid online ID.
|
||||
if (api.IsLoggedIn && Score?.BeatmapInfo?.BeatmapSet != null && Score.BeatmapInfo.BeatmapSet.OnlineID > 0)
|
||||
{
|
||||
GetBeatmapSetRequest beatmapSetRequest;
|
||||
beatmapSetRequest = new GetBeatmapSetRequest(Score.BeatmapInfo.BeatmapSet.OnlineID);
|
||||
|
||||
beatmapSetRequest.Success += (beatmapSet) =>
|
||||
{
|
||||
buttons.Add(new FavouriteButton(beatmapSet)
|
||||
{
|
||||
Width = 75
|
||||
});
|
||||
};
|
||||
beatmapSetRequest.Failure += e =>
|
||||
{
|
||||
Logger.Error(e, $"Failed to fetch beatmap info: {e.Message}");
|
||||
};
|
||||
|
||||
api.Queue(beatmapSetRequest);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
Loading…
Reference in New Issue
Block a user