aboutsummaryrefslogtreecommitdiff
path: root/backend/handlers/map.go
diff options
context:
space:
mode:
authorArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2023-09-18 12:03:30 +0300
committerArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2023-09-18 12:03:30 +0300
commitd69a601251ce3a3e785cf9a32233b7d7dd94fea5 (patch)
treead07b32a77ebd3e92b55828e7e3e0a2b2466bfcc /backend/handlers/map.go
parentMerge branch 'main' of https://github.com/pektezol/LeastPortalsHub (diff)
downloadlphub-d69a601251ce3a3e785cf9a32233b7d7dd94fea5.tar.gz
lphub-d69a601251ce3a3e785cf9a32233b7d7dd94fea5.tar.bz2
lphub-d69a601251ce3a3e785cf9a32233b7d7dd94fea5.zip
feat: pagination for map leaderboards
Former-commit-id: 0a38362eadcf1c1ecf5ae29d5a58a015abfd54ee
Diffstat (limited to 'backend/handlers/map.go')
-rw-r--r--backend/handlers/map.go63
1 files changed, 50 insertions, 13 deletions
diff --git a/backend/handlers/map.go b/backend/handlers/map.go
index 1d9cee8..b3de2e8 100644
--- a/backend/handlers/map.go
+++ b/backend/handlers/map.go
@@ -16,8 +16,9 @@ type MapSummaryResponse struct {
16} 16}
17 17
18type MapLeaderboardsResponse struct { 18type MapLeaderboardsResponse struct {
19 Map models.Map `json:"map"` 19 Map models.Map `json:"map"`
20 Records any `json:"records"` 20 Records any `json:"records"`
21 Pagination models.Pagination `json:"pagination"`
21} 22}
22 23
23type ChaptersResponse struct { 24type ChaptersResponse struct {
@@ -115,17 +116,24 @@ func FetchMapSummary(c *gin.Context) {
115// @Description Get map leaderboards with specified id. 116// @Description Get map leaderboards with specified id.
116// @Tags maps 117// @Tags maps
117// @Produce json 118// @Produce json
118// @Param id path int true "Map ID" 119// @Param id path int true "Map ID"
119// @Success 200 {object} models.Response{data=MapLeaderboardsResponse} 120// @Param page query int false "Page Number (default: 1)"
120// @Failure 400 {object} models.Response 121// @Param pageSize query int false "Number of Records Per Page (default: 10)"
122// @Success 200 {object} models.Response{data=MapLeaderboardsResponse}
123// @Failure 400 {object} models.Response
121// @Router /maps/{id}/leaderboards [get] 124// @Router /maps/{id}/leaderboards [get]
122func FetchMapLeaderboards(c *gin.Context) { 125func FetchMapLeaderboards(c *gin.Context) {
123 // TODO: make new response type
124 id := c.Param("id") 126 id := c.Param("id")
125 // Get map data 127 // Get map data
126 response := MapLeaderboardsResponse{Map: models.Map{}, Records: nil} 128 response := MapLeaderboardsResponse{Map: models.Map{}, Records: nil, Pagination: models.Pagination{}}
127 // var mapData models.Map 129 page, err := strconv.Atoi(c.DefaultQuery("page", "1"))
128 // var mapRecordsData models.MapRecords 130 if err != nil || page < 1 {
131 page = 1
132 }
133 pageSize, err := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
134 if err != nil || pageSize < 1 {
135 pageSize = 10
136 }
129 var isDisabled bool 137 var isDisabled bool
130 intID, err := strconv.Atoi(id) 138 intID, err := strconv.Atoi(id)
131 if err != nil { 139 if err != nil {
@@ -147,7 +155,8 @@ func FetchMapLeaderboards(c *gin.Context) {
147 c.JSON(http.StatusBadRequest, models.ErrorResponse("Map is not available for competitive boards.")) 155 c.JSON(http.StatusBadRequest, models.ErrorResponse("Map is not available for competitive boards."))
148 return 156 return
149 } 157 }
150 // TODO: avatar and names for host & partner 158 totalRecords := 0
159 totalPages := 0
151 if response.Map.GameName == "Portal 2 - Cooperative" { 160 if response.Map.GameName == "Portal 2 - Cooperative" {
152 records := []RecordMultiplayer{} 161 records := []RecordMultiplayer{}
153 sql = `SELECT 162 sql = `SELECT
@@ -179,7 +188,7 @@ func FetchMapLeaderboards(c *gin.Context) {
179 ) sub 188 ) sub
180 JOIN users AS host ON sub.host_id = host.steam_id 189 JOIN users AS host ON sub.host_id = host.steam_id
181 JOIN users AS partner ON sub.partner_id = partner.steam_id 190 JOIN users AS partner ON sub.partner_id = partner.steam_id
182 WHERE sub.rn = 1;` 191 WHERE sub.rn = 1`
183 rows, err := database.DB.Query(sql, id) 192 rows, err := database.DB.Query(sql, id)
184 if err != nil { 193 if err != nil {
185 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 194 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
@@ -203,7 +212,18 @@ func FetchMapLeaderboards(c *gin.Context) {
203 records = append(records, record) 212 records = append(records, record)
204 placement++ 213 placement++
205 } 214 }
206 response.Records = records 215 totalRecords = len(records)
216 totalPages = (totalRecords + pageSize - 1) / pageSize
217 if page > totalPages {
218 c.JSON(http.StatusBadRequest, models.ErrorResponse("Invalid page number."))
219 return
220 }
221 startIndex := (page - 1) * pageSize
222 endIndex := startIndex + pageSize
223 if endIndex > totalRecords {
224 endIndex = totalRecords
225 }
226 response.Records = records[startIndex:endIndex]
207 } else { 227 } else {
208 records := []RecordSingleplayer{} 228 records := []RecordSingleplayer{}
209 sql = `SELECT id, user_id, users.user_name, users.avatar_link, score_count, score_time, demo_id, record_date 229 sql = `SELECT id, user_id, users.user_name, users.avatar_link, score_count, score_time, demo_id, record_date
@@ -238,7 +258,24 @@ func FetchMapLeaderboards(c *gin.Context) {
238 records = append(records, record) 258 records = append(records, record)
239 placement++ 259 placement++
240 } 260 }
241 response.Records = records 261 totalRecords = len(records)
262 totalPages = (totalRecords + pageSize - 1) / pageSize
263 if page > totalPages {
264 c.JSON(http.StatusBadRequest, models.ErrorResponse("Invalid page number."))
265 return
266 }
267 startIndex := (page - 1) * pageSize
268 endIndex := startIndex + pageSize
269 if endIndex > totalRecords {
270 endIndex = totalRecords
271 }
272 response.Records = records[startIndex:endIndex]
273 }
274 response.Pagination = models.Pagination{
275 TotalRecords: totalRecords,
276 TotalPages: totalPages,
277 CurrentPage: page,
278 PageSize: pageSize,
242 } 279 }
243 c.JSON(http.StatusOK, models.Response{ 280 c.JSON(http.StatusOK, models.Response{
244 Success: true, 281 Success: true,