diff options
author | 2023-05-22 16:32:36 +0200 | |
---|---|---|
committer | 2023-05-22 16:32:36 +0200 | |
commit | c48abd8bc0e708fedcddd7985c00243580464452 (patch) | |
tree | 6f9eb8b0537c75c3d68f1a9e0135870e6e0e7575 /internal/util/paging.go | |
parent | [chore]: Bump github.com/go-playground/validator/v10 (#1812) (diff) | |
download | gotosocial-c48abd8bc0e708fedcddd7985c00243580464452.tar.xz |
[chore] update account statuses paging logic (#1814)
Diffstat (limited to 'internal/util/paging.go')
-rw-r--r-- | internal/util/paging.go | 108 |
1 files changed, 64 insertions, 44 deletions
diff --git a/internal/util/paging.go b/internal/util/paging.go index 3d620ca1f..0ab4b9567 100644 --- a/internal/util/paging.go +++ b/internal/util/paging.go @@ -20,6 +20,7 @@ package util import ( "fmt" "net/url" + "strings" apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" "github.com/superseriousbusiness/gotosocial/internal/config" @@ -47,6 +48,13 @@ type PageableResponseParams struct { // a bunch of pageable items (notifications, statuses, etc), as well // as a Link header to inform callers of where to find next/prev items. func PackagePageableResponse(params PageableResponseParams) (*apimodel.PageableResponse, gtserror.WithCode) { + if len(params.Items) == 0 { + // No items to page through. + return EmptyPageableResponse(), nil + } + + // Set default paging values, if + // they weren't set by the caller. if params.NextMaxIDKey == "" { params.NextMaxIDKey = "max_id" } @@ -55,58 +63,70 @@ func PackagePageableResponse(params PageableResponseParams) (*apimodel.PageableR params.PrevMinIDKey = "min_id" } - pageableResponse := EmptyPageableResponse() + var ( + protocol = config.GetProtocol() + host = config.GetHost() + nextLink string + prevLink string + linkHeaderParts = make([]string, 0, 2) + ) - if len(params.Items) == 0 { - return pageableResponse, nil - } + // Parse next link. + if params.NextMaxIDValue != "" { + nextRaw := params.NextMaxIDKey + "=" + params.NextMaxIDValue - // items - pageableResponse.Items = params.Items + if params.Limit != 0 { + nextRaw = fmt.Sprintf("limit=%d&", params.Limit) + nextRaw + } - protocol := config.GetProtocol() - host := config.GetHost() + for _, p := range params.ExtraQueryParams { + nextRaw += "&" + p + } - // next - nextRaw := params.NextMaxIDKey + "=" + params.NextMaxIDValue - if params.Limit != 0 { - nextRaw = fmt.Sprintf("limit=%d&", params.Limit) + nextRaw - } - for _, p := range params.ExtraQueryParams { - nextRaw = nextRaw + "&" + p - } - nextLink := &url.URL{ - Scheme: protocol, - Host: host, - Path: params.Path, - RawQuery: nextRaw, - } - nextLinkString := nextLink.String() - pageableResponse.NextLink = nextLinkString + nextLink = func() string { + u := &url.URL{ + Scheme: protocol, + Host: host, + Path: params.Path, + RawQuery: nextRaw, + } + return u.String() + }() - // prev - prevRaw := params.PrevMinIDKey + "=" + params.PrevMinIDValue - if params.Limit != 0 { - prevRaw = fmt.Sprintf("limit=%d&", params.Limit) + prevRaw + linkHeaderParts = append(linkHeaderParts, `<`+nextLink+`>; rel="next"`) } - for _, p := range params.ExtraQueryParams { - prevRaw = prevRaw + "&" + p - } - prevLink := &url.URL{ - Scheme: protocol, - Host: host, - Path: params.Path, - RawQuery: prevRaw, - } - prevLinkString := prevLink.String() - pageableResponse.PrevLink = prevLinkString - // link header - next := fmt.Sprintf("<%s>; rel=\"next\"", nextLinkString) - prev := fmt.Sprintf("<%s>; rel=\"prev\"", prevLinkString) - pageableResponse.LinkHeader = next + ", " + prev + // Parse prev link. + if params.PrevMinIDValue != "" { + prevRaw := params.PrevMinIDKey + "=" + params.PrevMinIDValue + + if params.Limit != 0 { + prevRaw = fmt.Sprintf("limit=%d&", params.Limit) + prevRaw + } + + for _, p := range params.ExtraQueryParams { + prevRaw = prevRaw + "&" + p + } - return pageableResponse, nil + prevLink = func() string { + u := &url.URL{ + Scheme: protocol, + Host: host, + Path: params.Path, + RawQuery: prevRaw, + } + return u.String() + }() + + linkHeaderParts = append(linkHeaderParts, `<`+prevLink+`>; rel="prev"`) + } + + return &apimodel.PageableResponse{ + Items: params.Items, + LinkHeader: strings.Join(linkHeaderParts, ", "), + NextLink: nextLink, + PrevLink: prevLink, + }, nil } // EmptyPageableResponse just returns an empty |