aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2023-10-10 19:41:31 +0300
committerGitHub <noreply@github.com>2023-10-10 19:41:31 +0300
commit7c40cdb0fdd112736b98591ab1a14622146788c7 (patch)
tree073a4a315fd9a2c7e974d174b93eb21b8d4d4549 /backend
parentfeat: add is_disabled to chapters itself (#112) (diff)
downloadlphub-7c40cdb0fdd112736b98591ab1a14622146788c7.tar.gz
lphub-7c40cdb0fdd112736b98591ab1a14622146788c7.tar.bz2
lphub-7c40cdb0fdd112736b98591ab1a14622146788c7.zip
feat: pagination for user/profile scores (#118)
Former-commit-id: 1a1244a49c9be8f73240f2d5b6f7abe05a1544ab
Diffstat (limited to 'backend')
-rw-r--r--backend/handlers/user.go84
1 files changed, 73 insertions, 11 deletions
diff --git a/backend/handlers/user.go b/backend/handlers/user.go
index c985471..a9174a2 100644
--- a/backend/handlers/user.go
+++ b/backend/handlers/user.go
@@ -4,6 +4,7 @@ import (
4 "net/http" 4 "net/http"
5 "os" 5 "os"
6 "regexp" 6 "regexp"
7 "strconv"
7 "time" 8 "time"
8 9
9 "github.com/gin-gonic/gin" 10 "github.com/gin-gonic/gin"
@@ -12,15 +13,16 @@ import (
12) 13)
13 14
14type ProfileResponse struct { 15type ProfileResponse struct {
15 Profile bool `json:"profile"` 16 Profile bool `json:"profile"`
16 SteamID string `json:"steam_id"` 17 SteamID string `json:"steam_id"`
17 UserName string `json:"user_name"` 18 UserName string `json:"user_name"`
18 AvatarLink string `json:"avatar_link"` 19 AvatarLink string `json:"avatar_link"`
19 CountryCode string `json:"country_code"` 20 CountryCode string `json:"country_code"`
20 Titles []models.Title `json:"titles"` 21 Titles []models.Title `json:"titles"`
21 Links models.Links `json:"links"` 22 Links models.Links `json:"links"`
22 Rankings ProfileRankings `json:"rankings"` 23 Rankings ProfileRankings `json:"rankings"`
23 Records []ProfileRecords `json:"records"` 24 Records []ProfileRecords `json:"records"`
25 Pagination models.Pagination `json:"pagination"`
24} 26}
25 27
26type ProfileRankings struct { 28type ProfileRankings struct {
@@ -73,10 +75,18 @@ func Profile(c *gin.Context) {
73 c.JSON(http.StatusOK, models.ErrorResponse("User not logged in.")) 75 c.JSON(http.StatusOK, models.ErrorResponse("User not logged in."))
74 return 76 return
75 } 77 }
78 page, err := strconv.Atoi(c.DefaultQuery("page", "1"))
79 if err != nil || page < 1 {
80 page = 1
81 }
82 pageSize, err := strconv.Atoi(c.DefaultQuery("pageSize", "20"))
83 if err != nil || pageSize < 1 {
84 pageSize = 20
85 }
76 // Get user links 86 // Get user links
77 links := models.Links{} 87 links := models.Links{}
78 sql := `SELECT u.p2sr, u.steam, u.youtube, u.twitch FROM users u WHERE u.steam_id = $1` 88 sql := `SELECT u.p2sr, u.steam, u.youtube, u.twitch FROM users u WHERE u.steam_id = $1`
79 err := database.DB.QueryRow(sql, user.(models.User).SteamID).Scan(&links.P2SR, &links.Steam, &links.YouTube, &links.Twitch) 89 err = database.DB.QueryRow(sql, user.(models.User).SteamID).Scan(&links.P2SR, &links.Steam, &links.YouTube, &links.Twitch)
80 if err != nil { 90 if err != nil {
81 c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) 91 c.JSON(http.StatusOK, models.ErrorResponse(err.Error()))
82 return 92 return
@@ -291,6 +301,8 @@ func Profile(c *gin.Context) {
291 } 301 }
292 } 302 }
293 records := []ProfileRecords{} 303 records := []ProfileRecords{}
304 totalRecords := 0
305 totalPages := 0
294 // Get singleplayer records 306 // Get singleplayer records
295 sql = `SELECT sp.id, m.game_id, m.chapter_id, sp.map_id, m."name", (SELECT mr.score_count FROM map_routes mr WHERE mr.map_id = sp.map_id ORDER BY mr.score_count ASC LIMIT 1) AS wr_count, sp.score_count, sp.score_time, sp.demo_id, sp.record_date 307 sql = `SELECT sp.id, m.game_id, m.chapter_id, sp.map_id, m."name", (SELECT mr.score_count FROM map_routes mr WHERE mr.map_id = sp.map_id ORDER BY mr.score_count ASC LIMIT 1) AS wr_count, sp.score_count, sp.score_time, sp.demo_id, sp.record_date
296 FROM records_sp sp INNER JOIN maps m ON sp.map_id = m.id WHERE sp.user_id = $1 AND sp.is_deleted = false ORDER BY sp.map_id, sp.score_count, sp.score_time` 308 FROM records_sp sp INNER JOIN maps m ON sp.map_id = m.id WHERE sp.user_id = $1 AND sp.is_deleted = false ORDER BY sp.map_id, sp.score_count, sp.score_time`
@@ -393,6 +405,20 @@ func Profile(c *gin.Context) {
393 placementIndex++ 405 placementIndex++
394 records[len(records)-1].Scores = append(records[len(records)-1].Scores, score) 406 records[len(records)-1].Scores = append(records[len(records)-1].Scores, score)
395 } 407 }
408 totalRecords = len(records)
409 if totalRecords != 0 {
410 totalPages = (totalRecords + pageSize - 1) / pageSize
411 if page > totalPages {
412 c.JSON(http.StatusOK, models.ErrorResponse("Invalid page number."))
413 return
414 }
415 startIndex := (page - 1) * pageSize
416 endIndex := startIndex + pageSize
417 if endIndex > totalRecords {
418 endIndex = totalRecords
419 }
420 records = records[startIndex:endIndex]
421 }
396 c.JSON(http.StatusOK, models.Response{ 422 c.JSON(http.StatusOK, models.Response{
397 Success: true, 423 Success: true,
398 Message: "Successfully retrieved user scores.", 424 Message: "Successfully retrieved user scores.",
@@ -406,6 +432,12 @@ func Profile(c *gin.Context) {
406 Links: links, 432 Links: links,
407 Rankings: rankings, 433 Rankings: rankings,
408 Records: records, 434 Records: records,
435 Pagination: models.Pagination{
436 TotalRecords: totalRecords,
437 TotalPages: totalPages,
438 CurrentPage: page,
439 PageSize: pageSize,
440 },
409 }, 441 },
410 }) 442 })
411} 443}
@@ -427,11 +459,19 @@ func FetchUser(c *gin.Context) {
427 c.JSON(http.StatusOK, models.ErrorResponse("User not found.")) 459 c.JSON(http.StatusOK, models.ErrorResponse("User not found."))
428 return 460 return
429 } 461 }
462 page, err := strconv.Atoi(c.DefaultQuery("page", "1"))
463 if err != nil || page < 1 {
464 page = 1
465 }
466 pageSize, err := strconv.Atoi(c.DefaultQuery("pageSize", "20"))
467 if err != nil || pageSize < 1 {
468 pageSize = 20
469 }
430 // Check if user exists 470 // Check if user exists
431 var user models.User 471 var user models.User
432 links := models.Links{} 472 links := models.Links{}
433 sql := `SELECT u.steam_id, u.user_name, u.avatar_link, u.country_code, u.created_at, u.updated_at, u.p2sr, u.steam, u.youtube, u.twitch FROM users u WHERE u.steam_id = $1` 473 sql := `SELECT u.steam_id, u.user_name, u.avatar_link, u.country_code, u.created_at, u.updated_at, u.p2sr, u.steam, u.youtube, u.twitch FROM users u WHERE u.steam_id = $1`
434 err := database.DB.QueryRow(sql, id).Scan(&user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, &user.CreatedAt, &user.UpdatedAt, &links.P2SR, &links.Steam, &links.YouTube, &links.Twitch) 474 err = database.DB.QueryRow(sql, id).Scan(&user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, &user.CreatedAt, &user.UpdatedAt, &links.P2SR, &links.Steam, &links.YouTube, &links.Twitch)
435 if err != nil { 475 if err != nil {
436 c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) 476 c.JSON(http.StatusOK, models.ErrorResponse(err.Error()))
437 return 477 return
@@ -663,6 +703,8 @@ func FetchUser(c *gin.Context) {
663 } 703 }
664 } 704 }
665 records := []ProfileRecords{} 705 records := []ProfileRecords{}
706 totalRecords := 0
707 totalPages := 0
666 // Get singleplayer records 708 // Get singleplayer records
667 sql = `SELECT sp.id, m.game_id, m.chapter_id, sp.map_id, m."name", (SELECT mr.score_count FROM map_routes mr WHERE mr.map_id = sp.map_id ORDER BY mr.score_count ASC LIMIT 1) AS wr_count, sp.score_count, sp.score_time, sp.demo_id, sp.record_date 709 sql = `SELECT sp.id, m.game_id, m.chapter_id, sp.map_id, m."name", (SELECT mr.score_count FROM map_routes mr WHERE mr.map_id = sp.map_id ORDER BY mr.score_count ASC LIMIT 1) AS wr_count, sp.score_count, sp.score_time, sp.demo_id, sp.record_date
668 FROM records_sp sp INNER JOIN maps m ON sp.map_id = m.id WHERE sp.user_id = $1 AND sp.is_deleted = false ORDER BY sp.map_id, sp.score_count, sp.score_time` 710 FROM records_sp sp INNER JOIN maps m ON sp.map_id = m.id WHERE sp.user_id = $1 AND sp.is_deleted = false ORDER BY sp.map_id, sp.score_count, sp.score_time`
@@ -765,6 +807,20 @@ func FetchUser(c *gin.Context) {
765 placementIndex++ 807 placementIndex++
766 records[len(records)-1].Scores = append(records[len(records)-1].Scores, score) 808 records[len(records)-1].Scores = append(records[len(records)-1].Scores, score)
767 } 809 }
810 totalRecords = len(records)
811 if totalRecords != 0 {
812 totalPages = (totalRecords + pageSize - 1) / pageSize
813 if page > totalPages {
814 c.JSON(http.StatusOK, models.ErrorResponse("Invalid page number."))
815 return
816 }
817 startIndex := (page - 1) * pageSize
818 endIndex := startIndex + pageSize
819 if endIndex > totalRecords {
820 endIndex = totalRecords
821 }
822 records = records[startIndex:endIndex]
823 }
768 c.JSON(http.StatusOK, models.Response{ 824 c.JSON(http.StatusOK, models.Response{
769 Success: true, 825 Success: true,
770 Message: "Successfully retrieved user scores.", 826 Message: "Successfully retrieved user scores.",
@@ -778,6 +834,12 @@ func FetchUser(c *gin.Context) {
778 Links: links, 834 Links: links,
779 Rankings: rankings, 835 Rankings: rankings,
780 Records: records, 836 Records: records,
837 Pagination: models.Pagination{
838 TotalRecords: totalRecords,
839 TotalPages: totalPages,
840 CurrentPage: page,
841 PageSize: pageSize,
842 },
781 }, 843 },
782 }) 844 })
783} 845}