Add pagination to Leaderboard API response
This commit is contained in:
parent
c6333ec3ad
commit
29fc204536
@ -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; }
|
||||
}
|
@ -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
|
||||
});
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user