MM-31712 Server/API: Unreads-only filter for GetUserThreads (#16660)
Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
c38dd22261
Коммит
bb7e5b6e9d
@@ -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
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user