mirror of
https://github.com/ppy/osu
synced 2025-01-05 21:59:46 +00:00
Implement paging
This commit is contained in:
parent
b7790de66f
commit
46ea775cfb
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -72,40 +73,93 @@ namespace osu.Game.Screens.Multi.Ranking
|
|||||||
lowerScoresCursor = userScore.ScoresAround.Lower.Cursor;
|
lowerScoresCursor = userScore.ScoresAround.Lower.Cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
success(allScores);
|
performSuccessCallback(scoresCallback, allScores);
|
||||||
};
|
};
|
||||||
|
|
||||||
userScoreReq.Failure += _ =>
|
userScoreReq.Failure += _ =>
|
||||||
{
|
{
|
||||||
// Fallback to a normal index.
|
// Fallback to a normal index.
|
||||||
var indexReq = new IndexPlaylistScoresRequest(roomId, playlistItem.ID);
|
var indexReq = new IndexPlaylistScoresRequest(roomId, playlistItem.ID);
|
||||||
indexReq.Success += r => success(r.Scores);
|
|
||||||
|
indexReq.Success += r =>
|
||||||
|
{
|
||||||
|
performSuccessCallback(scoresCallback, r.Scores);
|
||||||
|
lowerScoresCursor = r.Cursor;
|
||||||
|
};
|
||||||
|
|
||||||
indexReq.Failure += __ => loadingLayer.Hide();
|
indexReq.Failure += __ => loadingLayer.Hide();
|
||||||
|
|
||||||
api.Queue(indexReq);
|
api.Queue(indexReq);
|
||||||
};
|
};
|
||||||
|
|
||||||
return userScoreReq;
|
return userScoreReq;
|
||||||
|
}
|
||||||
|
|
||||||
void success(List<MultiplayerScore> scores)
|
protected override APIRequest FetchNextPage(int direction, Action<IEnumerable<ScoreInfo>> scoresCallback)
|
||||||
|
{
|
||||||
|
Debug.Assert(direction == 1 || direction == -1);
|
||||||
|
|
||||||
|
Cursor cursor;
|
||||||
|
MultiplayerScoresSort sort;
|
||||||
|
|
||||||
|
switch (direction)
|
||||||
{
|
{
|
||||||
var scoreInfos = new List<ScoreInfo>(scores.Select(s => s.CreateScoreInfo(playlistItem)));
|
case -1:
|
||||||
|
cursor = higherScoresCursor;
|
||||||
|
sort = MultiplayerScoresSort.Ascending;
|
||||||
|
break;
|
||||||
|
|
||||||
// Select a score if we don't already have one selected.
|
default:
|
||||||
// Note: This is done before the callback so that the panel list centres on the selected score before panels are added (eliminating initial scroll).
|
cursor = lowerScoresCursor;
|
||||||
if (SelectedScore.Value == null)
|
sort = MultiplayerScoresSort.Descending;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var indexReq = new IndexPlaylistScoresRequest(roomId, playlistItem.ID, cursor, sort);
|
||||||
|
|
||||||
|
indexReq.Success += r =>
|
||||||
|
{
|
||||||
|
switch (direction)
|
||||||
{
|
{
|
||||||
Schedule(() =>
|
case -1:
|
||||||
{
|
higherScoresCursor = r.Cursor;
|
||||||
// Prefer selecting the local user's score, or otherwise default to the first visible score.
|
break;
|
||||||
SelectedScore.Value = scoreInfos.FirstOrDefault(s => s.User.Id == api.LocalUser.Value.Id) ?? scoreInfos.FirstOrDefault();
|
|
||||||
});
|
default:
|
||||||
|
lowerScoresCursor = r.Cursor;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke callback to add the scores. Exclude the user's current score which was added previously.
|
performSuccessCallback(scoresCallback, r.Scores);
|
||||||
scoresCallback?.Invoke(scoreInfos.Where(s => s.ID != Score?.OnlineScoreID));
|
};
|
||||||
|
|
||||||
loadingLayer.Hide();
|
indexReq.Failure += _ => loadingLayer.Hide();
|
||||||
|
|
||||||
|
return indexReq;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performSuccessCallback(Action<IEnumerable<ScoreInfo>> callback, List<MultiplayerScore> scores)
|
||||||
|
{
|
||||||
|
var scoreInfos = new List<ScoreInfo>(scores.Select(s => s.CreateScoreInfo(playlistItem)));
|
||||||
|
|
||||||
|
// Select a score if we don't already have one selected.
|
||||||
|
// Note: This is done before the callback so that the panel list centres on the selected score before panels are added (eliminating initial scroll).
|
||||||
|
if (SelectedScore.Value == null)
|
||||||
|
{
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
// Prefer selecting the local user's score, or otherwise default to the first visible score.
|
||||||
|
SelectedScore.Value = scoreInfos.FirstOrDefault(s => s.User.Id == api.LocalUser.Value.Id) ?? scoreInfos.FirstOrDefault();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invoke callback to add the scores. Exclude the user's current score which was added previously.
|
||||||
|
callback?.Invoke(scoreInfos.Where(s => s.ID != Score?.OnlineScoreID));
|
||||||
|
|
||||||
|
loadingLayer.Hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,11 +164,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
var req = FetchScores(scores => Schedule(() =>
|
var req = FetchScores(fetchScoresCallback);
|
||||||
{
|
|
||||||
foreach (var s in scores)
|
|
||||||
addScore(s);
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (req != null)
|
if (req != null)
|
||||||
api.Queue(req);
|
api.Queue(req);
|
||||||
@ -176,6 +172,29 @@ namespace osu.Game.Screens.Ranking
|
|||||||
statisticsPanel.State.BindValueChanged(onStatisticsStateChanged, true);
|
statisticsPanel.State.BindValueChanged(onStatisticsStateChanged, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private APIRequest nextPageRequest;
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
if (hasAnyScores && nextPageRequest == null)
|
||||||
|
{
|
||||||
|
if (scorePanelList.IsScrolledToStart)
|
||||||
|
nextPageRequest = FetchNextPage(-1, fetchScoresCallback);
|
||||||
|
else if (scorePanelList.IsScrolledToEnd)
|
||||||
|
nextPageRequest = FetchNextPage(1, fetchScoresCallback);
|
||||||
|
|
||||||
|
if (nextPageRequest != null)
|
||||||
|
{
|
||||||
|
nextPageRequest.Success += () => nextPageRequest = null;
|
||||||
|
nextPageRequest.Failure += _ => nextPageRequest = null;
|
||||||
|
|
||||||
|
api.Queue(nextPageRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs a fetch/refresh of scores to be displayed.
|
/// Performs a fetch/refresh of scores to be displayed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -183,6 +202,18 @@ namespace osu.Game.Screens.Ranking
|
|||||||
/// <returns>An <see cref="APIRequest"/> responsible for the fetch operation. This will be queued and performed automatically.</returns>
|
/// <returns>An <see cref="APIRequest"/> responsible for the fetch operation. This will be queued and performed automatically.</returns>
|
||||||
protected virtual APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback) => null;
|
protected virtual APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback) => null;
|
||||||
|
|
||||||
|
protected virtual APIRequest FetchNextPage(int direction, Action<IEnumerable<ScoreInfo>> scoresCallback) => null;
|
||||||
|
|
||||||
|
private bool hasAnyScores;
|
||||||
|
|
||||||
|
private void fetchScoresCallback(IEnumerable<ScoreInfo> scores) => Schedule(() =>
|
||||||
|
{
|
||||||
|
foreach (var s in scores)
|
||||||
|
addScore(s);
|
||||||
|
|
||||||
|
hasAnyScores = true;
|
||||||
|
});
|
||||||
|
|
||||||
public override void OnEntering(IScreen last)
|
public override void OnEntering(IScreen last)
|
||||||
{
|
{
|
||||||
base.OnEntering(last);
|
base.OnEntering(last);
|
||||||
|
@ -26,6 +26,10 @@ namespace osu.Game.Screens.Ranking
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const float expanded_panel_spacing = 15;
|
private const float expanded_panel_spacing = 15;
|
||||||
|
|
||||||
|
public bool IsScrolledToStart => flow.Count > 0 && scroll.ScrollableExtent > 0 && scroll.Current <= 100;
|
||||||
|
|
||||||
|
public bool IsScrolledToEnd => flow.Count > 0 && scroll.ScrollableExtent > 0 && scroll.IsScrolledToEnd(100);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An action to be invoked if a <see cref="ScorePanel"/> is clicked while in an expanded state.
|
/// An action to be invoked if a <see cref="ScorePanel"/> is clicked while in an expanded state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user