From 33f05bc262dded574f6ef31f59d176ff560075c2 Mon Sep 17 00:00:00 2001 From: Leon Hudak <33522493+leohhhn@users.noreply.github.com> Date: Fri, 15 Mar 2024 15:20:47 +0100 Subject: [PATCH] fix: better pagination (#2) * remove checks * remove pointless assertion * sort newest-first by default * modifications * fix pagination * rm newline * spacing/inlining --- api/p/memeland/memeland.gno | 30 ++++++++++++++++-------------- api/p/memeland/memeland_test.gno | 14 +++++++------- api/r/memeland/memeland.gno | 17 ++--------------- api/r/memeland/memeland_test.gno | 0 4 files changed, 25 insertions(+), 36 deletions(-) create mode 100644 api/r/memeland/memeland_test.gno diff --git a/api/p/memeland/memeland.gno b/api/p/memeland/memeland.gno index 4994915..b154d85 100644 --- a/api/p/memeland/memeland.gno +++ b/api/p/memeland/memeland.gno @@ -50,7 +50,6 @@ func (m *Memeland) PostMeme(data string, timestamp int64) string { } m.Posts = append(m.Posts, newPost) - return id } @@ -60,18 +59,13 @@ func (m *Memeland) Upvote(id string) string { panic("post with specified ID does not exist") } - p, ok := post.(*Post) - if !ok { - panic("error casting post") - } - caller := std.PrevRealm().Addr().String() - if _, exists := p.UpvoteTracker.Get(caller); exists { + if _, exists := post.UpvoteTracker.Get(caller); exists { panic("user has already upvoted this post") } - p.UpvoteTracker.Set(caller, struct{}{}) + post.UpvoteTracker.Set(caller, struct{}{}) return "upvote successful" } @@ -103,25 +97,26 @@ func (m *Memeland) GetPostsInRange(startTimestamp, endTimestamp int64, page, pag case "UPVOTES": sort.Sort(UpvoteSorter(filteredPosts)) default: - break + // Sort by timestamp, beginning with newest + filteredPosts = reversePosts(filteredPosts) } // Pagination startIndex := (page - 1) * pageSize endIndex := startIndex + pageSize + // If page does not contain any posts if startIndex >= len(filteredPosts) { - panic("page size too large") + return "[]" } + // If page contains fewer posts than the page size if endIndex > len(filteredPosts) { endIndex = len(filteredPosts) } - paginatedPosts := filteredPosts[startIndex:endIndex] - // Return JSON representation of paginated and sorted posts - return PostsToJSONString(paginatedPosts) + return PostsToJSONString(filteredPosts[startIndex:endIndex]) } // PostsToJSONString converts a slice of Post structs into a JSON string representation. @@ -136,8 +131,8 @@ func PostsToJSONString(posts []*Post) string { sb.WriteString(PostToJSONString(post)) } - sb.WriteString("]") + return sb.String() } @@ -170,6 +165,13 @@ func (m *Memeland) getPost(id string) *Post { return nil } +func reversePosts(posts []*Post) []*Post { + for i, j := 0, len(posts)-1; i < j; i, j = i+1, j-1 { + posts[i], posts[j] = posts[j], posts[i] + } + return posts +} + func (a UpvoteSorter) Len() int { return len(a) } func (a UpvoteSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a UpvoteSorter) Less(i, j int) bool { diff --git a/api/p/memeland/memeland_test.gno b/api/p/memeland/memeland_test.gno index 861e148..7ff7e80 100644 --- a/api/p/memeland/memeland_test.gno +++ b/api/p/memeland/memeland_test.gno @@ -42,11 +42,12 @@ func TestGetPostsInRangePagination(t *testing.T) { pageSize int expectedNumOfPosts int }{ - {page: 1, pageSize: 1, expectedNumOfPosts: 1}, // one per page - {page: 2, pageSize: 1, expectedNumOfPosts: 1}, // one on second page - {page: 1, pageSize: numOfPosts, expectedNumOfPosts: numOfPosts}, // all posts on single page - //{page: 10, pageSize: 10, expectedNumOfPosts: 0}, // todo fix - {page: 5, pageSize: numOfPosts / 5, expectedNumOfPosts: 2}, // evenly distribute posts per page + {page: 1, pageSize: 1, expectedNumOfPosts: 1}, // one per page + {page: 2, pageSize: 1, expectedNumOfPosts: 1}, // one on second page + {page: 1, pageSize: numOfPosts, expectedNumOfPosts: numOfPosts}, // all posts on single page + {page: 12, pageSize: 1, expectedNumOfPosts: 0}, // empty page + {page: 1, pageSize: numOfPosts + 1, expectedNumOfPosts: numOfPosts}, // page with fewer posts than its size + {page: 5, pageSize: numOfPosts / 5, expectedNumOfPosts: 2}, // evenly distribute posts per page } for _, tc := range testCases { @@ -66,7 +67,7 @@ func TestGetPostsInRangeByTimestamp(t *testing.T) { m := NewMemeland() now := time.Now() - numOfPosts := 10 + numOfPosts := 5 var memeData []string for i := 1; i <= numOfPosts; i++ { // Prep meme data @@ -107,7 +108,6 @@ func TestGetPostsInRangeByTimestamp(t *testing.T) { } // todo add test to check order - } func TestGetPostsInRangeByUpvote(t *testing.T) { diff --git a/api/r/memeland/memeland.gno b/api/r/memeland/memeland.gno index e8e1e4c..cadac84 100644 --- a/api/r/memeland/memeland.gno +++ b/api/r/memeland/memeland.gno @@ -8,36 +8,23 @@ import ( var m = memeland.NewMemeland() func PostMeme(data string, timestamp int64) string { - if m == nil { - return "memeland does not exist" - } return m.PostMeme(data, timestamp) } func Upvote(id string) string { - if m == nil { - return "memeland does not exist" - } return m.Upvote(id) } func GetPostsInRange(startTimestamp, endTimestamp int64, page, pageSize int, sortBy string) string { - if m == nil { - return "memeland does not exist" - } - return m.GetPostsInRange(startTimestamp, endTimestamp, page, pageSize, sortBy) } func Render(path string) string { numOfMemes := int(m.MemeCounter) if numOfMemes == 0 { - return "no memes yet :c" + return "No memes posted yet! :/" } // Default render is get Posts since year 2000 to now - postsJson := m.GetPostsInRange(952733931, time.Now().Unix(), 1, numOfMemes, "DATE_CREATED") - if postsJson == "[]" { - } - return postsJson + return m.GetPostsInRange(0, time.Now().Unix(), 1, numOfMemes, "DATE_CREATED") } diff --git a/api/r/memeland/memeland_test.gno b/api/r/memeland/memeland_test.gno new file mode 100644 index 0000000..e69de29