MM-11210 Add "GET /posts/unread" API to support landing on the last unread post (#11486)
* [MM-11210] Add API GET 'api/v4/channels/{channel_id:[A-Za-z0-9]+}/posts/unread' for scrolling overhaul (#9108)
* Add API GET 'api/v4/channels/{channel_id:[A-Za-z0-9]+}/posts/unread'
* add constants
* refactor GetPostSince and added more tests
* move constants to app package
* [MM-11528 && MM-11583] Add userId to in the "posts/unread" path and update test with time delay to fix intermittent failure (#9229)
* add userId to in the "posts/unread" path and update test with time delay to fix intermittent failure
* add limit before and after to query
* remove time delay on test and put pretermined value of Post.CreateAt
* Fix conflict
* [MM-11876] Add cursor to posts list such as next_post_id and previous_post_id (#9707)
* add cursor to posts list such as next_post_id and previous_post_id
add publish previous_post_id on WEBSOCKET_EVENT_POSTED and only get next or previous post IDs if necessary
revert change on adding previous_post_id in WEBSOCKET_EVENT_POSTED
add missing strings import
fix merge conflicts
* update per comment
* update per feedback
* corrected the logic in getting the next and previous post ID
* fix logic to determine next and post IDs, and rename function to have suffix of "Time"
* rearrange logics and add mote tests
* fix merge conflict
* fix missing message when using unread API (#10233)
* MM-15569 Fixes failing test on TestGetPostsForChannelAroundLastUnread (#11039)
* Fix missing posts when getting posts since
* revert changes to GetPostsSince
* migrate Post.GetPostAfterTime and Post.GetPostBeforeTime to sync by default
* revert change to cacheItem
* Fix post ID validation, build query on squirrel and only return post ID as necessary
Этот коммит содержится в:
коммит произвёл
Sudheer
родитель
f56a8f5a99
Коммит
b832985f1d
@@ -4,6 +4,7 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
@@ -334,7 +335,7 @@ func (s *SqlPostStore) InvalidateLastPostTimeCache(channelId string) {
|
||||
|
||||
func (s *SqlPostStore) GetEtag(channelId string, allowFromCache bool) string {
|
||||
if allowFromCache {
|
||||
if cacheItem, ok := s.lastPostTimeCache.Get(channelId); ok {
|
||||
if cacheItem, ok := s.lastPostTimeCache.Get(channelId); ok && cacheItem.(int64) > 0 {
|
||||
if s.metrics != nil {
|
||||
s.metrics.IncrementMemCacheHitCounter("Last Post Time")
|
||||
}
|
||||
@@ -661,6 +662,78 @@ func (s *SqlPostStore) getPostsAround(channelId string, postId string, limit int
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) GetPostIdBeforeTime(channelId string, time int64) (string, *model.AppError) {
|
||||
return s.getPostIdAroundTime(channelId, time, true)
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) GetPostIdAfterTime(channelId string, time int64) (string, *model.AppError) {
|
||||
return s.getPostIdAroundTime(channelId, time, false)
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) getPostIdAroundTime(channelId string, time int64, before bool) (string, *model.AppError) {
|
||||
var direction sq.Sqlizer
|
||||
var sort string
|
||||
if before {
|
||||
direction = sq.Lt{"CreateAt": time}
|
||||
sort = "DESC"
|
||||
} else {
|
||||
direction = sq.Gt{"CreateAt": time}
|
||||
sort = "ASC"
|
||||
}
|
||||
|
||||
query := s.getQueryBuilder().
|
||||
Select("Id").
|
||||
From("Posts").
|
||||
Where(sq.And{
|
||||
direction,
|
||||
sq.Eq{"ChannelId": channelId},
|
||||
sq.Eq{"DeleteAt": int(0)},
|
||||
}).
|
||||
OrderBy("CreateAt " + sort).
|
||||
Limit(1)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return "", model.NewAppError("SqlPostStore.getPostIdAroundTime", "store.sql_post.get_post_id_around.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
var postId string
|
||||
if err := s.GetMaster().SelectOne(&postId, queryString, args...); err != nil {
|
||||
if err != sql.ErrNoRows {
|
||||
return "", model.NewAppError("SqlPostStore.getPostIdAroundTime", "store.sql_post.get_post_id_around.app_error", nil, "channelId="+channelId+err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
return postId, nil
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) GetPostAfterTime(channelId string, time int64) (*model.Post, *model.AppError) {
|
||||
query := s.getQueryBuilder().
|
||||
Select("*").
|
||||
From("Posts").
|
||||
Where(sq.And{
|
||||
sq.Gt{"CreateAt": time},
|
||||
sq.Eq{"ChannelId": channelId},
|
||||
sq.Eq{"DeleteAt": int(0)},
|
||||
}).
|
||||
OrderBy("CreateAt ASC").
|
||||
Limit(1)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("SqlPostStore.GetPostAfterTime", "store.sql_post.get_post_after_time.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
var post *model.Post
|
||||
if err := s.GetMaster().SelectOne(&post, queryString, args...); err != nil {
|
||||
if err != sql.ErrNoRows {
|
||||
return nil, model.NewAppError("SqlPostStore.GetPostAfterTime", "store.sql_post.get_post_after_time.app_error", nil, "channelId="+channelId+err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
return post, nil
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) getRootPosts(channelId string, offset int, limit int) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
var posts []*model.Post
|
||||
|
||||
Ссылка в новой задаче
Block a user