mirror of
https://github.com/ppy/osu
synced 2024-12-27 17:32:56 +00:00
Update favourite statistic value on favourite button clicks
This commit is contained in:
parent
b5cbdcf981
commit
f4b8dee2d0
@ -9,8 +9,11 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Drawables.Cards;
|
using osu.Game.Beatmaps.Drawables.Cards;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -20,6 +23,8 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
|||||||
{
|
{
|
||||||
public class TestSceneBeatmapCard : OsuTestScene
|
public class TestSceneBeatmapCard : OsuTestScene
|
||||||
{
|
{
|
||||||
|
private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
|
||||||
|
|
||||||
private APIBeatmapSet[] testCases;
|
private APIBeatmapSet[] testCases;
|
||||||
|
|
||||||
#region Test case generation
|
#region Test case generation
|
||||||
@ -164,6 +169,19 @@ namespace osu.Game.Tests.Visual.Beatmaps
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("register request handling", () => dummyAPI.HandleRequest = request =>
|
||||||
|
{
|
||||||
|
if (!(request is PostBeatmapFavouriteRequest))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
request.TriggerSuccess();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private Drawable createContent(OverlayColourScheme colourScheme, Func<APIBeatmapSet, Drawable> creationFunc)
|
private Drawable createContent(OverlayColourScheme colourScheme, Func<APIBeatmapSet, Drawable> creationFunc)
|
||||||
{
|
{
|
||||||
var colourProvider = new OverlayColourProvider(colourScheme);
|
var colourProvider = new OverlayColourProvider(colourScheme);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -35,6 +36,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
|
|||||||
private const float corner_radius = 10;
|
private const float corner_radius = 10;
|
||||||
|
|
||||||
private readonly APIBeatmapSet beatmapSet;
|
private readonly APIBeatmapSet beatmapSet;
|
||||||
|
private readonly Bindable<BeatmapSetFavouriteState> favouriteState;
|
||||||
|
|
||||||
private UpdateableOnlineBeatmapSetCover leftCover;
|
private UpdateableOnlineBeatmapSetCover leftCover;
|
||||||
private FillFlowContainer leftIconArea;
|
private FillFlowContainer leftIconArea;
|
||||||
@ -55,6 +57,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
|
|||||||
: base(HoverSampleSet.Submit)
|
: base(HoverSampleSet.Submit)
|
||||||
{
|
{
|
||||||
this.beatmapSet = beatmapSet;
|
this.beatmapSet = beatmapSet;
|
||||||
|
favouriteState = new Bindable<BeatmapSetFavouriteState>(new BeatmapSetFavouriteState(beatmapSet.HasFavourited, beatmapSet.FavouriteCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -108,7 +111,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
|
|||||||
Spacing = new Vector2(0, 14),
|
Spacing = new Vector2(0, 14),
|
||||||
Children = new BeatmapCardIconButton[]
|
Children = new BeatmapCardIconButton[]
|
||||||
{
|
{
|
||||||
new FavouriteButton(beatmapSet),
|
new FavouriteButton(beatmapSet) { Current = favouriteState },
|
||||||
new DownloadButton(beatmapSet)
|
new DownloadButton(beatmapSet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,7 +315,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
|
|||||||
if (beatmapSet.HypeStatus != null && beatmapSet.NominationStatus != null)
|
if (beatmapSet.HypeStatus != null && beatmapSet.NominationStatus != null)
|
||||||
yield return new NominationsStatistic(beatmapSet.NominationStatus);
|
yield return new NominationsStatistic(beatmapSet.NominationStatus);
|
||||||
|
|
||||||
yield return new FavouritesStatistic(beatmapSet);
|
yield return new FavouritesStatistic(beatmapSet) { Current = favouriteState };
|
||||||
yield return new PlayCountStatistic(beatmapSet);
|
yield return new PlayCountStatistic(beatmapSet);
|
||||||
|
|
||||||
var dateStatistic = BeatmapCardDateStatistic.CreateFor(beatmapSet);
|
var dateStatistic = BeatmapCardDateStatistic.CreateFor(beatmapSet);
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
// 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 osu.Game.Beatmaps.Drawables.Cards.Buttons;
|
||||||
|
using osu.Game.Beatmaps.Drawables.Cards.Statistics;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps.Drawables.Cards
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Stores the current favourite state of a beatmap set.
|
||||||
|
/// Used to coordinate between <see cref="FavouriteButton"/> and <see cref="FavouritesStatistic"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly struct BeatmapSetFavouriteState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the currently logged-in user has favourited this beatmap.
|
||||||
|
/// </summary>
|
||||||
|
public bool Favourited { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of favourites that the beatmap set has received, including the currently logged-in user.
|
||||||
|
/// </summary>
|
||||||
|
public int FavouriteCount { get; }
|
||||||
|
|
||||||
|
public BeatmapSetFavouriteState(bool favourited, int favouriteCount)
|
||||||
|
{
|
||||||
|
Favourited = favourited;
|
||||||
|
FavouriteCount = favouriteCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,9 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
@ -11,17 +13,24 @@ using osu.Game.Resources.Localisation.Web;
|
|||||||
|
|
||||||
namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
|
namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
|
||||||
{
|
{
|
||||||
public class FavouriteButton : BeatmapCardIconButton
|
public class FavouriteButton : BeatmapCardIconButton, IHasCurrentValue<BeatmapSetFavouriteState>
|
||||||
{
|
{
|
||||||
private readonly APIBeatmapSet beatmapSet;
|
private readonly BindableWithCurrent<BeatmapSetFavouriteState> current;
|
||||||
|
|
||||||
|
public Bindable<BeatmapSetFavouriteState> Current
|
||||||
|
{
|
||||||
|
get => current.Current;
|
||||||
|
set => current.Current = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly int onlineBeatmapID;
|
||||||
|
|
||||||
private PostBeatmapFavouriteRequest favouriteRequest;
|
private PostBeatmapFavouriteRequest favouriteRequest;
|
||||||
|
|
||||||
public FavouriteButton(APIBeatmapSet beatmapSet)
|
public FavouriteButton(APIBeatmapSet beatmapSet)
|
||||||
{
|
{
|
||||||
this.beatmapSet = beatmapSet;
|
current = new BindableWithCurrent<BeatmapSetFavouriteState>(new BeatmapSetFavouriteState(beatmapSet.HasFavourited, beatmapSet.FavouriteCount));
|
||||||
|
onlineBeatmapID = beatmapSet.OnlineID;
|
||||||
updateState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -29,17 +38,19 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
|
|||||||
{
|
{
|
||||||
Action = () =>
|
Action = () =>
|
||||||
{
|
{
|
||||||
var actionType = beatmapSet.HasFavourited ? BeatmapFavouriteAction.UnFavourite : BeatmapFavouriteAction.Favourite;
|
var actionType = current.Value.Favourited ? BeatmapFavouriteAction.UnFavourite : BeatmapFavouriteAction.Favourite;
|
||||||
|
|
||||||
favouriteRequest?.Cancel();
|
favouriteRequest?.Cancel();
|
||||||
favouriteRequest = new PostBeatmapFavouriteRequest(beatmapSet.OnlineID, actionType);
|
favouriteRequest = new PostBeatmapFavouriteRequest(onlineBeatmapID, actionType);
|
||||||
|
|
||||||
Enabled.Value = false;
|
Enabled.Value = false;
|
||||||
favouriteRequest.Success += () =>
|
favouriteRequest.Success += () =>
|
||||||
{
|
{
|
||||||
beatmapSet.HasFavourited = actionType == BeatmapFavouriteAction.Favourite;
|
bool favourited = actionType == BeatmapFavouriteAction.Favourite;
|
||||||
|
|
||||||
|
current.Value = new BeatmapSetFavouriteState(favourited, current.Value.FavouriteCount + (favourited ? 1 : -1));
|
||||||
|
|
||||||
Enabled.Value = true;
|
Enabled.Value = true;
|
||||||
updateState();
|
|
||||||
};
|
};
|
||||||
favouriteRequest.Failure += e =>
|
favouriteRequest.Failure += e =>
|
||||||
{
|
{
|
||||||
@ -51,9 +62,15 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
current.BindValueChanged(_ => updateState(), true);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateState()
|
private void updateState()
|
||||||
{
|
{
|
||||||
if (beatmapSet.HasFavourited)
|
if (current.Value.Favourited)
|
||||||
{
|
{
|
||||||
Icon.Icon = FontAwesome.Solid.Heart;
|
Icon.Icon = FontAwesome.Solid.Heart;
|
||||||
TooltipText = BeatmapsetsStrings.ShowDetailsUnfavourite;
|
TooltipText = BeatmapsetsStrings.ShowDetailsUnfavourite;
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.LocalisationExtensions;
|
using osu.Framework.Extensions.LocalisationExtensions;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Game.Resources.Localisation.Web;
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
|
namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
|
||||||
@ -11,13 +13,32 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows the number of favourites that a beatmap set has received.
|
/// Shows the number of favourites that a beatmap set has received.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FavouritesStatistic : BeatmapCardStatistic
|
public class FavouritesStatistic : BeatmapCardStatistic, IHasCurrentValue<BeatmapSetFavouriteState>
|
||||||
{
|
{
|
||||||
|
private readonly BindableWithCurrent<BeatmapSetFavouriteState> current;
|
||||||
|
|
||||||
|
public Bindable<BeatmapSetFavouriteState> Current
|
||||||
|
{
|
||||||
|
get => current.Current;
|
||||||
|
set => current.Current = value;
|
||||||
|
}
|
||||||
|
|
||||||
public FavouritesStatistic(IBeatmapSetOnlineInfo onlineInfo)
|
public FavouritesStatistic(IBeatmapSetOnlineInfo onlineInfo)
|
||||||
{
|
{
|
||||||
Icon = onlineInfo.HasFavourited ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart;
|
current = new BindableWithCurrent<BeatmapSetFavouriteState>(new BeatmapSetFavouriteState(onlineInfo.HasFavourited, onlineInfo.FavouriteCount));
|
||||||
Text = onlineInfo.FavouriteCount.ToMetric(decimals: 1);
|
}
|
||||||
TooltipText = BeatmapsStrings.PanelFavourites(onlineInfo.FavouriteCount.ToLocalisableString(@"N0"));
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
current.BindValueChanged(_ => updateState(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateState()
|
||||||
|
{
|
||||||
|
Icon = current.Value.Favourited ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart;
|
||||||
|
Text = current.Value.FavouriteCount.ToMetric(decimals: 1);
|
||||||
|
TooltipText = BeatmapsStrings.PanelFavourites(current.Value.FavouriteCount.ToLocalisableString(@"N0"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user