MM-54201 Refactor mention parsing in preparation for multi-word mentions (#25030)

* MM-54201 Move ExplicitMentions to its own file and rename it (#24932)

* MM-54201 Move ExplicitMentions to its own file and rename it

* Fix vet

* MM-54201 Refactor current mention parsing into MentionParserStandard (#24936)

* MM-54201 Refactor current mention parsing into MentionParserStandard

* Fix vet

* MM-54201 Unify user and group mention parsing logic (#24937)

* MM-54201 Add MentionKeywords type

* MM-54201 Move group mentions into MentionKeywords

* Fix flaky test caused by random iteration order

* Update server/channels/app/mention_results.go

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>

* Address feedback

---------

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>

---------

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
Этот коммит содержится в:
Harrison Healey
2023-10-23 12:37:58 -04:00
коммит произвёл GitHub
родитель 74f35aa92c
Коммит a78710c2a6
11 изменённых файлов: 1659 добавлений и 1182 удалений

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

@@ -56,7 +56,7 @@ func (a *App) ResolvePersistentNotification(c request.CTX, post *model.Post, log
}
stopNotifications := false
if err := a.forEachPersistentNotificationPost([]*model.Post{post}, func(_ *model.Post, _ *model.Channel, _ *model.Team, mentions *ExplicitMentions, _ model.UserMap, _ map[string]map[string]model.StringMap) error {
if err := a.forEachPersistentNotificationPost([]*model.Post{post}, func(_ *model.Post, _ *model.Channel, _ *model.Team, mentions *MentionResults, _ model.UserMap, _ map[string]map[string]model.StringMap) error {
if mentions.isUserMentioned(loggedInUserID) {
stopNotifications = true
}
@@ -151,7 +151,7 @@ func (a *App) SendPersistentNotifications() error {
return nil
}
func (a *App) forEachPersistentNotificationPost(posts []*model.Post, fn func(post *model.Post, channel *model.Channel, team *model.Team, mentions *ExplicitMentions, profileMap model.UserMap, channelNotifyProps map[string]map[string]model.StringMap) error) error {
func (a *App) forEachPersistentNotificationPost(posts []*model.Post, fn func(post *model.Post, channel *model.Channel, team *model.Team, mentions *MentionResults, profileMap model.UserMap, channelNotifyProps map[string]map[string]model.StringMap) error) error {
channelsMap, teamsMap, err := a.channelTeamMapsForPosts(posts)
if err != nil {
return err
@@ -171,7 +171,7 @@ func (a *App) forEachPersistentNotificationPost(posts []*model.Post, fn func(pos
}
profileMap := channelProfileMap[channel.Id]
mentions := &ExplicitMentions{}
mentions := &MentionResults{}
// In DMs, only the "other" user can be mentioned
if channel.Type == model.ChannelTypeDirect {
otherUserId := channel.GetOtherUserIdForDM(post.UserId)
@@ -180,8 +180,11 @@ func (a *App) forEachPersistentNotificationPost(posts []*model.Post, fn func(pos
}
} else {
keywords := channelKeywords[channel.Id]
mentions = getExplicitMentions(post, keywords, channelGroupMap[channel.Id])
for _, group := range mentions.GroupMentions {
keywords.AddGroupsMap(channelGroupMap[channel.Id])
mentions = getExplicitMentions(post, keywords)
for groupID := range mentions.GroupMentions {
group := channelGroupMap[channel.Id][groupID]
_, err := a.insertGroupMentions(group, channel, profileMap, mentions)
if err != nil {
return errors.Wrapf(err, "failed to include mentions from group - %s for channel - %s", group.Id, channel.Id)
@@ -197,10 +200,10 @@ func (a *App) forEachPersistentNotificationPost(posts []*model.Post, fn func(pos
return nil
}
func (a *App) persistentNotificationsAuxiliaryData(channelsMap map[string]*model.Channel, teamsMap map[string]*model.Team) (map[string]map[string]*model.Group, map[string]model.UserMap, map[string]map[string][]string, map[string]map[string]model.StringMap, error) {
func (a *App) persistentNotificationsAuxiliaryData(channelsMap map[string]*model.Channel, teamsMap map[string]*model.Team) (map[string]map[string]*model.Group, map[string]model.UserMap, map[string]MentionKeywords, map[string]map[string]model.StringMap, error) {
channelGroupMap := make(map[string]map[string]*model.Group, len(channelsMap))
channelProfileMap := make(map[string]model.UserMap, len(channelsMap))
channelKeywords := make(map[string]map[string][]string, len(channelsMap))
channelKeywords := make(map[string]MentionKeywords, len(channelsMap))
channelNotifyProps := make(map[string]map[string]model.StringMap, len(channelsMap))
for _, c := range channelsMap {
// In DM, notifications can't be send to any 3rd person.
@@ -210,8 +213,8 @@ func (a *App) persistentNotificationsAuxiliaryData(channelsMap map[string]*model
return nil, nil, nil, nil, errors.Wrapf(err, "failed to get profiles for channel %s", c.Id)
}
channelGroupMap[c.Id] = make(map[string]*model.Group, len(groups))
for k, v := range groups {
channelGroupMap[c.Id][k] = v
for groupID, group := range groups {
channelGroupMap[c.Id][groupID] = group
}
props, err := a.Srv().Store().Channel().GetAllChannelMembersNotifyPropsForChannel(c.Id, true)
if err != nil {
@@ -225,14 +228,14 @@ func (a *App) persistentNotificationsAuxiliaryData(channelsMap map[string]*model
return nil, nil, nil, nil, errors.Wrapf(err, "failed to get profiles for channel %s", c.Id)
}
channelKeywords[c.Id] = make(map[string][]string, len(profileMap))
channelKeywords[c.Id] = make(MentionKeywords, len(profileMap))
validProfileMap := make(map[string]*model.User, len(profileMap))
for k, v := range profileMap {
if v.IsBot {
for userID, user := range profileMap {
if user.IsBot {
continue
}
validProfileMap[k] = v
channelKeywords[c.Id]["@"+v.Username] = []string{k}
validProfileMap[userID] = user
channelKeywords[c.Id].AddUserKeyword(userID, "@"+user.Username)
}
channelProfileMap[c.Id] = validProfileMap
}
@@ -273,7 +276,7 @@ func (a *App) channelTeamMapsForPosts(posts []*model.Post) (map[string]*model.Ch
return channelsMap, teamsMap, nil
}
func (a *App) sendPersistentNotifications(post *model.Post, channel *model.Channel, team *model.Team, mentions *ExplicitMentions, profileMap model.UserMap, channelNotifyProps map[string]map[string]model.StringMap) error {
func (a *App) sendPersistentNotifications(post *model.Post, channel *model.Channel, team *model.Team, mentions *MentionResults, profileMap model.UserMap, channelNotifyProps map[string]map[string]model.StringMap) error {
mentionedUsersList := make(model.StringArray, 0, len(mentions.Mentions))
for id, v := range mentions.Mentions {
// Don't send notification to post owner nor GM mentions