MM-32655 - Collapsed threads websocket handling (#16909)
Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
78355ae2a7
Коммит
23d51ed1f2
@@ -1020,8 +1020,8 @@ type AppIface interface {
|
||||
UpdateTeamMemberSchemeRoles(teamID string, userID string, isSchemeGuest bool, isSchemeUser bool, isSchemeAdmin bool) (*model.TeamMember, *model.AppError)
|
||||
UpdateTeamPrivacy(teamID string, teamType string, allowOpenInvite bool) *model.AppError
|
||||
UpdateTeamScheme(team *model.Team) (*model.Team, *model.AppError)
|
||||
UpdateThreadFollowForUser(userID, threadId string, state bool) *model.AppError
|
||||
UpdateThreadReadForUser(userID, teamID, threadId string, timestamp int64) *model.AppError
|
||||
UpdateThreadFollowForUser(userID, teamID, threadID string, state bool) *model.AppError
|
||||
UpdateThreadReadForUser(userID, teamID, threadID string, timestamp int64) (*model.ThreadResponse, *model.AppError)
|
||||
UpdateThreadsReadForUser(userID, teamID string) *model.AppError
|
||||
UpdateUser(user *model.User, sendNotifications bool) (*model.User, *model.AppError)
|
||||
UpdateUserActive(userID string, active bool) *model.AppError
|
||||
|
||||
@@ -2371,8 +2371,13 @@ func (a *App) MarkChannelAsUnreadFromPost(postID string, userID string) (*model.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if *a.Config().ServiceSettings.ThreadAutoFollow && post.RootId != "" {
|
||||
threadMembership, _ := a.Srv().Store.Thread().GetMembershipForUser(user.Id, post.RootId)
|
||||
if *a.Config().ServiceSettings.ThreadAutoFollow {
|
||||
threadId := post.RootId
|
||||
if post.RootId == "" {
|
||||
threadId = post.Id
|
||||
}
|
||||
|
||||
threadMembership, _ := a.Srv().Store.Thread().GetMembershipForUser(user.Id, threadId)
|
||||
if threadMembership != nil {
|
||||
channel, nErr := a.Srv().Store.Channel().Get(post.ChannelId, true)
|
||||
if nErr != nil {
|
||||
@@ -2386,6 +2391,20 @@ func (a *App) MarkChannelAsUnreadFromPost(postID string, userID string) (*model.
|
||||
if nErr != nil {
|
||||
return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
thread, _ := a.Srv().Store.Thread().GetThreadForUser(userID, channel.TeamId, threadId, true)
|
||||
a.sanitizeProfiles(thread.Participants, false)
|
||||
thread.Post.SanitizeProps()
|
||||
|
||||
payload := thread.ToJson()
|
||||
sendEvent := *a.Config().ServiceSettings.CollapsedThreads == model.COLLAPSED_THREADS_DEFAULT_ON
|
||||
if preference, err := a.Srv().Store.Preference().Get(userID, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_COLLAPSED_THREADS_ENABLED); err == nil {
|
||||
sendEvent = preference.Value == "on"
|
||||
}
|
||||
if sendEvent {
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_THREAD_UPDATED, channel.TeamId, "", userID, nil)
|
||||
message.Add("thread", payload)
|
||||
a.Publish(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"context"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
@@ -168,7 +167,7 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
||||
}
|
||||
}
|
||||
|
||||
mentionedUsersList := make([]string, 0, len(mentions.Mentions))
|
||||
mentionedUsersList := make(model.StringArray, 0, len(mentions.Mentions))
|
||||
updateMentionChans := []chan *model.AppError{}
|
||||
mentionAutofollowChans := []chan *model.AppError{}
|
||||
threadParticipants := map[string]bool{post.UserId: true}
|
||||
@@ -433,16 +432,19 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot get thread %q", post.RootId)
|
||||
}
|
||||
payload := thread.ToJson()
|
||||
for _, uid := range thread.Participants {
|
||||
sendEvent := *a.Config().ServiceSettings.CollapsedThreads == model.COLLAPSED_THREADS_DEFAULT_ON
|
||||
// check if a participant has overridden collapsed threads settings
|
||||
if preference, err := a.Srv().Store.Preference().Get(uid, model.PREFERENCE_CATEGORY_COLLAPSED_THREADS_SETTINGS, model.PREFERENCE_NAME_COLLAPSED_THREADS_ENABLED); err == nil {
|
||||
sendEvent, _ = strconv.ParseBool(preference.Value)
|
||||
if preference, err := a.Srv().Store.Preference().Get(uid, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_COLLAPSED_THREADS_ENABLED); err == nil {
|
||||
sendEvent = preference.Value == "on"
|
||||
}
|
||||
if sendEvent {
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_THREAD_UPDATED, "", "", uid, nil)
|
||||
message.Add("thread", payload)
|
||||
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_THREAD_UPDATED, team.Id, "", uid, nil)
|
||||
userThread, _ := a.Srv().Store.Thread().GetThreadForUser(uid, channel.TeamId, thread.PostId, true)
|
||||
a.sanitizeProfiles(userThread.Participants, false)
|
||||
userThread.Post.SanitizeProps()
|
||||
message.Add("thread", userThread.ToJson())
|
||||
a.Publish(message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15643,7 +15643,7 @@ func (a *OpenTracingAppLayer) UpdateTeamScheme(team *model.Team) (*model.Team, *
|
||||
return resultVar0, resultVar1
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) UpdateThreadFollowForUser(userID string, threadId string, state bool) *model.AppError {
|
||||
func (a *OpenTracingAppLayer) UpdateThreadFollowForUser(userID string, teamID string, threadID string, state bool) *model.AppError {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateThreadFollowForUser")
|
||||
|
||||
@@ -15655,7 +15655,7 @@ func (a *OpenTracingAppLayer) UpdateThreadFollowForUser(userID string, threadId
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
resultVar0 := a.app.UpdateThreadFollowForUser(userID, threadId, state)
|
||||
resultVar0 := a.app.UpdateThreadFollowForUser(userID, teamID, threadID, state)
|
||||
|
||||
if resultVar0 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar0))
|
||||
@@ -15665,7 +15665,7 @@ func (a *OpenTracingAppLayer) UpdateThreadFollowForUser(userID string, threadId
|
||||
return resultVar0
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) UpdateThreadReadForUser(userID string, teamID string, threadId string, timestamp int64) *model.AppError {
|
||||
func (a *OpenTracingAppLayer) UpdateThreadReadForUser(userID string, teamID string, threadID string, timestamp int64) (*model.ThreadResponse, *model.AppError) {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateThreadReadForUser")
|
||||
|
||||
@@ -15677,14 +15677,14 @@ func (a *OpenTracingAppLayer) UpdateThreadReadForUser(userID string, teamID stri
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
resultVar0 := a.app.UpdateThreadReadForUser(userID, teamID, threadId, timestamp)
|
||||
resultVar0, resultVar1 := a.app.UpdateThreadReadForUser(userID, teamID, threadID, timestamp)
|
||||
|
||||
if resultVar0 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar0))
|
||||
if resultVar1 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar1))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return resultVar0
|
||||
return resultVar0, resultVar1
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) UpdateThreadsReadForUser(userID string, teamID string) *model.AppError {
|
||||
|
||||
@@ -1390,8 +1390,10 @@ func (a *App) countThreadMentions(user *model.User, post *model.Post, teamID str
|
||||
}
|
||||
|
||||
mentions := getExplicitMentions(post, keywords, groups)
|
||||
if _, ok := mentions.Mentions[user.Id]; ok {
|
||||
count += 1
|
||||
if post.UpdateAt >= timestamp {
|
||||
if _, ok := mentions.Mentions[user.Id]; ok {
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range posts {
|
||||
|
||||
44
app/user.go
44
app/user.go
@@ -2397,54 +2397,60 @@ func (a *App) UpdateThreadsReadForUser(userID, teamID string) *model.AppError {
|
||||
if nErr != nil {
|
||||
return model.NewAppError("UpdateThreadsReadForUser", "app.user.update_threads_read_for_user.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_THREAD_READ_CHANGED, "", "", userID, nil)
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_THREAD_READ_CHANGED, teamID, "", userID, nil)
|
||||
a.Publish(message)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) UpdateThreadFollowForUser(userID, threadId string, state bool) *model.AppError {
|
||||
err := a.Srv().Store.Thread().CreateMembershipIfNeeded(userID, threadId, state, false, true)
|
||||
func (a *App) UpdateThreadFollowForUser(userID, teamID, threadID string, state bool) *model.AppError {
|
||||
err := a.Srv().Store.Thread().CreateMembershipIfNeeded(userID, threadID, state, false, true)
|
||||
if err != nil {
|
||||
return model.NewAppError("UpdateThreadFollowForUser", "app.user.update_thread_follow_for_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_THREAD_FOLLOW_CHANGED, "", "", userID, nil)
|
||||
message.Add("thread_id", threadId)
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_THREAD_FOLLOW_CHANGED, teamID, "", userID, nil)
|
||||
message.Add("thread_id", threadID)
|
||||
message.Add("state", state)
|
||||
a.Publish(message)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) UpdateThreadReadForUser(userID, teamID, threadId string, timestamp int64) *model.AppError {
|
||||
func (a *App) UpdateThreadReadForUser(userID, teamID, threadID string, timestamp int64) (*model.ThreadResponse, *model.AppError) {
|
||||
user, err := a.GetUser(userID)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
membership, nErr := a.Srv().Store.Thread().GetMembershipForUser(userID, threadId)
|
||||
membership, nErr := a.Srv().Store.Thread().GetMembershipForUser(userID, threadID)
|
||||
if nErr != nil {
|
||||
return model.NewAppError("UpdateThreadsReadForUser", "app.user.update_threads_read_for_user.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
return nil, model.NewAppError("UpdateThreadsReadForUser", "app.user.update_threads_read_for_user.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
post, err := a.GetSinglePost(threadId)
|
||||
post, err := a.GetSinglePost(threadID)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
membership.UnreadMentions, err = a.countThreadMentions(user, post, teamID, timestamp)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
membership.Following = true
|
||||
_, nErr = a.Srv().Store.Thread().UpdateMembership(membership)
|
||||
if nErr != nil {
|
||||
return model.NewAppError("UpdateThreadsReadForUser", "app.user.update_threads_read_for_user.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
return nil, model.NewAppError("UpdateThreadsReadForUser", "app.user.update_threads_read_for_user.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
nErr = a.Srv().Store.Thread().MarkAsRead(userID, threadId, timestamp)
|
||||
nErr = a.Srv().Store.Thread().MarkAsRead(userID, threadID, timestamp)
|
||||
if nErr != nil {
|
||||
return model.NewAppError("UpdateThreadReadForUser", "app.user.update_thread_read_for_user.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
return nil, model.NewAppError("UpdateThreadReadForUser", "app.user.update_thread_read_for_user.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_THREAD_READ_CHANGED, "", "", userID, nil)
|
||||
message.Add("thread_id", threadId)
|
||||
thread, err := a.GetThreadForUser(userID, teamID, threadID, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_THREAD_READ_CHANGED, teamID, "", userID, nil)
|
||||
message.Add("thread_id", threadID)
|
||||
message.Add("timestamp", timestamp)
|
||||
message.Add("unread_mentions", membership.UnreadMentions)
|
||||
message.Add("unread_replies", thread.UnreadReplies)
|
||||
message.Add("channel_id", post.ChannelId)
|
||||
a.Publish(message)
|
||||
return nil
|
||||
return thread, nil
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user