MM-38164: Paginate the GetPostThread API (#19485)

We implement a cursor based pagination model
to page through the posts in a given thread.

The cursor is a combination of the post.CreateAt+
post.Id to differentiate multiple posts in a given
timestamp.

Some additional parameters like direction, fromPost,
fromCreateAt and perPage were introduced to implement
this.

```release-note
NONE
```
Этот коммит содержится в:
Agniva De Sarker
2022-03-24 12:51:41 +05:30
коммит произвёл GitHub
родитель ad5f57b161
Коммит c1f3827801
24 изменённых файлов: 470 добавлений и 112 удалений

Просмотреть файл

@@ -3748,6 +3748,49 @@ func (c *Client4) GetPostThread(postId string, etag string, collapsedThreads boo
return &list, BuildResponse(r), nil
}
// GetPostThreadWithOpts gets a post with all the other posts in the same thread.
func (c *Client4) GetPostThreadWithOpts(postID string, etag string, opts GetPostsOptions) (*PostList, *Response, error) {
urlVal := c.postRoute(postID) + "/thread"
values := url.Values{}
if opts.CollapsedThreads {
values.Set("collapsedThreads", "true")
}
if opts.CollapsedThreadsExtended {
values.Set("collapsedThreadsExtended", "true")
}
if opts.SkipFetchThreads {
values.Set("skipFetchThreads", "true")
}
if opts.PerPage != 0 {
values.Set("perPage", strconv.Itoa(opts.PerPage))
}
if opts.FromPost != "" {
values.Set("fromPost", opts.FromPost)
}
if opts.FromCreateAt != 0 {
values.Set("fromCreateAt", strconv.FormatInt(opts.FromCreateAt, 10))
}
if opts.Direction != "" {
values.Set("direction", opts.Direction)
}
urlVal += "?" + values.Encode()
r, err := c.DoAPIGet(urlVal, etag)
if err != nil {
return nil, BuildResponse(r), err
}
defer closeBody(r)
var list PostList
if r.StatusCode == http.StatusNotModified {
return &list, BuildResponse(r), nil
}
if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil {
return nil, nil, NewAppError("GetPostThread", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
}
return &list, BuildResponse(r), nil
}
// GetPostsForChannel gets a page of posts with an array for ordering for a channel.
func (c *Client4) GetPostsForChannel(channelId string, page, perPage int, etag string, collapsedThreads bool) (*PostList, *Response, error) {
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage)

Просмотреть файл

@@ -263,6 +263,9 @@ type GetPostsOptions struct {
SkipFetchThreads bool
CollapsedThreads bool
CollapsedThreadsExtended bool
FromPost string // PostId after which to send the items
FromCreateAt int64 // CreateAt after which to send the items
Direction string // Only accepts up|down. Indicates the order in which to send the items.
}
func (o *Post) Etag() string {

Просмотреть файл

@@ -14,6 +14,8 @@ type PostList struct {
Posts map[string]*Post `json:"posts"`
NextPostId string `json:"next_post_id"`
PrevPostId string `json:"prev_post_id"`
// HasNext indicates whether there are more items to be fetched or not.
HasNext bool `json:"has_next"`
}
func NewPostList() *PostList {
@@ -39,6 +41,7 @@ func (o *PostList) Clone() *PostList {
Posts: postsCopy,
NextPostId: o.NextPostId,
PrevPostId: o.PrevPostId,
HasNext: o.HasNext,
}
}