MM-33708 - Add MentionCountRoot column to ChannelMembers (#17099)
* added new column for root-only mentions Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
3c21eef110
Коммит
480796a1df
@@ -320,6 +320,9 @@ jobs:
|
||||
mattermost/mattermost-build-server:20201119_golang-1.15.5 \
|
||||
bash -c "ulimit -n 8096; make ARGS='version' run-cli && make MM_SQLSETTINGS_DATASOURCE='postgres://mmuser:mostest@postgres:5432/latest?sslmode=disable&connect_timeout=10' ARGS='version' run-cli"
|
||||
|
||||
echo "Ignoring known mismatch: ChannelMembers.MentionCountRoot"
|
||||
docker-compose --no-ansi exec -T postgres sh -c 'exec echo "ALTER TABLE ChannelMembers DROP COLUMN MentionCountRoot;" | exec psql -U mmuser -d migrated'
|
||||
docker-compose --no-ansi exec -T postgres sh -c 'exec echo "ALTER TABLE ChannelMembers DROP COLUMN MentionCountRoot;" | exec psql -U mmuser -d latest'
|
||||
echo "Ignoring known mismatch: ChannelMembers.MsgCountRoot and Channels.TotalMsgCountRoot"
|
||||
docker-compose --no-ansi exec -T postgres sh -c 'exec echo "ALTER TABLE ChannelMembers DROP COLUMN MsgCountRoot;" | exec psql -U mmuser -d migrated'
|
||||
docker-compose --no-ansi exec -T postgres sh -c 'exec echo "ALTER TABLE ChannelMembers DROP COLUMN MsgCountRoot;" | exec psql -U mmuser -d latest'
|
||||
@@ -359,7 +362,9 @@ jobs:
|
||||
echo "Ignoring known MySQL mismatch: ChannelMembers.SchemeGuest"
|
||||
docker-compose --no-ansi exec -T mysql mysql -D migrated -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN SchemeGuest;"
|
||||
docker-compose --no-ansi exec -T mysql mysql -D latest -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN SchemeGuest;"
|
||||
echo "Ignoring known MySQL mismatch: ChannelMembers.MentionCountRoot"
|
||||
echo "Ignoring known MySQL mismatch: ChannelMembers.MentionCountRoot and MsgCountRoot"
|
||||
docker-compose --no-ansi exec -T mysql mysql -D migrated -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN MentionCountRoot;"
|
||||
docker-compose --no-ansi exec -T mysql mysql -D latest -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN MentionCountRoot;"
|
||||
docker-compose --no-ansi exec -T mysql mysql -D migrated -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN MsgCountRoot;"
|
||||
docker-compose --no-ansi exec -T mysql mysql -D latest -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN MsgCountRoot;"
|
||||
echo "Ignoring known MySQL mismatch: Channels.TotalMsgCountRoot"
|
||||
|
||||
@@ -2152,6 +2152,7 @@ func TestViewChannel(t *testing.T) {
|
||||
CheckNoError(t, resp)
|
||||
require.Equal(t, channel.TotalMsgCount, member.MsgCount, "should match message counts")
|
||||
require.Equal(t, int64(0), member.MentionCount, "should have no mentions")
|
||||
require.Equal(t, int64(0), member.MentionCountRoot, "should have no mentions")
|
||||
|
||||
_, resp = Client.ViewChannel("junk", view)
|
||||
CheckBadRequestStatus(t, resp)
|
||||
@@ -4064,3 +4065,43 @@ func TestMoveChannel(t *testing.T) {
|
||||
require.Equal(t, team2.Id, newChannel.TeamId)
|
||||
}, "Should be able to (force) move private channel by a member that is not member of target team")
|
||||
}
|
||||
|
||||
func TestRootMentionsCount(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
Client := th.Client
|
||||
user := th.BasicUser
|
||||
channel := th.BasicChannel
|
||||
|
||||
// initially, MentionCountRoot is 0 in the database
|
||||
channelMember, err := th.App.Srv().Store.Channel().GetMember(context.Background(), channel.Id, user.Id)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(0), channelMember.MentionCountRoot)
|
||||
require.Equal(t, int64(0), channelMember.MentionCount)
|
||||
|
||||
// mention the user in a root post
|
||||
post1, resp := th.SystemAdminClient.CreatePost(&model.Post{ChannelId: channel.Id, Message: "hey @" + user.Username})
|
||||
CheckNoError(t, resp)
|
||||
// mention the user in a reply post
|
||||
post2 := &model.Post{ChannelId: channel.Id, Message: "reply at @" + user.Username, RootId: post1.Id}
|
||||
_, resp = th.SystemAdminClient.CreatePost(post2)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
// this should perform lazy migration and populate the field
|
||||
channelUnread, resp := Client.GetChannelUnread(channel.Id, user.Id)
|
||||
CheckNoError(t, resp)
|
||||
// reply post is not counted, so we should have one root mention
|
||||
require.EqualValues(t, int64(1), channelUnread.MentionCountRoot)
|
||||
// regular count stays the same
|
||||
require.Equal(t, int64(2), channelUnread.MentionCount)
|
||||
// validate that DB is updated
|
||||
channelMember, err = th.App.Srv().Store.Channel().GetMember(context.Background(), channel.Id, user.Id)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, int64(1), channelMember.MentionCountRoot)
|
||||
|
||||
// validate that Team level counts are calculated
|
||||
counts, appErr := th.App.GetTeamUnread(channel.TeamId, user.Id)
|
||||
require.Nil(t, appErr)
|
||||
require.Equal(t, int64(1), counts.MentionCountRoot)
|
||||
require.Equal(t, int64(2), counts.MentionCount)
|
||||
}
|
||||
|
||||
21
api4/user.go
21
api4/user.go
@@ -94,7 +94,6 @@ func (api *API) InitUser() {
|
||||
|
||||
api.BaseRoutes.UserThreads.Handle("", api.ApiSessionRequired(getThreadsForUser)).Methods("GET")
|
||||
api.BaseRoutes.UserThreads.Handle("/read", api.ApiSessionRequired(updateReadStateAllThreadsByUser)).Methods("PUT")
|
||||
api.BaseRoutes.UserThreads.Handle("/mention_counts", api.ApiSessionRequired(getMentionCountsForAllThreadsByUser)).Methods("GET")
|
||||
|
||||
api.BaseRoutes.UserThread.Handle("", api.ApiSessionRequired(getThreadForUser)).Methods("GET")
|
||||
api.BaseRoutes.UserThread.Handle("/following", api.ApiSessionRequired(followThreadByUser)).Methods("PUT")
|
||||
@@ -2871,26 +2870,6 @@ func getThreadForUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(threads.ToJson()))
|
||||
}
|
||||
|
||||
func getMentionCountsForAllThreadsByUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireUserId().RequireTeamId()
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) {
|
||||
c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
|
||||
return
|
||||
}
|
||||
counts, err := c.App.GetThreadMentionsForUserPerChannel(c.Params.UserId, c.Params.TeamId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
resp, _ := json.Marshal(counts)
|
||||
|
||||
w.Write(resp)
|
||||
}
|
||||
|
||||
func getThreadsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireUserId().RequireTeamId()
|
||||
if c.Err != nil {
|
||||
|
||||
@@ -5840,11 +5840,6 @@ func TestMaintainUnreadMentionsInThread(t *testing.T) {
|
||||
*cfg.ServiceSettings.ThreadAutoFollow = true
|
||||
*cfg.ServiceSettings.CollapsedThreads = model.COLLAPSED_THREADS_DEFAULT_ON
|
||||
})
|
||||
checkMentionCounts := func(client *model.Client4, userId string, expected map[string]int64) {
|
||||
actual, resp2 := client.GetThreadMentionsForUserPerChannel(userId, th.BasicTeam.Id)
|
||||
CheckNoError(t, resp2)
|
||||
require.EqualValues(t, expected, actual)
|
||||
}
|
||||
checkThreadList := func(client *model.Client4, userId string, expectedMentions, expectedThreads int) (*model.Threads, *model.Response) {
|
||||
uss, resp := client.GetUserThreads(userId, th.BasicTeam.Id, model.GetUserThreadsOpts{
|
||||
Deleted: false,
|
||||
@@ -5870,7 +5865,6 @@ func TestMaintainUnreadMentionsInThread(t *testing.T) {
|
||||
// create reply and mention the original poster and another user
|
||||
postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply @" + th.BasicUser.Username + " and @" + th.BasicUser2.Username, RootId: rpost.Id})
|
||||
|
||||
checkMentionCounts(Client, th.BasicUser.Id, map[string]int64{th.BasicChannel.Id: 1})
|
||||
// basic user 1 was mentioned 1 time
|
||||
checkThreadList(th.Client, th.BasicUser.Id, 1, 1)
|
||||
// basic user 2 was mentioned 1 time
|
||||
@@ -5899,7 +5893,6 @@ func TestMaintainUnreadMentionsInThread(t *testing.T) {
|
||||
postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: dm.Id, Message: "msg2", RootId: dm_root_post.Id})
|
||||
// expect increment by two mentions
|
||||
checkThreadList(th.Client, th.BasicUser.Id, 3, 2)
|
||||
checkMentionCounts(Client, th.BasicUser.Id, map[string]int64{th.BasicChannel.Id: 1, dm.Id: 2})
|
||||
}
|
||||
|
||||
func TestReadThreads(t *testing.T) {
|
||||
|
||||
@@ -704,7 +704,6 @@ type AppIface interface {
|
||||
GetTermsOfService(id string) (*model.TermsOfService, *model.AppError)
|
||||
GetThreadForUser(userID, teamID, threadId string, extended bool) (*model.ThreadResponse, *model.AppError)
|
||||
GetThreadMembershipsForUser(userID, teamID string) ([]*model.ThreadMembership, error)
|
||||
GetThreadMentionsForUserPerChannel(userId, teamId string) (map[string]int64, *model.AppError)
|
||||
GetThreadsForUser(userID, teamID string, options model.GetUserThreadsOpts) (*model.Threads, *model.AppError)
|
||||
GetUploadSession(uploadId string) (*model.UploadSession, *model.AppError)
|
||||
GetUploadSessionsForUser(userID string) ([]*model.UploadSession, *model.AppError)
|
||||
|
||||
@@ -1873,7 +1873,6 @@ func (a *App) GetChannelUnread(channelID, userID string) (*model.ChannelUnread,
|
||||
channelUnread.MsgCount = 0
|
||||
channelUnread.MsgCountRoot = 0
|
||||
}
|
||||
|
||||
return channelUnread, nil
|
||||
}
|
||||
|
||||
@@ -2340,7 +2339,7 @@ func (a *App) MarkChannelAsUnreadFromPost(postID string, userID string) (*model.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unreadMentions, err := a.countMentionsFromPost(user, post)
|
||||
unreadMentions, unreadMentionsRoot, err := a.countMentionsFromPost(user, post)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2382,7 +2381,7 @@ func (a *App) MarkChannelAsUnreadFromPost(postID string, userID string) (*model.
|
||||
}
|
||||
}
|
||||
|
||||
channelUnread, nErr := a.Srv().Store.Channel().UpdateLastViewedAtPost(post, userID, unreadMentions, *a.Config().ServiceSettings.ThreadAutoFollow)
|
||||
channelUnread, nErr := a.Srv().Store.Channel().UpdateLastViewedAtPost(post, userID, unreadMentions, unreadMentionsRoot, *a.Config().ServiceSettings.ThreadAutoFollow)
|
||||
if nErr != nil {
|
||||
return channelUnread, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
@@ -2390,6 +2389,7 @@ func (a *App) MarkChannelAsUnreadFromPost(postID string, userID string) (*model.
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_POST_UNREAD, channelUnread.TeamId, channelUnread.ChannelId, channelUnread.UserId, nil)
|
||||
message.Add("msg_count", channelUnread.MsgCount)
|
||||
message.Add("mention_count", channelUnread.MentionCount)
|
||||
message.Add("mention_count_root", channelUnread.MentionCountRoot)
|
||||
message.Add("last_viewed_at", channelUnread.LastViewedAt)
|
||||
message.Add("post_id", postID)
|
||||
a.Publish(message)
|
||||
|
||||
@@ -1343,15 +1343,24 @@ func TestMarkChannelAsUnreadFromPost(t *testing.T) {
|
||||
require.Nil(t, err)
|
||||
th.CreatePost(c2)
|
||||
|
||||
th.App.CreatePost(&model.Post{
|
||||
UserId: u2.Id,
|
||||
ChannelId: c2.Id,
|
||||
RootId: p4.Id,
|
||||
Message: "@" + u1.Username,
|
||||
}, c2, false, true)
|
||||
|
||||
response, err := th.App.MarkChannelAsUnreadFromPost(p4.Id, u1.Id)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(1), response.MsgCount)
|
||||
assert.Equal(t, int64(1), response.MentionCount)
|
||||
assert.Equal(t, int64(2), response.MentionCount)
|
||||
assert.Equal(t, int64(1), response.MentionCountRoot)
|
||||
|
||||
unread, err := th.App.GetChannelUnread(c2.Id, u1.Id)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, int64(1), unread.MsgCount)
|
||||
assert.Equal(t, int64(1), unread.MentionCount)
|
||||
assert.Equal(t, int64(2), unread.MsgCount)
|
||||
assert.Equal(t, int64(2), unread.MentionCount)
|
||||
assert.Equal(t, int64(1), unread.MentionCountRoot)
|
||||
})
|
||||
|
||||
t.Run("Unread on a DM channel", func(t *testing.T) {
|
||||
@@ -1361,15 +1370,20 @@ func TestMarkChannelAsUnreadFromPost(t *testing.T) {
|
||||
th.CreatePost(dc)
|
||||
th.CreatePost(dc)
|
||||
|
||||
_, err := th.App.CreatePost(&model.Post{ChannelId: dc.Id, UserId: th.BasicUser.Id, Message: "testReply", RootId: dm1.Id}, dc, false, false)
|
||||
assert.Nil(t, err)
|
||||
|
||||
response, err := th.App.MarkChannelAsUnreadFromPost(dm1.Id, u2.Id)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(0), response.MsgCount)
|
||||
assert.Equal(t, int64(3), response.MentionCount)
|
||||
assert.Equal(t, int64(4), response.MentionCount)
|
||||
assert.Equal(t, int64(3), response.MentionCountRoot)
|
||||
|
||||
unread, err := th.App.GetChannelUnread(dc.Id, u2.Id)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, int64(3), unread.MsgCount)
|
||||
assert.Equal(t, int64(3), unread.MentionCount)
|
||||
assert.Equal(t, int64(4), unread.MsgCount)
|
||||
assert.Equal(t, int64(4), unread.MentionCount)
|
||||
assert.Equal(t, int64(3), unread.MentionCountRoot)
|
||||
})
|
||||
|
||||
t.Run("Can't unread an imaginary post", func(t *testing.T) {
|
||||
|
||||
@@ -201,7 +201,7 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
||||
umc := make(chan *model.AppError, 1)
|
||||
go func(userID string) {
|
||||
defer close(umc)
|
||||
nErr := a.Srv().Store.Channel().IncrementMentionCount(post.ChannelId, userID, *a.Config().ServiceSettings.ThreadAutoFollow)
|
||||
nErr := a.Srv().Store.Channel().IncrementMentionCount(post.ChannelId, userID, *a.Config().ServiceSettings.ThreadAutoFollow, post.RootId == "")
|
||||
if nErr != nil {
|
||||
umc <- model.NewAppError("SendNotifications", "app.channel.increment_mention_count.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
||||
@@ -8650,28 +8650,6 @@ func (a *OpenTracingAppLayer) GetThreadMembershipsForUser(userID string, teamID
|
||||
return resultVar0, resultVar1
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) GetThreadMentionsForUserPerChannel(userId string, teamId string) (map[string]int64, *model.AppError) {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetThreadMentionsForUserPerChannel")
|
||||
|
||||
a.ctx = newCtx
|
||||
a.app.Srv().Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
a.app.Srv().Store.SetContext(origCtx)
|
||||
a.ctx = origCtx
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
resultVar0, resultVar1 := a.app.GetThreadMentionsForUserPerChannel(userId, teamId)
|
||||
|
||||
if resultVar1 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar1))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return resultVar0, resultVar1
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) GetThreadsForUser(userID string, teamID string, options model.GetUserThreadsOpts) (*model.Threads, *model.AppError) {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetThreadsForUser")
|
||||
|
||||
26
app/post.go
26
app/post.go
@@ -1403,25 +1403,25 @@ func (a *App) countThreadMentions(user *model.User, post *model.Post, teamID str
|
||||
|
||||
// countMentionsFromPost returns the number of posts in the post's channel that mention the user after and including the
|
||||
// given post.
|
||||
func (a *App) countMentionsFromPost(user *model.User, post *model.Post) (int, *model.AppError) {
|
||||
func (a *App) countMentionsFromPost(user *model.User, post *model.Post) (int, int, *model.AppError) {
|
||||
channel, err := a.GetChannel(post.ChannelId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
if channel.Type == model.CHANNEL_DIRECT {
|
||||
// In a DM channel, every post made by the other user is a mention
|
||||
count, _, nErr := a.Srv().Store.Channel().CountPostsAfter(post.ChannelId, post.CreateAt-1, channel.GetOtherUserIdForDM(user.Id))
|
||||
count, countRoot, nErr := a.Srv().Store.Channel().CountPostsAfter(post.ChannelId, post.CreateAt-1, channel.GetOtherUserIdForDM(user.Id))
|
||||
if nErr != nil {
|
||||
return 0, model.NewAppError("countMentionsFromPost", "app.channel.count_posts_since.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
return 0, 0, model.NewAppError("countMentionsFromPost", "app.channel.count_posts_since.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
return count, countRoot, nil
|
||||
}
|
||||
|
||||
channelMember, err := a.GetChannelMember(context.Background(), channel.Id, user.Id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
keywords := addMentionKeywordsForUser(
|
||||
@@ -1439,13 +1439,16 @@ func (a *App) countMentionsFromPost(user *model.User, post *model.Post) (int, *m
|
||||
|
||||
thread, err := a.GetPostThread(post.Id, false, false, false, user.Id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
count := 0
|
||||
|
||||
countRoot := 0
|
||||
if isPostMention(user, post, keywords, thread.Posts, mentionedByThread, checkForCommentMentions) {
|
||||
count += 1
|
||||
if post.RootId == "" {
|
||||
countRoot += 1
|
||||
}
|
||||
}
|
||||
|
||||
page := 0
|
||||
@@ -1458,12 +1461,15 @@ func (a *App) countMentionsFromPost(user *model.User, post *model.Post) (int, *m
|
||||
PerPage: perPage,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
for _, postID := range postList.Order {
|
||||
if isPostMention(user, postList.Posts[postID], keywords, postList.Posts, mentionedByThread, checkForCommentMentions) {
|
||||
count += 1
|
||||
if postList.Posts[postID].RootId == "" {
|
||||
countRoot += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1474,7 +1480,7 @@ func (a *App) countMentionsFromPost(user *model.User, post *model.Post) (int, *m
|
||||
page += 1
|
||||
}
|
||||
|
||||
return count, nil
|
||||
return count, countRoot, nil
|
||||
}
|
||||
|
||||
func isCommentMention(user *model.User, post *model.Post, otherPosts map[string]*model.Post, mentionedByThread map[string]bool) bool {
|
||||
|
||||
@@ -1231,7 +1231,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
}, channel, false, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, count)
|
||||
@@ -1270,7 +1270,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
|
||||
// post1 and post3 should mention the user
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, count)
|
||||
@@ -1309,7 +1309,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
|
||||
// post2 and post3 should mention the user
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, count)
|
||||
@@ -1346,7 +1346,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
}, channel, false, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, count)
|
||||
@@ -1388,7 +1388,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
}, channel, false, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, count)
|
||||
@@ -1442,7 +1442,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
|
||||
// post2 should mention the user
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, count)
|
||||
@@ -1496,7 +1496,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
|
||||
// post2 and post5 should mention the user
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, count)
|
||||
@@ -1545,7 +1545,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
|
||||
// should be mentioned by post2 and post3
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, count)
|
||||
@@ -1575,12 +1575,12 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
}, channel, false, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, count)
|
||||
|
||||
count, err = th.App.countMentionsFromPost(user1, post1)
|
||||
count, _, err = th.App.countMentionsFromPost(user1, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, count)
|
||||
@@ -1617,7 +1617,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
|
||||
// post1 and post3 should mention the user, but we only count post3
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post2)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post2)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, count)
|
||||
@@ -1648,7 +1648,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
|
||||
// post2 should mention the user
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, count)
|
||||
@@ -1695,7 +1695,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
|
||||
// post4 should mention the user
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post3)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post3)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, count)
|
||||
@@ -1735,7 +1735,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
|
||||
// post3 should mention the user
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, count)
|
||||
@@ -1771,7 +1771,7 @@ func TestCountMentionsFromPost(t *testing.T) {
|
||||
|
||||
// Every post should mention the user
|
||||
|
||||
count, err := th.App.countMentionsFromPost(user2, post1)
|
||||
count, _, err := th.App.countMentionsFromPost(user2, post1)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, numPosts, count)
|
||||
|
||||
21
app/team.go
21
app/team.go
@@ -1139,14 +1139,15 @@ func (a *App) GetTeamUnread(teamID, userID string) (*model.TeamUnread, *model.Ap
|
||||
}
|
||||
|
||||
var teamUnread = &model.TeamUnread{
|
||||
MsgCount: 0,
|
||||
MsgCountRoot: 0,
|
||||
MentionCount: 0,
|
||||
TeamId: teamID,
|
||||
MsgCount: 0,
|
||||
MentionCount: 0,
|
||||
MentionCountRoot: 0,
|
||||
MsgCountRoot: 0,
|
||||
TeamId: teamID,
|
||||
}
|
||||
|
||||
for _, cu := range channelUnreads {
|
||||
teamUnread.MentionCount += cu.MentionCount
|
||||
teamUnread.MentionCountRoot += cu.MentionCountRoot
|
||||
|
||||
if cu.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != model.CHANNEL_MARK_UNREAD_MENTION {
|
||||
teamUnread.MsgCount += cu.MsgCount
|
||||
@@ -1677,6 +1678,7 @@ func (a *App) GetTeamsUnreadForUser(excludeTeamId string, userID string) ([]*mod
|
||||
|
||||
unreads := func(cu *model.ChannelUnread, tu *model.TeamUnread) *model.TeamUnread {
|
||||
tu.MentionCount += cu.MentionCount
|
||||
tu.MentionCountRoot += cu.MentionCountRoot
|
||||
|
||||
if cu.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != model.CHANNEL_MARK_UNREAD_MENTION {
|
||||
tu.MsgCount += cu.MsgCount
|
||||
@@ -1692,10 +1694,11 @@ func (a *App) GetTeamsUnreadForUser(excludeTeamId string, userID string) ([]*mod
|
||||
membersMap[id] = unreads(data[i], mu)
|
||||
} else {
|
||||
membersMap[id] = unreads(data[i], &model.TeamUnread{
|
||||
MsgCount: 0,
|
||||
MsgCountRoot: 0,
|
||||
MentionCount: 0,
|
||||
TeamId: id,
|
||||
MsgCount: 0,
|
||||
MentionCount: 0,
|
||||
MentionCountRoot: 0,
|
||||
MsgCountRoot: 0,
|
||||
TeamId: id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2401,14 +2401,6 @@ func (a *App) GetThreadsForUser(userID, teamID string, options model.GetUserThre
|
||||
return threads, nil
|
||||
}
|
||||
|
||||
func (a *App) GetThreadMentionsForUserPerChannel(userId, teamId string) (map[string]int64, *model.AppError) {
|
||||
res, err := a.Srv().Store.Thread().GetThreadMentionsForUserPerChannel(userId, teamId)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("GetThreadMentionsForUserPerChannel", "app.user.get_threads_for_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a *App) GetThreadForUser(userID, teamID, threadId string, extended bool) (*model.ThreadResponse, *model.AppError) {
|
||||
thread, err := a.Srv().Store.Thread().GetThreadForUser(userID, teamID, threadId, extended)
|
||||
if err != nil {
|
||||
|
||||
@@ -24,39 +24,42 @@ const (
|
||||
)
|
||||
|
||||
type ChannelUnread struct {
|
||||
TeamId string `json:"team_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MsgCountRoot int64 `json:"msg_count_root"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
NotifyProps StringMap `json:"-"`
|
||||
TeamId string `json:"team_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
MentionCountRoot int64 `json:"mention_count_root"`
|
||||
MsgCountRoot int64 `json:"msg_count_root"`
|
||||
NotifyProps StringMap `json:"-"`
|
||||
}
|
||||
|
||||
type ChannelUnreadAt struct {
|
||||
TeamId string `json:"team_id"`
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MsgCountRoot int64 `json:"msg_count_root"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
LastViewedAt int64 `json:"last_viewed_at"`
|
||||
NotifyProps StringMap `json:"-"`
|
||||
TeamId string `json:"team_id"`
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
MentionCountRoot int64 `json:"mention_count_root"`
|
||||
MsgCountRoot int64 `json:"msg_count_root"`
|
||||
LastViewedAt int64 `json:"last_viewed_at"`
|
||||
NotifyProps StringMap `json:"-"`
|
||||
}
|
||||
|
||||
type ChannelMember struct {
|
||||
ChannelId string `json:"channel_id"`
|
||||
UserId string `json:"user_id"`
|
||||
Roles string `json:"roles"`
|
||||
LastViewedAt int64 `json:"last_viewed_at"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
NotifyProps StringMap `json:"notify_props"`
|
||||
LastUpdateAt int64 `json:"last_update_at"`
|
||||
SchemeGuest bool `json:"scheme_guest"`
|
||||
SchemeUser bool `json:"scheme_user"`
|
||||
SchemeAdmin bool `json:"scheme_admin"`
|
||||
ExplicitRoles string `json:"explicit_roles"`
|
||||
MsgCountRoot int64 `json:"msg_count_root"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
UserId string `json:"user_id"`
|
||||
Roles string `json:"roles"`
|
||||
LastViewedAt int64 `json:"last_viewed_at"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
MentionCountRoot int64 `json:"mention_count_root"`
|
||||
MsgCountRoot int64 `json:"msg_count_root"`
|
||||
NotifyProps StringMap `json:"notify_props"`
|
||||
LastUpdateAt int64 `json:"last_update_at"`
|
||||
SchemeGuest bool `json:"scheme_guest"`
|
||||
SchemeUser bool `json:"scheme_user"`
|
||||
SchemeAdmin bool `json:"scheme_admin"`
|
||||
ExplicitRoles string `json:"explicit_roles"`
|
||||
}
|
||||
|
||||
type ChannelMembers []ChannelMember
|
||||
|
||||
@@ -5885,20 +5885,6 @@ func (c *Client4) DownloadExport(name string, wr io.Writer, offset int64) (int64
|
||||
return n, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) GetThreadMentionsForUserPerChannel(userId, teamId string) (map[string]int64, *Response) {
|
||||
url := c.GetUserThreadsRoute(userId, teamId)
|
||||
r, appErr := c.DoApiGet(url+"/mention_counts", "")
|
||||
if appErr != nil {
|
||||
return nil, BuildErrorResponse(r, appErr)
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
var counts map[string]int64
|
||||
json.NewDecoder(r.Body).Decode(&counts)
|
||||
|
||||
return counts, BuildResponse(r)
|
||||
}
|
||||
|
||||
func (c *Client4) GetUserThreads(userId, teamId string, options GetUserThreadsOpts) (*Threads, *Response) {
|
||||
v := url.Values{}
|
||||
if options.Since != 0 {
|
||||
|
||||
@@ -31,10 +31,11 @@ type TeamMember struct {
|
||||
|
||||
//msgp:ignore TeamUnread
|
||||
type TeamUnread struct {
|
||||
TeamId string `json:"team_id"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MsgCountRoot int64 `json:"msg_count_root"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
TeamId string `json:"team_id"`
|
||||
MsgCount int64 `json:"msg_count"`
|
||||
MentionCount int64 `json:"mention_count"`
|
||||
MentionCountRoot int64 `json:"mention_count_root"`
|
||||
MsgCountRoot int64 `json:"msg_count_root"`
|
||||
}
|
||||
|
||||
//msgp:ignore TeamMemberForExport
|
||||
|
||||
@@ -22,7 +22,7 @@ make ARGS="config set SqlSettings.DataSource 'mmuser:mostest@tcp(localhost:3306)
|
||||
echo "Setting up fresh db"
|
||||
make ARGS="version --config $TMPDIR/config.json" run-cli
|
||||
|
||||
for i in "ChannelMembers SchemeGuest" "ChannelMembers MsgCountRoot" "Channels TotalMsgCountRoot"; do
|
||||
for i in "ChannelMembers SchemeGuest" "ChannelMembers MsgCountRoot" "ChannelMembers MentionCountRoot" "Channels TotalMsgCountRoot"; do
|
||||
a=( $i );
|
||||
echo "Ignoring known MySQL mismatch: ${a[0]}.${a[1]}"
|
||||
docker exec mattermost-mysql mysql -D migrated -uroot -pmostest -e "ALTER TABLE ${a[0]} DROP COLUMN ${a[1]};"
|
||||
|
||||
@@ -22,7 +22,7 @@ make ARGS="config set SqlSettings.DataSource 'postgres://mmuser:mostest@localhos
|
||||
echo "Setting up fresh db"
|
||||
make ARGS="version --config $TMPDIR/config.json" run-cli
|
||||
|
||||
for i in "ChannelMembers MsgCountRoot" "Channels TotalMsgCountRoot"; do
|
||||
for i in "ChannelMembers MentionCountRoot" "ChannelMembers MsgCountRoot" "Channels TotalMsgCountRoot"; do
|
||||
a=( $i );
|
||||
echo "Ignoring known Postgres mismatch: ${a[0]}.${a[1]}"
|
||||
docker exec mattermost-postgres psql -U mmuser -d migrated -c "ALTER TABLE ${a[0]} DROP COLUMN ${a[1]};"
|
||||
|
||||
@@ -1556,7 +1556,7 @@ func (s *OpenTracingLayerChannelStore) GroupSyncedChannelCount() (int64, error)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerChannelStore) IncrementMentionCount(channelID string, userId string, updateThreads bool) error {
|
||||
func (s *OpenTracingLayerChannelStore) IncrementMentionCount(channelID string, userId string, updateThreads bool, isRoot bool) error {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.IncrementMentionCount")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
@@ -1565,7 +1565,7 @@ func (s *OpenTracingLayerChannelStore) IncrementMentionCount(channelID string, u
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
err := s.ChannelStore.IncrementMentionCount(channelID, userId, updateThreads)
|
||||
err := s.ChannelStore.IncrementMentionCount(channelID, userId, updateThreads, isRoot)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
@@ -2110,7 +2110,7 @@ func (s *OpenTracingLayerChannelStore) UpdateLastViewedAt(channelIds []string, u
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
func (s *OpenTracingLayerChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, mentionCountRoot int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.UpdateLastViewedAtPost")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
@@ -2119,7 +2119,7 @@ func (s *OpenTracingLayerChannelStore) UpdateLastViewedAtPost(unreadPost *model.
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.ChannelStore.UpdateLastViewedAtPost(unreadPost, userID, mentionCount, updateThreads)
|
||||
result, err := s.ChannelStore.UpdateLastViewedAtPost(unreadPost, userID, mentionCount, mentionCountRoot, updateThreads)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
@@ -7864,24 +7864,6 @@ func (s *OpenTracingLayerThreadStore) GetThreadForUser(userId string, teamId str
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerThreadStore) GetThreadMentionsForUserPerChannel(userId string, teamId string) (map[string]int64, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ThreadStore.GetThreadMentionsForUserPerChannel")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
s.Root.Store.SetContext(origCtx)
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.ThreadStore.GetThreadMentionsForUserPerChannel(userId, teamId)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerThreadStore) GetThreadsForUser(userId string, teamId string, opts model.GetUserThreadsOpts) (*model.Threads, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ThreadStore.GetThreadsForUser")
|
||||
|
||||
@@ -1690,11 +1690,11 @@ func (s *RetryLayerChannelStore) GroupSyncedChannelCount() (int64, error) {
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerChannelStore) IncrementMentionCount(channelID string, userId string, updateThreads bool) error {
|
||||
func (s *RetryLayerChannelStore) IncrementMentionCount(channelID string, userId string, updateThreads bool, isRoot bool) error {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
err := s.ChannelStore.IncrementMentionCount(channelID, userId, updateThreads)
|
||||
err := s.ChannelStore.IncrementMentionCount(channelID, userId, updateThreads, isRoot)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -2238,11 +2238,11 @@ func (s *RetryLayerChannelStore) UpdateLastViewedAt(channelIds []string, userId
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
func (s *RetryLayerChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, mentionCountRoot int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.ChannelStore.UpdateLastViewedAtPost(unreadPost, userID, mentionCount, updateThreads)
|
||||
result, err := s.ChannelStore.UpdateLastViewedAtPost(unreadPost, userID, mentionCount, mentionCountRoot, updateThreads)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
@@ -8538,26 +8538,6 @@ func (s *RetryLayerThreadStore) GetThreadForUser(userId string, teamId string, t
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerThreadStore) GetThreadMentionsForUserPerChannel(userId string, teamId string) (map[string]int64, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.ThreadStore.GetThreadMentionsForUserPerChannel(userId, teamId)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
if !isRepeatableError(err) {
|
||||
return result, err
|
||||
}
|
||||
tries++
|
||||
if tries >= 3 {
|
||||
err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures")
|
||||
return result, err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerThreadStore) GetThreadsForUser(userId string, teamId string, opts model.GetUserThreadsOpts) (*model.Threads, error) {
|
||||
|
||||
tries := 0
|
||||
|
||||
@@ -39,34 +39,36 @@ type SqlChannelStore struct {
|
||||
}
|
||||
|
||||
type channelMember struct {
|
||||
ChannelId string
|
||||
UserId string
|
||||
Roles string
|
||||
LastViewedAt int64
|
||||
MsgCount int64
|
||||
MentionCount int64
|
||||
NotifyProps model.StringMap
|
||||
LastUpdateAt int64
|
||||
SchemeUser sql.NullBool
|
||||
SchemeAdmin sql.NullBool
|
||||
SchemeGuest sql.NullBool
|
||||
MsgCountRoot int64
|
||||
ChannelId string
|
||||
UserId string
|
||||
Roles string
|
||||
LastViewedAt int64
|
||||
MsgCount int64
|
||||
MentionCount int64
|
||||
NotifyProps model.StringMap
|
||||
LastUpdateAt int64
|
||||
SchemeUser sql.NullBool
|
||||
SchemeAdmin sql.NullBool
|
||||
SchemeGuest sql.NullBool
|
||||
MentionCountRoot int64
|
||||
MsgCountRoot int64
|
||||
}
|
||||
|
||||
func NewChannelMemberFromModel(cm *model.ChannelMember) *channelMember {
|
||||
return &channelMember{
|
||||
ChannelId: cm.ChannelId,
|
||||
UserId: cm.UserId,
|
||||
Roles: cm.ExplicitRoles,
|
||||
LastViewedAt: cm.LastViewedAt,
|
||||
MsgCount: cm.MsgCount,
|
||||
MsgCountRoot: cm.MsgCountRoot,
|
||||
MentionCount: cm.MentionCount,
|
||||
NotifyProps: cm.NotifyProps,
|
||||
LastUpdateAt: cm.LastUpdateAt,
|
||||
SchemeGuest: sql.NullBool{Valid: true, Bool: cm.SchemeGuest},
|
||||
SchemeUser: sql.NullBool{Valid: true, Bool: cm.SchemeUser},
|
||||
SchemeAdmin: sql.NullBool{Valid: true, Bool: cm.SchemeAdmin},
|
||||
ChannelId: cm.ChannelId,
|
||||
UserId: cm.UserId,
|
||||
Roles: cm.ExplicitRoles,
|
||||
LastViewedAt: cm.LastViewedAt,
|
||||
MsgCount: cm.MsgCount,
|
||||
MentionCount: cm.MentionCount,
|
||||
MentionCountRoot: cm.MentionCountRoot,
|
||||
MsgCountRoot: cm.MsgCountRoot,
|
||||
NotifyProps: cm.NotifyProps,
|
||||
LastUpdateAt: cm.LastUpdateAt,
|
||||
SchemeGuest: sql.NullBool{Valid: true, Bool: cm.SchemeGuest},
|
||||
SchemeUser: sql.NullBool{Valid: true, Bool: cm.SchemeUser},
|
||||
SchemeAdmin: sql.NullBool{Valid: true, Bool: cm.SchemeAdmin},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +79,7 @@ type channelMemberWithSchemeRoles struct {
|
||||
LastViewedAt int64
|
||||
MsgCount int64
|
||||
MentionCount int64
|
||||
MentionCountRoot int64
|
||||
NotifyProps model.StringMap
|
||||
LastUpdateAt int64
|
||||
SchemeGuest sql.NullBool
|
||||
@@ -92,7 +95,7 @@ type channelMemberWithSchemeRoles struct {
|
||||
}
|
||||
|
||||
func channelMemberSliceColumns() []string {
|
||||
return []string{"ChannelId", "UserId", "Roles", "LastViewedAt", "MsgCount", "MsgCountRoot", "MentionCount", "NotifyProps", "LastUpdateAt", "SchemeUser", "SchemeAdmin", "SchemeGuest"}
|
||||
return []string{"ChannelId", "UserId", "Roles", "LastViewedAt", "MsgCount", "MsgCountRoot", "MentionCount", "MentionCountRoot", "NotifyProps", "LastUpdateAt", "SchemeUser", "SchemeAdmin", "SchemeGuest"}
|
||||
}
|
||||
|
||||
func channelMemberToSlice(member *model.ChannelMember) []interface{} {
|
||||
@@ -104,6 +107,7 @@ func channelMemberToSlice(member *model.ChannelMember) []interface{} {
|
||||
resultSlice = append(resultSlice, member.MsgCount)
|
||||
resultSlice = append(resultSlice, member.MsgCountRoot)
|
||||
resultSlice = append(resultSlice, member.MentionCount)
|
||||
resultSlice = append(resultSlice, member.MentionCountRoot)
|
||||
resultSlice = append(resultSlice, model.MapToJson(member.NotifyProps))
|
||||
resultSlice = append(resultSlice, member.LastUpdateAt)
|
||||
resultSlice = append(resultSlice, member.SchemeUser)
|
||||
@@ -229,19 +233,20 @@ func (db channelMemberWithSchemeRoles) ToModel() *model.ChannelMember {
|
||||
strings.Fields(db.Roles),
|
||||
)
|
||||
return &model.ChannelMember{
|
||||
ChannelId: db.ChannelId,
|
||||
UserId: db.UserId,
|
||||
Roles: strings.Join(rolesResult.roles, " "),
|
||||
LastViewedAt: db.LastViewedAt,
|
||||
MsgCount: db.MsgCount,
|
||||
MsgCountRoot: db.MsgCountRoot,
|
||||
MentionCount: db.MentionCount,
|
||||
NotifyProps: db.NotifyProps,
|
||||
LastUpdateAt: db.LastUpdateAt,
|
||||
SchemeAdmin: rolesResult.schemeAdmin,
|
||||
SchemeUser: rolesResult.schemeUser,
|
||||
SchemeGuest: rolesResult.schemeGuest,
|
||||
ExplicitRoles: strings.Join(rolesResult.explicitRoles, " "),
|
||||
ChannelId: db.ChannelId,
|
||||
UserId: db.UserId,
|
||||
Roles: strings.Join(rolesResult.roles, " "),
|
||||
LastViewedAt: db.LastViewedAt,
|
||||
MsgCount: db.MsgCount,
|
||||
MsgCountRoot: db.MsgCountRoot,
|
||||
MentionCount: db.MentionCount,
|
||||
MentionCountRoot: db.MentionCountRoot,
|
||||
NotifyProps: db.NotifyProps,
|
||||
LastUpdateAt: db.LastUpdateAt,
|
||||
SchemeAdmin: rolesResult.schemeAdmin,
|
||||
SchemeUser: rolesResult.schemeUser,
|
||||
SchemeGuest: rolesResult.schemeGuest,
|
||||
ExplicitRoles: strings.Join(rolesResult.explicitRoles, " "),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -717,10 +722,7 @@ func (s SqlChannelStore) GetChannelUnread(channelId, userId string) (*model.Chan
|
||||
var unreadChannel model.ChannelUnread
|
||||
err := s.GetReplica().SelectOne(&unreadChannel,
|
||||
`SELECT
|
||||
Channels.TeamId TeamId, Channels.Id ChannelId,
|
||||
(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount,
|
||||
(Channels.TotalMsgCountRoot - ChannelMembers.MsgCountRoot) MsgCountRoot,
|
||||
ChannelMembers.MentionCount MentionCount, ChannelMembers.NotifyProps NotifyProps
|
||||
Channels.TeamId TeamId, Channels.Id ChannelId, (Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount, (Channels.TotalMsgCountRoot - ChannelMembers.MsgCountRoot) MsgCountRoot, ChannelMembers.MentionCount MentionCount, ChannelMembers.MentionCountRoot MentionCountRoot, ChannelMembers.NotifyProps NotifyProps
|
||||
FROM
|
||||
Channels, ChannelMembers
|
||||
WHERE
|
||||
@@ -2086,6 +2088,7 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string,
|
||||
ChannelMembers cm
|
||||
SET
|
||||
MentionCount = 0,
|
||||
MentionCountRoot = 0,
|
||||
MsgCount = greatest(cm.MsgCount, c.TotalMsgCount),
|
||||
MsgCountRoot = greatest(cm.MsgCountRoot, c.TotalMsgCountRoot),
|
||||
LastViewedAt = greatest(cm.LastViewedAt, c.LastPostAt),
|
||||
@@ -2140,6 +2143,7 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string,
|
||||
ChannelMembers
|
||||
SET
|
||||
MentionCount = 0,
|
||||
MentionCountRoot = 0,
|
||||
MsgCount = CASE ChannelId ` + msgCountQuery + ` END,
|
||||
MsgCountRoot = CASE ChannelId ` + msgCountQueryRoot + ` END,
|
||||
LastViewedAt = CASE ChannelId ` + lastViewedQuery + ` END,
|
||||
@@ -2196,7 +2200,7 @@ func (s SqlChannelStore) CountPostsAfter(channelId string, timestamp int64, user
|
||||
// UpdateLastViewedAtPost updates a ChannelMember as if the user last read the channel at the time of the given post.
|
||||
// If the provided mentionCount is -1, the given post and all posts after it are considered to be mentions. Returns
|
||||
// an updated model.ChannelUnreadAt that can be returned to the client.
|
||||
func (s SqlChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
func (s SqlChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount, mentionCountRoot int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
var threadsToUpdate []string
|
||||
unreadDate := unreadPost.CreateAt - 1
|
||||
if updateThreads {
|
||||
@@ -2214,6 +2218,7 @@ func (s SqlChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID s
|
||||
|
||||
params := map[string]interface{}{
|
||||
"mentions": mentionCount,
|
||||
"mentionsRoot": mentionCountRoot,
|
||||
"unreadCount": unread,
|
||||
"unreadCountRoot": unreadRoot,
|
||||
"lastViewedAt": unreadDate,
|
||||
@@ -2229,6 +2234,7 @@ func (s SqlChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID s
|
||||
ChannelMembers
|
||||
SET
|
||||
MentionCount = :mentions,
|
||||
MentionCountRoot = :mentionsRoot,
|
||||
MsgCount = (SELECT TotalMsgCount FROM Channels WHERE ID = :channelId) - :unreadCount,
|
||||
MsgCountRoot = (SELECT TotalMsgCountRoot FROM Channels WHERE ID = :channelId) - :unreadCountRoot,
|
||||
LastViewedAt = :lastViewedAt,
|
||||
@@ -2250,6 +2256,7 @@ func (s SqlChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID s
|
||||
cm.MsgCount MsgCount,
|
||||
cm.MsgCountRoot MsgCountRoot,
|
||||
cm.MentionCount MentionCount,
|
||||
cm.MentionCountRoot MentionCountRoot,
|
||||
cm.LastViewedAt LastViewedAt,
|
||||
cm.NotifyProps NotifyProps
|
||||
FROM
|
||||
@@ -2271,7 +2278,7 @@ func (s SqlChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID s
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) IncrementMentionCount(channelId string, userId string, updateThreads bool) error {
|
||||
func (s SqlChannelStore) IncrementMentionCount(channelId string, userId string, updateThreads, isRoot bool) error {
|
||||
now := model.GetMillis()
|
||||
var threadsToUpdate []string
|
||||
if updateThreads {
|
||||
@@ -2281,17 +2288,21 @@ func (s SqlChannelStore) IncrementMentionCount(channelId string, userId string,
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
rootInc := 0
|
||||
if isRoot {
|
||||
rootInc = 1
|
||||
}
|
||||
_, err := s.GetMaster().Exec(
|
||||
`UPDATE
|
||||
ChannelMembers
|
||||
SET
|
||||
MentionCount = MentionCount + 1,
|
||||
MentionCountRoot = MentionCountRoot + :RootInc,
|
||||
LastUpdateAt = :LastUpdateAt
|
||||
WHERE
|
||||
UserId = :UserId
|
||||
AND ChannelId = :ChannelId`,
|
||||
map[string]interface{}{"ChannelId": channelId, "UserId": userId, "LastUpdateAt": now})
|
||||
AND ChannelId = :ChannelId`,
|
||||
map[string]interface{}{"ChannelId": channelId, "UserId": userId, "LastUpdateAt": now, "RootInc": rootInc})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to Update ChannelMembers with channelId=%s and userId=%s", channelId, userId)
|
||||
}
|
||||
@@ -3186,6 +3197,7 @@ func (s SqlChannelStore) GetChannelMembersForExport(userId string, teamId string
|
||||
ChannelMembers.LastViewedAt,
|
||||
ChannelMembers.MsgCount,
|
||||
ChannelMembers.MentionCount,
|
||||
ChannelMembers.MentionCountRoot,
|
||||
ChannelMembers.NotifyProps,
|
||||
ChannelMembers.LastUpdateAt,
|
||||
ChannelMembers.SchemeUser,
|
||||
@@ -3236,7 +3248,7 @@ func (s SqlChannelStore) GetAllDirectChannelsForExportAfter(limit int, afterId s
|
||||
channelIds = append(channelIds, channel.Id)
|
||||
}
|
||||
query = s.getQueryBuilder().
|
||||
Select("u.Username as Username, ChannelId, UserId, cm.Roles as Roles, LastViewedAt, MsgCount, MentionCount, cm.NotifyProps as NotifyProps, LastUpdateAt, SchemeUser, SchemeAdmin, (SchemeGuest IS NOT NULL AND SchemeGuest) as SchemeGuest").
|
||||
Select("u.Username as Username, ChannelId, UserId, cm.Roles as Roles, LastViewedAt, MsgCount, MentionCount, MentionCountRoot, cm.NotifyProps as NotifyProps, LastUpdateAt, SchemeUser, SchemeAdmin, (SchemeGuest IS NOT NULL AND SchemeGuest) as SchemeGuest").
|
||||
From("ChannelMembers cm").
|
||||
Join("Users u ON ( u.Id = cm.UserId )").
|
||||
Where(sq.And{
|
||||
|
||||
@@ -69,6 +69,7 @@ func testNewChannelMemberFromModel(t *testing.T) {
|
||||
assert.Equal(t, m.LastViewedAt, db.LastViewedAt)
|
||||
assert.Equal(t, m.MsgCount, db.MsgCount)
|
||||
assert.Equal(t, m.MentionCount, db.MentionCount)
|
||||
assert.Equal(t, int64(0), m.MentionCountRoot)
|
||||
assert.Equal(t, m.NotifyProps, db.NotifyProps)
|
||||
assert.Equal(t, m.LastUpdateAt, db.LastUpdateAt)
|
||||
assert.Equal(t, true, db.SchemeGuest.Valid)
|
||||
@@ -111,6 +112,7 @@ func testChannelMemberWithSchemeRolesToModel(t *testing.T) {
|
||||
assert.Equal(t, db.LastViewedAt, m.LastViewedAt)
|
||||
assert.Equal(t, db.MsgCount, m.MsgCount)
|
||||
assert.Equal(t, db.MentionCount, m.MentionCount)
|
||||
assert.Equal(t, db.MentionCountRoot, m.MentionCountRoot)
|
||||
assert.Equal(t, db.NotifyProps, m.NotifyProps)
|
||||
assert.Equal(t, db.LastUpdateAt, m.LastUpdateAt)
|
||||
assert.Equal(t, db.SchemeGuest.Bool, m.SchemeGuest)
|
||||
|
||||
@@ -919,6 +919,7 @@ func (s *SqlGroupStore) ChannelMembersToRemove(channelID *string) ([]*model.Chan
|
||||
"ChannelMembers.MsgCount",
|
||||
"ChannelMembers.MsgCountRoot",
|
||||
"ChannelMembers.MentionCount",
|
||||
"ChannelMembers.MentionCountRoot",
|
||||
"ChannelMembers.NotifyProps",
|
||||
"ChannelMembers.LastUpdateAt",
|
||||
"ChannelMembers.LastUpdateAt",
|
||||
|
||||
@@ -2030,7 +2030,7 @@ func (s *SqlPostStore) GetDirectPostParentsForExportAfter(limit int, afterId str
|
||||
channelIds = append(channelIds, post.ChannelId)
|
||||
}
|
||||
query = s.getQueryBuilder().
|
||||
Select("u.Username as Username, ChannelId, UserId, cm.Roles as Roles, LastViewedAt, MsgCount, MentionCount, cm.NotifyProps as NotifyProps, LastUpdateAt, SchemeUser, SchemeAdmin, (SchemeGuest IS NOT NULL AND SchemeGuest) as SchemeGuest").
|
||||
Select("u.Username as Username, ChannelId, UserId, cm.Roles as Roles, LastViewedAt, MsgCount, MentionCount, MentionCountRoot, cm.NotifyProps as NotifyProps, LastUpdateAt, SchemeUser, SchemeAdmin, (SchemeGuest IS NOT NULL AND SchemeGuest) as SchemeGuest").
|
||||
From("ChannelMembers cm").
|
||||
Join("Users u ON ( u.Id = cm.UserId )").
|
||||
Where(sq.Eq{
|
||||
|
||||
@@ -1177,7 +1177,7 @@ func (s SqlTeamStore) GetTeamsForUserWithPagination(userId string, page, perPage
|
||||
// for all the channels in all the teams except the excluded ones.
|
||||
func (s SqlTeamStore) GetChannelUnreadsForAllTeams(excludeTeamId, userId string) ([]*model.ChannelUnread, error) {
|
||||
query, args, err := s.getQueryBuilder().
|
||||
Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "(Channels.TotalMsgCountRoot - ChannelMembers.MsgCountRoot) MsgCountRoot", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.NotifyProps NotifyProps").
|
||||
Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "(Channels.TotalMsgCountRoot - ChannelMembers.MsgCountRoot) MsgCountRoot", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.MentionCountRoot MentionCountRoot", "ChannelMembers.NotifyProps NotifyProps").
|
||||
From("Channels").
|
||||
Join("ChannelMembers ON Id = ChannelId").
|
||||
Where(sq.Eq{"UserId": userId, "DeleteAt": 0}).
|
||||
@@ -1199,7 +1199,7 @@ func (s SqlTeamStore) GetChannelUnreadsForAllTeams(excludeTeamId, userId string)
|
||||
// GetChannelUnreadsForTeam returns unreads msg count, mention counts and notifyProps for all the channels in a single team.
|
||||
func (s SqlTeamStore) GetChannelUnreadsForTeam(teamId, userId string) ([]*model.ChannelUnread, error) {
|
||||
query, args, err := s.getQueryBuilder().
|
||||
Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "(Channels.TotalMsgCountRoot - ChannelMembers.MsgCountRoot) MsgCountRoot", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.NotifyProps NotifyProps").
|
||||
Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "(Channels.TotalMsgCountRoot - ChannelMembers.MsgCountRoot) MsgCountRoot", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.MentionCountRoot MentionCountRoot", "ChannelMembers.NotifyProps NotifyProps").
|
||||
From("Channels").
|
||||
Join("ChannelMembers ON Id = ChannelId").
|
||||
Where(sq.Eq{"UserId": userId, "TeamId": teamId, "DeleteAt": 0}).ToSql()
|
||||
|
||||
@@ -109,35 +109,6 @@ func (s *SqlThreadStore) Get(id string) (*model.Thread, error) {
|
||||
return &thread, nil
|
||||
}
|
||||
|
||||
func (s *SqlThreadStore) GetThreadMentionsForUserPerChannel(userId, teamId string) (map[string]int64, error) {
|
||||
type Count struct {
|
||||
UnreadMentions int64
|
||||
ChannelId string
|
||||
}
|
||||
var counts []Count
|
||||
|
||||
sql, args, _ := s.getQueryBuilder().
|
||||
Select("SUM(UnreadMentions) as UnreadMentions", "ChannelId").
|
||||
From("ThreadMemberships").
|
||||
LeftJoin("Threads ON Threads.PostId = ThreadMemberships.PostId").
|
||||
LeftJoin("Channels ON Threads.ChannelId = Channels.Id").
|
||||
Where(sq.And{
|
||||
sq.Or{sq.Eq{"Channels.TeamId": teamId}, sq.Eq{"Channels.TeamId": ""}},
|
||||
sq.Eq{"ThreadMemberships.UserId": userId},
|
||||
sq.Eq{"ThreadMemberships.Following": true},
|
||||
}).
|
||||
GroupBy("Threads.ChannelId").ToSql()
|
||||
|
||||
if _, err := s.GetMaster().Select(&counts, sql, args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := map[string]int64{}
|
||||
for _, count := range counts {
|
||||
result[count.ChannelId] = count.UnreadMentions
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *SqlThreadStore) GetThreadsForUser(userId, teamId string, opts model.GetUserThreadsOpts) (*model.Threads, error) {
|
||||
type JoinedThread struct {
|
||||
PostId string
|
||||
|
||||
@@ -1011,6 +1011,38 @@ func upgradeDatabaseToVersion535(sqlStore *SqlStore) {
|
||||
|
||||
sqlStore.CreateColumnIfNotExists("SidebarCategories", "Collapsed", "tinyint(1)", "boolean", "0")
|
||||
|
||||
// note: setting default 0 on pre-5.0 tables causes test-db-migration script to fail, so this column will be added to ignore list
|
||||
sqlStore.CreateColumnIfNotExists("ChannelMembers", "MentionCountRoot", "bigint", "bigint", "0")
|
||||
sqlStore.AlterColumnDefaultIfExists("ChannelMembers", "MentionCountRoot", model.NewString("0"), model.NewString("0"))
|
||||
|
||||
mentionCountRootCTE := `
|
||||
SELECT ChannelId, COALESCE(SUM(UnreadMentions), 0) AS UnreadMentions, UserId
|
||||
FROM ThreadMemberships
|
||||
LEFT JOIN Threads ON ThreadMemberships.PostId = Threads.PostId
|
||||
GROUP BY Threads.ChannelId, ThreadMemberships.UserId
|
||||
`
|
||||
updateMentionCountRootQuery := `
|
||||
UPDATE ChannelMembers INNER JOIN (` + mentionCountRootCTE + `) AS q ON
|
||||
q.ChannelId = ChannelMembers.ChannelId AND
|
||||
q.UserId=ChannelMembers.UserId AND
|
||||
ChannelMembers.MentionCount > 0
|
||||
SET MentionCountRoot = ChannelMembers.MentionCount - q.UnreadMentions
|
||||
`
|
||||
if sqlStore.DriverName() == model.DATABASE_DRIVER_POSTGRES {
|
||||
updateMentionCountRootQuery = `
|
||||
WITH q AS (` + mentionCountRootCTE + `)
|
||||
UPDATE channelmembers
|
||||
SET MentionCountRoot = ChannelMembers.MentionCount - q.UnreadMentions
|
||||
FROM q
|
||||
WHERE
|
||||
q.ChannelId = ChannelMembers.ChannelId AND
|
||||
q.UserId = ChannelMembers.UserId AND
|
||||
ChannelMembers.MentionCount > 0
|
||||
`
|
||||
}
|
||||
if _, err := sqlStore.GetMaster().Exec(updateMentionCountRootQuery); err != nil {
|
||||
mlog.Error("Error updating ChannelId in Threads table", mlog.Err(err))
|
||||
}
|
||||
sqlStore.CreateColumnIfNotExists("Channels", "TotalMsgCountRoot", "bigint", "bigint", "0")
|
||||
sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "LastRootPostAt", "bigint", "bigint")
|
||||
defer sqlStore.RemoveColumnIfExists("Channels", "LastRootPostAt")
|
||||
|
||||
@@ -1634,6 +1634,7 @@ func (us SqlUserStore) GetUsersBatchForIndexing(startTime, endTime int64, limit
|
||||
cm.LastViewedAt,
|
||||
cm.MsgCount,
|
||||
cm.MentionCount,
|
||||
cm.MentionCountRoot,
|
||||
cm.NotifyProps,
|
||||
cm.LastUpdateAt,
|
||||
cm.SchemeUser,
|
||||
|
||||
@@ -193,9 +193,9 @@ type ChannelStore interface {
|
||||
PermanentDeleteMembersByUser(userId string) error
|
||||
PermanentDeleteMembersByChannel(channelID string) error
|
||||
UpdateLastViewedAt(channelIds []string, userId string, updateThreads bool) (map[string]int64, error)
|
||||
UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, updateThreads bool) (*model.ChannelUnreadAt, error)
|
||||
UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount, mentionCountRoot int, updateThreads bool) (*model.ChannelUnreadAt, error)
|
||||
CountPostsAfter(channelID string, timestamp int64, userId string) (int, int, error)
|
||||
IncrementMentionCount(channelID string, userId string, updateThreads bool) error
|
||||
IncrementMentionCount(channelID string, userId string, updateThreads, isRoot bool) error
|
||||
AnalyticsTypeCount(teamID string, channelType string) (int64, error)
|
||||
GetMembersForUser(teamID string, userId string) (*model.ChannelMembers, error)
|
||||
GetMembersForUserWithPagination(teamID, userId string, page, perPage int) (*model.ChannelMembers, error)
|
||||
@@ -257,7 +257,6 @@ type ThreadStore interface {
|
||||
GetThreadForUser(userId, teamId, threadId string, extended bool) (*model.ThreadResponse, error)
|
||||
Delete(postId string) error
|
||||
GetPosts(threadId string, since int64) ([]*model.Post, error)
|
||||
GetThreadMentionsForUserPerChannel(userId, teamId string) (map[string]int64, error)
|
||||
|
||||
MarkAllAsRead(userId, teamID string) error
|
||||
MarkAsRead(userId, threadID string, timestamp int64) error
|
||||
|
||||
@@ -340,7 +340,7 @@ func testGetChannelUnread(t *testing.T, ss store.Store) {
|
||||
_, nErr = ss.Channel().Save(c2, -1)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
cm2 := &model.ChannelMember{ChannelId: c2.Id, UserId: m2.UserId, NotifyProps: notifyPropsModel, MsgCount: 90, MsgCountRoot: 90, MentionCount: 5}
|
||||
cm2 := &model.ChannelMember{ChannelId: c2.Id, UserId: m2.UserId, NotifyProps: notifyPropsModel, MsgCount: 90, MsgCountRoot: 90, MentionCount: 5, MentionCountRoot: 1}
|
||||
_, err = ss.Channel().SaveMember(cm2)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -361,6 +361,7 @@ func testGetChannelUnread(t *testing.T, ss store.Store) {
|
||||
require.Equal(t, c2.Id, ch2.ChannelId, "Wrong channel id")
|
||||
require.Equal(t, teamId2, ch2.TeamId, "Wrong team id")
|
||||
require.EqualValues(t, 5, ch2.MentionCount, "wrong MentionCount for channel 2")
|
||||
require.EqualValues(t, 1, ch2.MentionCountRoot, "wrong MentionCountRoot for channel 2")
|
||||
require.EqualValues(t, 10, ch2.MsgCount, "wrong MsgCount for channel 2")
|
||||
}
|
||||
|
||||
@@ -4200,16 +4201,16 @@ func testChannelStoreIncrementMentionCount(t *testing.T, ss store.Store) {
|
||||
_, err := ss.Channel().SaveMember(&m1)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ss.Channel().IncrementMentionCount(m1.ChannelId, m1.UserId, false)
|
||||
err = ss.Channel().IncrementMentionCount(m1.ChannelId, m1.UserId, false, false)
|
||||
require.NoError(t, err, "failed to update")
|
||||
|
||||
err = ss.Channel().IncrementMentionCount(m1.ChannelId, "missing id", false)
|
||||
err = ss.Channel().IncrementMentionCount(m1.ChannelId, "missing id", false, false)
|
||||
require.NoError(t, err, "failed to update")
|
||||
|
||||
err = ss.Channel().IncrementMentionCount("missing id", m1.UserId, false)
|
||||
err = ss.Channel().IncrementMentionCount("missing id", m1.UserId, false, false)
|
||||
require.NoError(t, err, "failed to update")
|
||||
|
||||
err = ss.Channel().IncrementMentionCount("missing id", "missing id", false)
|
||||
err = ss.Channel().IncrementMentionCount("missing id", "missing id", false, false)
|
||||
require.NoError(t, err, "failed to update")
|
||||
}
|
||||
|
||||
|
||||
@@ -1294,13 +1294,13 @@ func (_m *ChannelStore) GroupSyncedChannelCount() (int64, error) {
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// IncrementMentionCount provides a mock function with given fields: channelID, userId, updateThreads
|
||||
func (_m *ChannelStore) IncrementMentionCount(channelID string, userId string, updateThreads bool) error {
|
||||
ret := _m.Called(channelID, userId, updateThreads)
|
||||
// IncrementMentionCount provides a mock function with given fields: channelID, userId, updateThreads, isRoot
|
||||
func (_m *ChannelStore) IncrementMentionCount(channelID string, userId string, updateThreads bool, isRoot bool) error {
|
||||
ret := _m.Called(channelID, userId, updateThreads, isRoot)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool) error); ok {
|
||||
r0 = rf(channelID, userId, updateThreads)
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool, bool) error); ok {
|
||||
r0 = rf(channelID, userId, updateThreads, isRoot)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
@@ -1817,13 +1817,13 @@ func (_m *ChannelStore) UpdateLastViewedAt(channelIds []string, userId string, u
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UpdateLastViewedAtPost provides a mock function with given fields: unreadPost, userID, mentionCount, updateThreads
|
||||
func (_m *ChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
ret := _m.Called(unreadPost, userID, mentionCount, updateThreads)
|
||||
// UpdateLastViewedAtPost provides a mock function with given fields: unreadPost, userID, mentionCount, mentionCountRoot, updateThreads
|
||||
func (_m *ChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, mentionCountRoot int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
ret := _m.Called(unreadPost, userID, mentionCount, mentionCountRoot, updateThreads)
|
||||
|
||||
var r0 *model.ChannelUnreadAt
|
||||
if rf, ok := ret.Get(0).(func(*model.Post, string, int, bool) *model.ChannelUnreadAt); ok {
|
||||
r0 = rf(unreadPost, userID, mentionCount, updateThreads)
|
||||
if rf, ok := ret.Get(0).(func(*model.Post, string, int, int, bool) *model.ChannelUnreadAt); ok {
|
||||
r0 = rf(unreadPost, userID, mentionCount, mentionCountRoot, updateThreads)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.ChannelUnreadAt)
|
||||
@@ -1831,8 +1831,8 @@ func (_m *ChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID st
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.Post, string, int, bool) error); ok {
|
||||
r1 = rf(unreadPost, userID, mentionCount, updateThreads)
|
||||
if rf, ok := ret.Get(1).(func(*model.Post, string, int, int, bool) error); ok {
|
||||
r1 = rf(unreadPost, userID, mentionCount, mentionCountRoot, updateThreads)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
@@ -180,29 +180,6 @@ func (_m *ThreadStore) GetThreadForUser(userId string, teamId string, threadId s
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetThreadMentionsForUserPerChannel provides a mock function with given fields: userId, teamId
|
||||
func (_m *ThreadStore) GetThreadMentionsForUserPerChannel(userId string, teamId string) (map[string]int64, error) {
|
||||
ret := _m.Called(userId, teamId)
|
||||
|
||||
var r0 map[string]int64
|
||||
if rf, ok := ret.Get(0).(func(string, string) map[string]int64); ok {
|
||||
r0 = rf(userId, teamId)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(map[string]int64)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||
r1 = rf(userId, teamId)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetThreadsForUser provides a mock function with given fields: userId, teamId, opts
|
||||
func (_m *ThreadStore) GetThreadsForUser(userId string, teamId string, opts model.GetUserThreadsOpts) (*model.Threads, error) {
|
||||
ret := _m.Called(userId, teamId, opts)
|
||||
|
||||
@@ -243,7 +243,7 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) {
|
||||
_, err := ss.Thread().UpdateMembership(m)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = ss.Channel().UpdateLastViewedAtPost(newPosts[0], newPosts[0].UserId, 0, true)
|
||||
_, err = ss.Channel().UpdateLastViewedAtPost(newPosts[0], newPosts[0].UserId, 0, 0, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
@@ -263,7 +263,7 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) {
|
||||
_, err := ss.Thread().UpdateMembership(m)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ss.Channel().IncrementMentionCount(newPosts[0].ChannelId, newPosts[0].UserId, true)
|
||||
err = ss.Channel().IncrementMentionCount(newPosts[0].ChannelId, newPosts[0].UserId, true, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
@@ -317,7 +317,7 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) {
|
||||
_, err := ss.Thread().UpdateMembership(m)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = ss.Channel().UpdateLastViewedAtPost(newPosts[0], newPosts[0].UserId, 0, true)
|
||||
_, err = ss.Channel().UpdateLastViewedAtPost(newPosts[0], newPosts[0].UserId, 0, 0, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Eventually(t, func() bool {
|
||||
|
||||
@@ -2246,7 +2246,7 @@ func testUserUnreadCount(t *testing.T, ss store.Store) {
|
||||
// Post one message with mention to open channel
|
||||
_, nErr = ss.Post().Save(&p1)
|
||||
require.NoError(t, nErr)
|
||||
nErr = ss.Channel().IncrementMentionCount(c1.Id, u2.Id, false)
|
||||
nErr = ss.Channel().IncrementMentionCount(c1.Id, u2.Id, false, false)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Post 2 messages without mention to direct channel
|
||||
@@ -2257,7 +2257,7 @@ func testUserUnreadCount(t *testing.T, ss store.Store) {
|
||||
|
||||
_, nErr = ss.Post().Save(&p2)
|
||||
require.NoError(t, nErr)
|
||||
nErr = ss.Channel().IncrementMentionCount(c2.Id, u2.Id, false)
|
||||
nErr = ss.Channel().IncrementMentionCount(c2.Id, u2.Id, false, false)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
p3 := model.Post{}
|
||||
@@ -2267,7 +2267,7 @@ func testUserUnreadCount(t *testing.T, ss store.Store) {
|
||||
_, nErr = ss.Post().Save(&p3)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
nErr = ss.Channel().IncrementMentionCount(c2.Id, u2.Id, false)
|
||||
nErr = ss.Channel().IncrementMentionCount(c2.Id, u2.Id, false, false)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
badge, unreadCountErr := ss.User().GetUnreadCount(u2.Id)
|
||||
|
||||
@@ -1431,10 +1431,10 @@ func (s *TimerLayerChannelStore) GroupSyncedChannelCount() (int64, error) {
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerChannelStore) IncrementMentionCount(channelID string, userId string, updateThreads bool) error {
|
||||
func (s *TimerLayerChannelStore) IncrementMentionCount(channelID string, userId string, updateThreads bool, isRoot bool) error {
|
||||
start := timemodule.Now()
|
||||
|
||||
err := s.ChannelStore.IncrementMentionCount(channelID, userId, updateThreads)
|
||||
err := s.ChannelStore.IncrementMentionCount(channelID, userId, updateThreads, isRoot)
|
||||
|
||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
@@ -1952,10 +1952,10 @@ func (s *TimerLayerChannelStore) UpdateLastViewedAt(channelIds []string, userId
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
func (s *TimerLayerChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, mentionCountRoot int, updateThreads bool) (*model.ChannelUnreadAt, error) {
|
||||
start := timemodule.Now()
|
||||
|
||||
result, err := s.ChannelStore.UpdateLastViewedAtPost(unreadPost, userID, mentionCount, updateThreads)
|
||||
result, err := s.ChannelStore.UpdateLastViewedAtPost(unreadPost, userID, mentionCount, mentionCountRoot, updateThreads)
|
||||
|
||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
@@ -7096,22 +7096,6 @@ func (s *TimerLayerThreadStore) GetThreadForUser(userId string, teamId string, t
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerThreadStore) GetThreadMentionsForUserPerChannel(userId string, teamId string) (map[string]int64, error) {
|
||||
start := timemodule.Now()
|
||||
|
||||
result, err := s.ThreadStore.GetThreadMentionsForUserPerChannel(userId, teamId)
|
||||
|
||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
success := "false"
|
||||
if err == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("ThreadStore.GetThreadMentionsForUserPerChannel", success, elapsed)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerThreadStore) GetThreadsForUser(userId string, teamId string, opts model.GetUserThreadsOpts) (*model.Threads, error) {
|
||||
start := timemodule.Now()
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user