feat(media): pagination
This commit is contained in:
1 parent
04dc151ed7
commit
63c1e7076e
65 files changed
+2960
-365
No files matched your search
@@ -4,13 +4,9 @@ import (
|
||||
"RenewCMS/internal/domain/article"
|
||||
"RenewCMS/internal/domain/image"
|
||||
"RenewCMS/internal/domain/user"
|
||||
"encoding/base64"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const cursorPrefix = "offset:"
|
||||
|
||||
type MediaItem struct {
|
||||
Image image.Image
|
||||
UploadedBy string
|
||||
@@ -28,9 +24,11 @@ type MediaCounts struct {
|
||||
}
|
||||
|
||||
type MediaPage struct {
|
||||
Items []MediaItem
|
||||
NextCursor string
|
||||
Counts MediaCounts
|
||||
Items []MediaItem
|
||||
Total int
|
||||
Page int
|
||||
Size int
|
||||
Counts MediaCounts
|
||||
}
|
||||
|
||||
type ListMediaUseCase struct {
|
||||
@@ -48,10 +46,6 @@ func (l *ListMediaUseCase) List(query image.ListQuery) (MediaPage, error) {
|
||||
if err := query.Validate(); err != nil {
|
||||
return MediaPage{}, err
|
||||
}
|
||||
offset, err := decodeCursor(query.Cursor)
|
||||
if err != nil {
|
||||
return MediaPage{}, err
|
||||
}
|
||||
|
||||
usage, err := l.usageCounter()
|
||||
if err != nil {
|
||||
@@ -83,8 +77,9 @@ func (l *ListMediaUseCase) List(query image.ListQuery) (MediaPage, error) {
|
||||
}
|
||||
}
|
||||
|
||||
pageEnd := min(offset+query.Limit, len(matching))
|
||||
pageStart := min(offset, pageEnd)
|
||||
offset := (query.Page - 1) * query.Size
|
||||
pageStart := min(offset, len(matching))
|
||||
pageEnd := min(pageStart+query.Size, len(matching))
|
||||
names := newUploaderNames(l.userRepository)
|
||||
items := []MediaItem{}
|
||||
for _, img := range matching[pageStart:pageEnd] {
|
||||
@@ -103,11 +98,7 @@ func (l *ListMediaUseCase) List(query image.ListQuery) (MediaPage, error) {
|
||||
})
|
||||
}
|
||||
|
||||
page := MediaPage{Items: items, Counts: counts}
|
||||
if pageEnd < len(matching) {
|
||||
page.NextCursor = encodeCursor(pageEnd)
|
||||
}
|
||||
return page, nil
|
||||
return MediaPage{Items: items, Total: len(matching), Page: query.Page, Size: query.Size, Counts: counts}, nil
|
||||
}
|
||||
|
||||
func (l *ListMediaUseCase) Describe(img image.Image) (MediaItem, error) {
|
||||
@@ -217,22 +208,3 @@ func matchesFilter(filter image.Filter, usedIn int, duplicate bool) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func encodeCursor(offset int) string {
|
||||
return base64.RawURLEncoding.EncodeToString([]byte(cursorPrefix + strconv.Itoa(offset)))
|
||||
}
|
||||
|
||||
func decodeCursor(cursor string) (int, error) {
|
||||
if cursor == "" {
|
||||
return 0, nil
|
||||
}
|
||||
raw, err := base64.RawURLEncoding.DecodeString(cursor)
|
||||
if err != nil || !strings.HasPrefix(string(raw), cursorPrefix) {
|
||||
return 0, image.ErrInvalidQuery
|
||||
}
|
||||
offset, err := strconv.Atoi(strings.TrimPrefix(string(raw), cursorPrefix))
|
||||
if err != nil || offset < 0 {
|
||||
return 0, image.ErrInvalidQuery
|
||||
}
|
||||
return offset, nil
|
||||
}
|
||||
Reference in new issue
Block a user