Files
mostlymatter/model/post_list.go
Agniva De Sarker c1f3827801 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
```
2022-03-24 12:51:41 +05:30

187 строки
3.4 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package model
import (
"encoding/json"
"io"
"sort"
)
type PostList struct {
Order []string `json:"order"`
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 {
return &PostList{
Order: make([]string, 0),
Posts: make(map[string]*Post),
NextPostId: "",
PrevPostId: "",
}
}
func (o *PostList) Clone() *PostList {
orderCopy := make([]string, len(o.Order))
postsCopy := make(map[string]*Post)
for i, v := range o.Order {
orderCopy[i] = v
}
for k, v := range o.Posts {
postsCopy[k] = v.Clone()
}
return &PostList{
Order: orderCopy,
Posts: postsCopy,
NextPostId: o.NextPostId,
PrevPostId: o.PrevPostId,
HasNext: o.HasNext,
}
}
func (o *PostList) ToSlice() []*Post {
var posts []*Post
if l := len(o.Posts); l > 0 {
posts = make([]*Post, 0, l)
}
for _, id := range o.Order {
posts = append(posts, o.Posts[id])
}
return posts
}
func (o *PostList) WithRewrittenImageURLs(f func(string) string) *PostList {
copy := *o
copy.Posts = make(map[string]*Post)
for id, post := range o.Posts {
copy.Posts[id] = post.WithRewrittenImageURLs(f)
}
return &copy
}
func (o *PostList) StripActionIntegrations() {
posts := o.Posts
o.Posts = make(map[string]*Post)
for id, post := range posts {
pcopy := post.Clone()
pcopy.StripActionIntegrations()
o.Posts[id] = pcopy
}
}
func (o *PostList) ToJSON() (string, error) {
copy := *o
copy.StripActionIntegrations()
b, err := json.Marshal(&copy)
return string(b), err
}
func (o *PostList) EncodeJSON(w io.Writer) error {
o.StripActionIntegrations()
return json.NewEncoder(w).Encode(o)
}
func (o *PostList) MakeNonNil() {
if o.Order == nil {
o.Order = make([]string, 0)
}
if o.Posts == nil {
o.Posts = make(map[string]*Post)
}
for _, v := range o.Posts {
v.MakeNonNil()
}
}
func (o *PostList) AddOrder(id string) {
if o.Order == nil {
o.Order = make([]string, 0, 128)
}
o.Order = append(o.Order, id)
}
func (o *PostList) AddPost(post *Post) {
if o.Posts == nil {
o.Posts = make(map[string]*Post)
}
o.Posts[post.Id] = post
}
func (o *PostList) UniqueOrder() {
keys := make(map[string]bool)
order := []string{}
for _, postId := range o.Order {
if _, value := keys[postId]; !value {
keys[postId] = true
order = append(order, postId)
}
}
o.Order = order
}
func (o *PostList) Extend(other *PostList) {
for postId := range other.Posts {
o.AddPost(other.Posts[postId])
}
for _, postId := range other.Order {
o.AddOrder(postId)
}
o.UniqueOrder()
}
func (o *PostList) SortByCreateAt() {
sort.Slice(o.Order, func(i, j int) bool {
return o.Posts[o.Order[i]].CreateAt > o.Posts[o.Order[j]].CreateAt
})
}
func (o *PostList) Etag() string {
id := "0"
var t int64 = 0
for _, v := range o.Posts {
if v.UpdateAt > t {
t = v.UpdateAt
id = v.Id
} else if v.UpdateAt == t && v.Id > id {
t = v.UpdateAt
id = v.Id
}
}
orderId := ""
if len(o.Order) > 0 {
orderId = o.Order[0]
}
return Etag(orderId, id, t)
}
func (o *PostList) IsChannelId(channelId string) bool {
for _, v := range o.Posts {
if v.ChannelId != channelId {
return false
}
}
return true
}