MM-31712 Server/API: Unreads-only filter for GetUserThreads (#16660)

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Eli Yukelzon
2021-01-31 11:54:35 +02:00
коммит произвёл GitHub
родитель c38dd22261
Коммит bb7e5b6e9d
5 изменённых файлов: 36 добавлений и 5 удалений

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

@@ -2857,6 +2857,7 @@ func getThreadsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
Since: 0, Since: 0,
Page: 0, Page: 0,
PageSize: 30, PageSize: 30,
Unread: false,
Extended: false, Extended: false,
Deleted: false, Deleted: false,
} }
@@ -2892,9 +2893,11 @@ func getThreadsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
} }
deletedStr := r.URL.Query().Get("deleted") deletedStr := r.URL.Query().Get("deleted")
unreadStr := r.URL.Query().Get("unread")
extendedStr := r.URL.Query().Get("extended") extendedStr := r.URL.Query().Get("extended")
options.Deleted, _ = strconv.ParseBool(deletedStr) options.Deleted, _ = strconv.ParseBool(deletedStr)
options.Unread, _ = strconv.ParseBool(unreadStr)
options.Extended, _ = strconv.ParseBool(extendedStr) options.Extended, _ = strconv.ParseBool(extendedStr)
threads, err := c.App.GetThreadsForUser(c.Params.UserId, c.Params.TeamId, options) threads, err := c.App.GetThreadsForUser(c.Params.UserId, c.Params.TeamId, options)

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

@@ -5618,8 +5618,22 @@ func TestMaintainUnreadRepliesInThread(t *testing.T) {
// reply count should be 0 // reply count should be 0
checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 0, 1, nil) checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 0, 1, nil)
// the other user should also have 2 // mark other user's read state
checkThreadListReplies(t, th, th.SystemAdminClient, th.SystemAdminUser.Id, 2, 1, nil) resp = th.SystemAdminClient.UpdateThreadReadForUser(th.SystemAdminUser.Id, th.BasicTeam.Id, rpost.Id, model.GetMillis())
CheckNoError(t, resp)
CheckOKStatus(t, resp)
// get unread only, should return nothing
checkThreadListReplies(t, th, th.SystemAdminClient, th.SystemAdminUser.Id, 0, 0, &model.GetUserThreadsOpts{Unread: true})
// restore unread to an old date
resp = th.SystemAdminClient.UpdateThreadReadForUser(th.SystemAdminUser.Id, th.BasicTeam.Id, rpost.Id, 123)
CheckNoError(t, resp)
CheckOKStatus(t, resp)
// should have 2 unread replies now
checkThreadListReplies(t, th, th.SystemAdminClient, th.SystemAdminUser.Id, 2, 1, &model.GetUserThreadsOpts{Unread: true})
} }
func TestThreadCounts(t *testing.T) { func TestThreadCounts(t *testing.T) {

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

@@ -5806,7 +5806,9 @@ func (c *Client4) GetUserThreads(userId, teamId string, options GetUserThreadsOp
if options.Deleted { if options.Deleted {
v.Set("deleted", "true") v.Set("deleted", "true")
} }
if options.Unread {
v.Set("unread", "true")
}
url := c.GetUserThreadsRoute(userId, teamId) url := c.GetUserThreadsRoute(userId, teamId)
if len(v) > 0 { if len(v) > 0 {
url += "?" + v.Encode() url += "?" + v.Encode()

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

@@ -48,6 +48,9 @@ type GetUserThreadsOpts struct {
// Since filters the threads based on their LastUpdateAt timestamp. // Since filters the threads based on their LastUpdateAt timestamp.
Since uint64 Since uint64
// Unread will make sure that only threads with unread replies are returned
Unread bool
} }
func (o *ThreadResponse) ToJson() string { func (o *ThreadResponse) ToJson() string {

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

@@ -153,13 +153,19 @@ func (s *SqlThreadStore) GetThreadsForUser(userId, teamId string, opts model.Get
close(totalUnreadThreadsChan) close(totalUnreadThreadsChan)
}() }()
go func() { go func() {
newFetchConditions := fetchConditions
if opts.Unread {
newFetchConditions = sq.And{newFetchConditions, sq.Expr("ThreadMemberships.LastViewed < Threads.LastReplyAt")}
}
threadsQuery, threadsQueryArgs, _ := s.getQueryBuilder(). threadsQuery, threadsQueryArgs, _ := s.getQueryBuilder().
Select("COUNT(ThreadMemberships.PostId)"). Select("COUNT(ThreadMemberships.PostId)").
LeftJoin("Threads ON Threads.PostId = ThreadMemberships.PostId"). LeftJoin("Threads ON Threads.PostId = ThreadMemberships.PostId").
LeftJoin("Channels ON Threads.ChannelId = Channels.Id"). LeftJoin("Channels ON Threads.ChannelId = Channels.Id").
LeftJoin("Posts ON Posts.Id = ThreadMemberships.PostId"). LeftJoin("Posts ON Posts.Id = ThreadMemberships.PostId").
From("ThreadMemberships"). From("ThreadMemberships").
Where(fetchConditions).ToSql() Where(newFetchConditions).ToSql()
totalCount, err := s.GetMaster().SelectInt(threadsQuery, threadsQueryArgs...) totalCount, err := s.GetMaster().SelectInt(threadsQuery, threadsQueryArgs...)
totalCountChan <- store.StoreResult{Data: totalCount, NErr: err} totalCountChan <- store.StoreResult{Data: totalCount, NErr: err}
@@ -180,7 +186,10 @@ func (s *SqlThreadStore) GetThreadsForUser(userId, teamId string, opts model.Get
go func() { go func() {
newFetchConditions := fetchConditions newFetchConditions := fetchConditions
if opts.Since > 0 { if opts.Since > 0 {
newFetchConditions = sq.And{newFetchConditions, sq.GtOrEq{"Threads.LastReplyAt": opts.Since}} newFetchConditions = sq.And{newFetchConditions, sq.GtOrEq{"ThreadMemberships.LastUpdated": opts.Since}}
}
if opts.Unread {
newFetchConditions = sq.And{newFetchConditions, sq.Expr("ThreadMemberships.LastViewed < Threads.LastReplyAt")}
} }
var threads []*JoinedThread var threads []*JoinedThread