1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-14 03:25:11 +08:00

Don't leave scores screen empty if no scores are present yet

Addresses https://github.com/ppy/osu/discussions/23787

I originally wanted to set `allowShowingResults` to false if there are
no results but because this involves an API request to fetch the scores
that would mean all the scores would have to be fetched all at once so
that it knows whether to hide or show the "View results" button on a
beatmap.
Because that would slow things down and be very inefficient, this still
allows the user to view the scores screen but if there aren't any
scores, it shows a text, which I think is at least for now better than
nothing.

As for the testing of this, I wasn't sure how to not generate scores
only for one specific test so I opted into not using `SetUpSteps` and
doing it that way.
This commit is contained in:
wooster0 2023-12-31 22:10:49 +09:00
parent e10733834b
commit 0c85fd496f
3 changed files with 63 additions and 21 deletions

View File

@ -42,15 +42,15 @@ namespace osu.Game.Tests.Visual.Playlists
private int totalCount;
private ScoreInfo userScore;
[SetUpSteps]
public override void SetUpSteps()
// We don't use SetUpSteps for this because one of the tests shouldn't receive any scores.
public void InitialiseUserScoresAndBeatmap(bool noScores = false)
{
base.SetUpSteps();
// Previous test instances of the results screen may still exist at this point so wait for
// those screens to be cleaned up by the base SetUpSteps before re-initialising test state.
// The the screen also holds a leased Beatmap bindable so reassigning it must happen after
// the screen as been exited.
// The screen also holds a leased Beatmap bindable so reassigning it must happen after
// the screen has been exited.
AddStep("initialise user scores and beatmap", () =>
{
lowestScoreId = 1;
@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual.Playlists
userScore.Statistics = new Dictionary<HitResult, int>();
userScore.MaximumStatistics = new Dictionary<HitResult, int>();
bindHandler();
bindHandler(noScores: noScores);
// Beatmap is required to be an actual beatmap so the scores can get their scores correctly
// calculated for standardised scoring, else the tests that rely on ordering will fall over.
@ -74,6 +74,8 @@ namespace osu.Game.Tests.Visual.Playlists
[Test]
public void TestShowWithUserScore()
{
InitialiseUserScoresAndBeatmap();
AddStep("bind user score info handler", () => bindHandler(userScore: userScore));
createResults(() => userScore);
@ -86,6 +88,8 @@ namespace osu.Game.Tests.Visual.Playlists
[Test]
public void TestShowNullUserScore()
{
InitialiseUserScoresAndBeatmap();
createResults();
AddAssert("top score selected", () => this.ChildrenOfType<ScorePanel>().OrderByDescending(p => p.Score.TotalScore).First().State == PanelState.Expanded);
@ -94,6 +98,8 @@ namespace osu.Game.Tests.Visual.Playlists
[Test]
public void TestShowUserScoreWithDelay()
{
InitialiseUserScoresAndBeatmap();
AddStep("bind user score info handler", () => bindHandler(true, userScore));
createResults(() => userScore);
@ -105,6 +111,8 @@ namespace osu.Game.Tests.Visual.Playlists
[Test]
public void TestShowNullUserScoreWithDelay()
{
InitialiseUserScoresAndBeatmap();
AddStep("bind delayed handler", () => bindHandler(true));
createResults();
@ -115,6 +123,8 @@ namespace osu.Game.Tests.Visual.Playlists
[Test]
public void TestFetchWhenScrolledToTheRight()
{
InitialiseUserScoresAndBeatmap();
createResults();
AddStep("bind delayed handler", () => bindHandler(true));
@ -137,6 +147,8 @@ namespace osu.Game.Tests.Visual.Playlists
[Test]
public void TestFetchWhenScrolledToTheLeft()
{
InitialiseUserScoresAndBeatmap();
AddStep("bind user score info handler", () => bindHandler(userScore: userScore));
createResults(() => userScore);
@ -158,7 +170,16 @@ namespace osu.Game.Tests.Visual.Playlists
}
}
private void createResults(Func<ScoreInfo> getScore = null)
[Test]
public void TestShowWithNoScores()
{
InitialiseUserScoresAndBeatmap(noScores: true);
createResults(noScores: true);
AddAssert("no scores visible", () => resultsScreen.ScorePanelList.GetScorePanels().Count() == 0);
}
private void createResults(Func<ScoreInfo> getScore = null, bool noScores = false)
{
AddStep("load results", () =>
{
@ -169,11 +190,13 @@ namespace osu.Game.Tests.Visual.Playlists
});
AddUntilStep("wait for screen to load", () => resultsScreen.IsLoaded);
waitForDisplay();
waitForDisplay(noScores);
}
private void waitForDisplay()
private void waitForDisplay(bool noScores = false)
{
if (noScores) return;
AddUntilStep("wait for scores loaded", () =>
requestComplete
// request handler may need to fire more than once to get scores.
@ -183,7 +206,7 @@ namespace osu.Game.Tests.Visual.Playlists
AddWaitStep("wait for display", 5);
}
private void bindHandler(bool delayed = false, ScoreInfo userScore = null, bool failRequests = false) => ((DummyAPIAccess)API).HandleRequest = request =>
private void bindHandler(bool delayed = false, ScoreInfo userScore = null, bool failRequests = false, bool noScores = false) => ((DummyAPIAccess)API).HandleRequest = request =>
{
// pre-check for requests we should be handling (as they are scheduled below).
switch (request)
@ -219,7 +242,7 @@ namespace osu.Game.Tests.Visual.Playlists
break;
case IndexPlaylistScoresRequest i:
triggerSuccess(i, createIndexResponse(i));
triggerSuccess(i, createIndexResponse(i, noScores));
break;
}
}, delay);
@ -301,10 +324,12 @@ namespace osu.Game.Tests.Visual.Playlists
return multiplayerUserScore;
}
private IndexedMultiplayerScores createIndexResponse(IndexPlaylistScoresRequest req)
private IndexedMultiplayerScores createIndexResponse(IndexPlaylistScoresRequest req, bool noScores = false)
{
var result = new IndexedMultiplayerScores();
if (noScores) return result;
string sort = req.IndexParams?.Properties["sort"].ToObject<string>() ?? "score_desc";
for (int i = 1; i <= scores_per_result; i++)

View File

@ -19,6 +19,7 @@ using osu.Framework.Input.Events;
using osu.Framework.Screens;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Input.Bindings;
using osu.Game.Online.API;
@ -204,17 +205,31 @@ namespace osu.Game.Screens.Ranking
if (lastFetchCompleted)
{
APIRequest nextPageRequest = null;
if (ScorePanelList.IsScrolledToStart)
nextPageRequest = FetchNextPage(-1, fetchScoresCallback);
else if (ScorePanelList.IsScrolledToEnd)
nextPageRequest = FetchNextPage(1, fetchScoresCallback);
if (nextPageRequest != null)
if (ScorePanelList.IsEmpty)
{
lastFetchCompleted = false;
api.Queue(nextPageRequest);
// This can happen if a beatmap part of a playlist hasn't been played yet.
VerticalScrollContent.Add(new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.GetFont(size: 32, weight: FontWeight.Regular),
Text = "no scores yet!",
});
}
else
{
APIRequest nextPageRequest = null;
if (ScorePanelList.IsScrolledToStart)
nextPageRequest = FetchNextPage(-1, fetchScoresCallback);
else if (ScorePanelList.IsScrolledToEnd)
nextPageRequest = FetchNextPage(1, fetchScoresCallback);
if (nextPageRequest != null)
{
lastFetchCompleted = false;
api.Queue(nextPageRequest);
}
}
}
}

View File

@ -49,6 +49,8 @@ namespace osu.Game.Screens.Ranking
public bool AllPanelsVisible => flow.All(p => p.IsPresent);
public bool IsEmpty => flow.Count == 0;
/// <summary>
/// The current scroll position.
/// </summary>