1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-06 06:57:39 +08:00

Track loading via state as well

This commit is contained in:
Dean Herbert 2022-01-31 01:12:03 +09:00
parent 1cec76df74
commit f8939af5e6
4 changed files with 48 additions and 43 deletions

View File

@ -116,11 +116,11 @@ namespace osu.Game.Tests.Visual.SongSelect
{
AddStep("ensure no scores displayed", () => leaderboard.SetScores(null));
AddStep(@"Network failure", () => leaderboard.SetErrorState(LeaderboardErrorState.NetworkFailure));
AddStep(@"No supporter", () => leaderboard.SetErrorState(LeaderboardErrorState.NotSupporter));
AddStep(@"Not logged in", () => leaderboard.SetErrorState(LeaderboardErrorState.NotLoggedIn));
AddStep(@"Unavailable", () => leaderboard.SetErrorState(LeaderboardErrorState.Unavailable));
AddStep(@"None selected", () => leaderboard.SetErrorState(LeaderboardErrorState.NoneSelected));
AddStep(@"Network failure", () => leaderboard.SetErrorState(LeaderboardState.NetworkFailure));
AddStep(@"No supporter", () => leaderboard.SetErrorState(LeaderboardState.NotSupporter));
AddStep(@"Not logged in", () => leaderboard.SetErrorState(LeaderboardState.NotLoggedIn));
AddStep(@"Unavailable", () => leaderboard.SetErrorState(LeaderboardState.Unavailable));
AddStep(@"None selected", () => leaderboard.SetErrorState(LeaderboardState.NoneSelected));
}
private void showPersonalBestWithNullPosition()
@ -404,7 +404,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private class FailableLeaderboard : BeatmapLeaderboard
{
public new void SetErrorState(LeaderboardErrorState errorState) => base.SetErrorState(errorState);
public new void SetErrorState(LeaderboardState state) => base.SetErrorState(state);
public new void SetScores(IEnumerable<ScoreInfo> scores, ScoreInfo userScore = default) => base.SetScores(scores, userScore);
}
}

View File

@ -58,7 +58,7 @@ namespace osu.Game.Online.Leaderboards
private APIRequest fetchScoresRequest;
private LeaderboardErrorState errorState;
private LeaderboardState state;
[Resolved(CanBeNull = true)]
private IAPIProvider api { get; set; }
@ -160,19 +160,20 @@ namespace osu.Game.Online.Leaderboards
/// <summary>
/// Call when a retrieval or display failure happened to show a relevant message to the user.
/// </summary>
/// <param name="errorState">The state to display.</param>
protected void SetErrorState(LeaderboardErrorState errorState)
/// <param name="state">The state to display.</param>
protected void SetErrorState(LeaderboardState state)
{
switch (errorState)
switch (state)
{
case LeaderboardErrorState.NoScores:
case LeaderboardErrorState.NoError:
throw new InvalidOperationException($"State {errorState} cannot be set by a leaderboard implementation.");
case LeaderboardState.NoScores:
case LeaderboardState.Retrieving:
case LeaderboardState.Success:
throw new InvalidOperationException($"State {state} cannot be set by a leaderboard implementation.");
}
Debug.Assert(scores?.Any() != true);
setErrorState(errorState);
setState(state);
}
/// <summary>
@ -212,8 +213,7 @@ namespace osu.Game.Online.Leaderboards
cancelPendingWork();
SetScores(null);
setErrorState(LeaderboardErrorState.NoError);
loading.Show();
setState(LeaderboardState.Retrieving);
currentFetchCancellationSource = new CancellationTokenSource();
@ -227,7 +227,7 @@ namespace osu.Game.Online.Leaderboards
if (e is OperationCanceledException || currentFetchCancellationSource.IsCancellationRequested)
return;
SetErrorState(LeaderboardErrorState.NetworkFailure);
SetErrorState(LeaderboardState.NetworkFailure);
});
api?.Queue(fetchScoresRequest);
@ -251,15 +251,10 @@ namespace osu.Game.Online.Leaderboards
if (scores?.Any() != true)
{
setErrorState(LeaderboardErrorState.NoScores);
loading.Hide();
setState(LeaderboardState.NoScores);
return;
}
// ensure placeholder is hidden when displaying scores
setErrorState(LeaderboardErrorState.NoError);
loading.Show();
LoadComponentAsync(new FillFlowContainer<LeaderboardScore>
{
RelativeSizeAxes = Axes.X,
@ -269,6 +264,8 @@ namespace osu.Game.Online.Leaderboards
ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1))
}, newFlow =>
{
setState(LeaderboardState.Success);
scrollContainer.Add(scoreFlowContainer = newFlow);
double delay = 0;
@ -282,7 +279,6 @@ namespace osu.Game.Online.Leaderboards
}
scrollContainer.ScrollToStart(false);
loading.Hide();
}, (currentScoresAsyncLoadCancellationSource = new CancellationTokenSource()).Token);
}
@ -290,16 +286,21 @@ namespace osu.Game.Online.Leaderboards
private Placeholder placeholder;
private void setErrorState(LeaderboardErrorState errorState)
private void setState(LeaderboardState state)
{
if (errorState == this.errorState)
if (state == this.state)
return;
this.errorState = errorState;
if (state == LeaderboardState.Retrieving)
loading.Show();
else
loading.Hide();
this.state = state;
placeholder?.FadeOut(150, Easing.OutQuint).Expire();
placeholder = getPlaceholderFor(errorState);
placeholder = getPlaceholderFor(state);
if (placeholder == null)
return;
@ -310,32 +311,35 @@ namespace osu.Game.Online.Leaderboards
placeholder.FadeInFromZero(fade_duration, Easing.OutQuint);
}
private Placeholder getPlaceholderFor(LeaderboardErrorState errorState)
private Placeholder getPlaceholderFor(LeaderboardState state)
{
switch (errorState)
switch (state)
{
case LeaderboardErrorState.NetworkFailure:
case LeaderboardState.NetworkFailure:
return new ClickablePlaceholder(@"Couldn't fetch scores!", FontAwesome.Solid.Sync)
{
Action = RefetchScores
};
case LeaderboardErrorState.NoneSelected:
case LeaderboardState.NoneSelected:
return new MessagePlaceholder(@"Please select a beatmap!");
case LeaderboardErrorState.Unavailable:
case LeaderboardState.Unavailable:
return new MessagePlaceholder(@"Leaderboards are not available for this beatmap!");
case LeaderboardErrorState.NoScores:
case LeaderboardState.NoScores:
return new MessagePlaceholder(@"No records yet!");
case LeaderboardErrorState.NotLoggedIn:
case LeaderboardState.NotLoggedIn:
return new LoginPlaceholder(@"Please sign in to view online leaderboards!");
case LeaderboardErrorState.NotSupporter:
case LeaderboardState.NotSupporter:
return new MessagePlaceholder(@"Please invest in an osu!supporter tag to view this leaderboard!");
case LeaderboardErrorState.NoError:
case LeaderboardState.Retrieving:
return null;
case LeaderboardState.Success:
return null;
default:

View File

@ -3,9 +3,10 @@
namespace osu.Game.Online.Leaderboards
{
public enum LeaderboardErrorState
public enum LeaderboardState
{
NoError,
Success,
Retrieving,
NetworkFailure,
Unavailable,
NoneSelected,

View File

@ -101,7 +101,7 @@ namespace osu.Game.Screens.Select.Leaderboards
if (fetchBeatmapInfo == null)
{
SetErrorState(LeaderboardErrorState.NoneSelected);
SetErrorState(LeaderboardState.NoneSelected);
return null;
}
@ -113,19 +113,19 @@ namespace osu.Game.Screens.Select.Leaderboards
if (api?.IsLoggedIn != true)
{
SetErrorState(LeaderboardErrorState.NotLoggedIn);
SetErrorState(LeaderboardState.NotLoggedIn);
return null;
}
if (fetchBeatmapInfo.OnlineID <= 0 || fetchBeatmapInfo.Status <= BeatmapOnlineStatus.Pending)
{
SetErrorState(LeaderboardErrorState.Unavailable);
SetErrorState(LeaderboardState.Unavailable);
return null;
}
if (!api.LocalUser.Value.IsSupporter && (Scope != BeatmapLeaderboardScope.Global || filterMods))
{
SetErrorState(LeaderboardErrorState.NotSupporter);
SetErrorState(LeaderboardState.NotSupporter);
return null;
}