1
0
mirror of synced 2025-01-19 00:04:05 +01:00

Add pagination to Leaderboard API response

This commit is contained in:
shiibe 2024-06-04 22:15:58 -04:00
parent c6333ec3ad
commit 29fc204536
5 changed files with 44 additions and 16 deletions

View File

@ -2,5 +2,7 @@
public class SongLeaderboardResponse
{
public List<SongLeaderboard> Leaderboard { get; set; } = new();
public List<SongLeaderboard> LeaderboardData { get; set; }
public int CurrentPage { get; set; }
public int TotalPages { get; set; }
}

View File

@ -16,8 +16,7 @@ public class SongLeaderboardController(ISongLeaderboardService songLeaderboardSe
[HttpGet("{songId}")]
[ServiceFilter(typeof(AuthorizeIfRequiredAttribute))]
public async Task<ActionResult<SongLeaderboardResponse>> GetSongLeaderboard(uint songId, [FromQuery] uint baid, [FromQuery] uint difficulty)
public async Task<ActionResult<SongLeaderboardResponse>> GetSongLeaderboard(uint songId, [FromQuery] uint baid, [FromQuery] uint difficulty, [FromQuery] int page = 1, [FromQuery] int limit = 10)
{
// if baid id is provided, check authentication
if (!baid.Equals(0))
@ -37,16 +36,28 @@ public class SongLeaderboardController(ISongLeaderboardService songLeaderboardSe
}
}
if (page < 1)
{
return BadRequest(new { Message = "Page number cannot be less than 1." });
}
if (limit > 200)
{
return BadRequest(new { Message = "Limit cannot be greater than 200." });
}
if (difficulty < 1 || difficulty > 5)
{
return BadRequest(new { Message = "Invalid difficulty. Please provide a number between 1-5." });
}
var leaderboard = await songLeaderboardService.GetSongLeaderboard(songId, (Difficulty)difficulty, (int)baid);
var (leaderboard, totalPages) = await songLeaderboardService.GetSongLeaderboard(songId, (Difficulty)difficulty, (int)baid, page, limit);
return Ok(new SongLeaderboardResponse
{
Leaderboard = leaderboard
LeaderboardData = leaderboard,
CurrentPage = page,
TotalPages = totalPages
});
}
}

View File

@ -3,5 +3,5 @@
using SharedProject.Models;
public interface ISongLeaderboardService
{
public Task<List<SongLeaderboard>> GetSongLeaderboard(uint songId, Difficulty difficulty, int baid, int limit = 10);
Task<(List<SongLeaderboard>, int)> GetSongLeaderboard(uint songId, Difficulty difficulty, int baid = 0, int page = 1, int limit = 10);
}

View File

@ -12,19 +12,29 @@ public class SongLeaderboardService : ISongLeaderboardService
this.context = context;
}
public async Task<List<SongLeaderboard>> GetSongLeaderboard(uint songId, Difficulty difficulty, int baid,
int limit = 10)
public async Task<(List<SongLeaderboard>, int)> GetSongLeaderboard(uint songId, Difficulty difficulty, int baid = 0,
int page = 1, int limit = 10)
{
if (baid == 0)
{
throw new ArgumentNullException(nameof(baid));
}
// Get the total count of scores for the song
var totalScores = await context.SongBestData
.Where(x => x.SongId == songId && x.Difficulty == difficulty)
.CountAsync();
// Calculate the total pages
var totalPages = totalScores / limit;
// If there is a remainder, add one to the total pages
if (totalScores % limit > 0)
{
totalPages++;
}
// get all scores for the song from every user
var scores = await context.SongBestData
.Where(x => x.SongId == songId && x.Difficulty == difficulty)
.OrderByDescending(x => x.BestScore)
.ThenByDescending(x => x.BestRate)
.Skip((page - 1) * limit) // Subtract 1 because page numbers now start at 1
.Take(limit)
.ToListAsync();
@ -54,6 +64,11 @@ public class SongLeaderboardService : ISongLeaderboardService
});
}
if (baid == 0)
{
return (leaderboard, totalPages);
}
// get current user score if it exists
var currentUserScore = await context.SongBestData
.Where(x => x.SongId == songId && x.Difficulty == difficulty && x.Baid == baid)
@ -84,6 +99,6 @@ public class SongLeaderboardService : ISongLeaderboardService
}
}
return leaderboard;
return (leaderboard, totalPages);
}
}

View File

@ -32,7 +32,7 @@
</MudGrid>
</MudCardHeader>
<MudCardContent Class="pa-0">
@if (response == null || response.Leaderboard.Count == 0)
@if (response == null || response.LeaderboardData.Count == 0)
{
<MudGrid>
<MudItem xs="12">
@ -44,7 +44,7 @@
}
else
{
<MudTable RowClassFunc="@GetActiveRowClass" Loading="isLoading" Items="@response.Leaderboard" Class="leaderboard-table" Elevation="0" Outlined="false" Dense="true" Striped="true">
<MudTable RowClassFunc="@GetActiveRowClass" Loading="isLoading" Items="@response.LeaderboardData" Class="leaderboard-table" Elevation="0" Outlined="false" Dense="true" Striped="true">
<HeaderContent>
<MudTh>@Localizer["Rank"]</MudTh>
<MudTh>@Localizer["Player"]</MudTh>