mirror of
https://github.com/osukey/osukey.git
synced 2025-07-01 16:29:58 +09:00
Introduce Pagination
and simplify paginated API requests
This commit is contained in:
@ -13,8 +13,8 @@ namespace osu.Game.Online.API.Requests
|
|||||||
|
|
||||||
private readonly BeatmapSetType type;
|
private readonly BeatmapSetType type;
|
||||||
|
|
||||||
public GetUserBeatmapsRequest(long userId, BeatmapSetType type, int page, int itemsPerPage, int initialItems)
|
public GetUserBeatmapsRequest(long userId, BeatmapSetType type, Pagination pagination)
|
||||||
: base(page, itemsPerPage, initialItems)
|
: base(pagination)
|
||||||
{
|
{
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
@ -10,8 +10,8 @@ namespace osu.Game.Online.API.Requests
|
|||||||
{
|
{
|
||||||
private readonly long userId;
|
private readonly long userId;
|
||||||
|
|
||||||
public GetUserKudosuHistoryRequest(long userId, int page, int itemsPerPage, int initialItems)
|
public GetUserKudosuHistoryRequest(long userId, Pagination pagination)
|
||||||
: base(page, itemsPerPage, initialItems)
|
: base(pagination)
|
||||||
{
|
{
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,8 @@ namespace osu.Game.Online.API.Requests
|
|||||||
{
|
{
|
||||||
private readonly long userId;
|
private readonly long userId;
|
||||||
|
|
||||||
public GetUserMostPlayedBeatmapsRequest(long userId, int page, int itemsPerPage, int initialItems)
|
public GetUserMostPlayedBeatmapsRequest(long userId, Pagination pagination)
|
||||||
: base(page, itemsPerPage, initialItems)
|
: base(pagination)
|
||||||
{
|
{
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,8 @@ namespace osu.Game.Online.API.Requests
|
|||||||
{
|
{
|
||||||
private readonly long userId;
|
private readonly long userId;
|
||||||
|
|
||||||
public GetUserRecentActivitiesRequest(long userId, int page, int itemsPerPage, int initialItems)
|
public GetUserRecentActivitiesRequest(long userId, Pagination pagination)
|
||||||
: base(page, itemsPerPage, initialItems)
|
: base(pagination)
|
||||||
{
|
{
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ namespace osu.Game.Online.API.Requests
|
|||||||
private readonly ScoreType type;
|
private readonly ScoreType type;
|
||||||
private readonly RulesetInfo ruleset;
|
private readonly RulesetInfo ruleset;
|
||||||
|
|
||||||
public GetUserScoresRequest(long userId, ScoreType type, int page, int itemsPerPage, int initialItems, RulesetInfo ruleset = null)
|
public GetUserScoresRequest(long userId, ScoreType type, Pagination pagination, RulesetInfo ruleset = null)
|
||||||
: base(page, itemsPerPage, initialItems)
|
: base(pagination)
|
||||||
{
|
{
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
@ -8,28 +8,19 @@ namespace osu.Game.Online.API.Requests
|
|||||||
{
|
{
|
||||||
public abstract class PaginatedAPIRequest<T> : APIRequest<T> where T : class
|
public abstract class PaginatedAPIRequest<T> : APIRequest<T> where T : class
|
||||||
{
|
{
|
||||||
private readonly int page;
|
private readonly Pagination pagination;
|
||||||
private readonly int initialItems;
|
|
||||||
private readonly int itemsPerPage;
|
|
||||||
|
|
||||||
protected PaginatedAPIRequest(int page, int itemsPerPage, int initialItems)
|
protected PaginatedAPIRequest(Pagination pagination)
|
||||||
{
|
{
|
||||||
this.page = page;
|
this.pagination = pagination;
|
||||||
this.initialItems = initialItems;
|
|
||||||
this.itemsPerPage = itemsPerPage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override WebRequest CreateWebRequest()
|
protected override WebRequest CreateWebRequest()
|
||||||
{
|
{
|
||||||
var req = base.CreateWebRequest();
|
var req = base.CreateWebRequest();
|
||||||
|
|
||||||
if (page == 0)
|
req.AddParameter("offset", pagination.Offset.ToString(CultureInfo.InvariantCulture));
|
||||||
req.AddParameter("limit", initialItems.ToString(CultureInfo.InvariantCulture));
|
req.AddParameter("limit", pagination.Limit.ToString(CultureInfo.InvariantCulture));
|
||||||
else
|
|
||||||
{
|
|
||||||
req.AddParameter("offset", (initialItems + (page - 1) * itemsPerPage).ToString(CultureInfo.InvariantCulture));
|
|
||||||
req.AddParameter("limit", itemsPerPage.ToString(CultureInfo.InvariantCulture));
|
|
||||||
}
|
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
38
osu.Game/Online/API/Requests/Pagination.cs
Normal file
38
osu.Game/Online/API/Requests/Pagination.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a pagination data used for <see cref="PaginatedAPIRequest{T}"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly struct Pagination
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The starting point of the request.
|
||||||
|
/// </summary>
|
||||||
|
public int Offset { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum number of items to return in this request.
|
||||||
|
/// </summary>
|
||||||
|
public int Limit { get; }
|
||||||
|
|
||||||
|
public Pagination(int offset, int limit)
|
||||||
|
{
|
||||||
|
Offset = offset;
|
||||||
|
Limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pagination(int limit)
|
||||||
|
: this(0, limit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a <see cref="Pagination"/> of the next number of items defined by <paramref name="limit"/> after this.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="limit">The limit of the next pagination.</param>
|
||||||
|
public Pagination TakeNext(int limit) => new Pagination(Offset + Limit, limit);
|
||||||
|
}
|
||||||
|
}
|
@ -58,8 +58,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override APIRequest<List<APIBeatmapSet>> CreateRequest(int itemsPerPage, int initialItems) =>
|
protected override APIRequest<List<APIBeatmapSet>> CreateRequest(Pagination pagination) =>
|
||||||
new GetUserBeatmapsRequest(User.Value.Id, type, VisiblePages++, itemsPerPage, initialItems);
|
new GetUserBeatmapsRequest(User.Value.Id, type, pagination);
|
||||||
|
|
||||||
protected override Drawable CreateDrawableItem(APIBeatmapSet model) => model.OnlineID > 0
|
protected override Drawable CreateDrawableItem(APIBeatmapSet model) => model.OnlineID > 0
|
||||||
? new BeatmapCardNormal(model)
|
? new BeatmapCardNormal(model)
|
||||||
|
@ -29,8 +29,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
|
|
||||||
protected override int GetCount(APIUser user) => user.BeatmapPlayCountsCount;
|
protected override int GetCount(APIUser user) => user.BeatmapPlayCountsCount;
|
||||||
|
|
||||||
protected override APIRequest<List<APIUserMostPlayedBeatmap>> CreateRequest(int itemsPerPage, int initialItems) =>
|
protected override APIRequest<List<APIUserMostPlayedBeatmap>> CreateRequest(Pagination pagination) =>
|
||||||
new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, itemsPerPage, initialItems);
|
new GetUserMostPlayedBeatmapsRequest(User.Value.Id, pagination);
|
||||||
|
|
||||||
protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap mostPlayed) =>
|
protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap mostPlayed) =>
|
||||||
new DrawableMostPlayedBeatmap(mostPlayed);
|
new DrawableMostPlayedBeatmap(mostPlayed);
|
||||||
|
@ -19,8 +19,8 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override APIRequest<List<APIKudosuHistory>> CreateRequest(int itemsPerPage, int initialItems)
|
protected override APIRequest<List<APIKudosuHistory>> CreateRequest(Pagination pagination)
|
||||||
=> new GetUserKudosuHistoryRequest(User.Value.Id, VisiblePages++, itemsPerPage, initialItems);
|
=> new GetUserKudosuHistoryRequest(User.Value.Id, pagination);
|
||||||
|
|
||||||
protected override Drawable CreateDrawableItem(APIKudosuHistory item) => new DrawableKudosuHistoryItem(item);
|
protected override Drawable CreateDrawableItem(APIKudosuHistory item) => new DrawableKudosuHistoryItem(item);
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ using osu.Game.Graphics.Sprites;
|
|||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
protected int VisiblePages;
|
protected Pagination? CurrentPage { get; private set; }
|
||||||
|
|
||||||
protected ReverseChildIDFillFlowContainer<Drawable> ItemsContainer { get; private set; }
|
protected ReverseChildIDFillFlowContainer<Drawable> ItemsContainer { get; private set; }
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
loadCancellation?.Cancel();
|
loadCancellation?.Cancel();
|
||||||
retrievalRequest?.Cancel();
|
retrievalRequest?.Cancel();
|
||||||
|
|
||||||
VisiblePages = 0;
|
CurrentPage = null;
|
||||||
ItemsContainer.Clear();
|
ItemsContainer.Clear();
|
||||||
|
|
||||||
if (e.NewValue != null)
|
if (e.NewValue != null)
|
||||||
@ -110,7 +111,9 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
{
|
{
|
||||||
loadCancellation = new CancellationTokenSource();
|
loadCancellation = new CancellationTokenSource();
|
||||||
|
|
||||||
retrievalRequest = CreateRequest(ItemsPerPage, InitialItemsCount);
|
CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new Pagination(InitialItemsCount);
|
||||||
|
|
||||||
|
retrievalRequest = CreateRequest(CurrentPage.Value);
|
||||||
retrievalRequest.Success += UpdateItems;
|
retrievalRequest.Success += UpdateItems;
|
||||||
|
|
||||||
api.Queue(retrievalRequest);
|
api.Queue(retrievalRequest);
|
||||||
@ -120,7 +123,7 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
{
|
{
|
||||||
OnItemsReceived(items);
|
OnItemsReceived(items);
|
||||||
|
|
||||||
if (!items.Any() && VisiblePages == 1)
|
if (!items.Any() && CurrentPage?.Offset == 0)
|
||||||
{
|
{
|
||||||
moreButton.Hide();
|
moreButton.Hide();
|
||||||
moreButton.IsLoading = false;
|
moreButton.IsLoading = false;
|
||||||
@ -135,8 +138,7 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
{
|
{
|
||||||
missing.Hide();
|
missing.Hide();
|
||||||
|
|
||||||
int maxCount = VisiblePages == 1 ? InitialItemsCount : ItemsPerPage;
|
moreButton.FadeTo(items.Count == CurrentPage?.Limit ? 1 : 0);
|
||||||
moreButton.FadeTo(items.Count == maxCount ? 1 : 0);
|
|
||||||
moreButton.IsLoading = false;
|
moreButton.IsLoading = false;
|
||||||
|
|
||||||
ItemsContainer.AddRange(drawables);
|
ItemsContainer.AddRange(drawables);
|
||||||
@ -149,7 +151,7 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract APIRequest<List<TModel>> CreateRequest(int itemsPerPage, int initialItems);
|
protected abstract APIRequest<List<TModel>> CreateRequest(Pagination pagination);
|
||||||
|
|
||||||
protected abstract Drawable CreateDrawableItem(TModel model);
|
protected abstract Drawable CreateDrawableItem(TModel model);
|
||||||
|
|
||||||
|
@ -54,14 +54,14 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
|
|
||||||
protected override void OnItemsReceived(List<APIScore> items)
|
protected override void OnItemsReceived(List<APIScore> items)
|
||||||
{
|
{
|
||||||
if (VisiblePages == 0)
|
if (CurrentPage == null || CurrentPage?.Offset == 0)
|
||||||
drawableItemIndex = 0;
|
drawableItemIndex = 0;
|
||||||
|
|
||||||
base.OnItemsReceived(items);
|
base.OnItemsReceived(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override APIRequest<List<APIScore>> CreateRequest(int itemsPerPage, int initialItems) =>
|
protected override APIRequest<List<APIScore>> CreateRequest(Pagination pagination) =>
|
||||||
new GetUserScoresRequest(User.Value.Id, type, VisiblePages++, itemsPerPage, initialItems);
|
new GetUserScoresRequest(User.Value.Id, type, pagination);
|
||||||
|
|
||||||
private int drawableItemIndex;
|
private int drawableItemIndex;
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
|
|||||||
ItemsContainer.Spacing = new Vector2(0, 8);
|
ItemsContainer.Spacing = new Vector2(0, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override APIRequest<List<APIRecentActivity>> CreateRequest(int itemsPerPage, int initialItems) =>
|
protected override APIRequest<List<APIRecentActivity>> CreateRequest(Pagination pagination) =>
|
||||||
new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++, itemsPerPage, initialItems);
|
new GetUserRecentActivitiesRequest(User.Value.Id, pagination);
|
||||||
|
|
||||||
protected override Drawable CreateDrawableItem(APIRecentActivity model) => new DrawableRecentActivity(model);
|
protected override Drawable CreateDrawableItem(APIRecentActivity model) => new DrawableRecentActivity(model);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user