summaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
authorJoram Wilander <jwawilander@gmail.com>2016-07-21 10:00:09 -0400
committerGitHub <noreply@github.com>2016-07-21 10:00:09 -0400
commitbfa04c0ab0eca5d812ad64e5f51e95ec458cf0d3 (patch)
tree6a51f8d4d144a181192499f5fd60ef82700e9abb /api
parentf0e9ec2dd127ffe34472c617f978173a8bf60b7c (diff)
downloadchat-bfa04c0ab0eca5d812ad64e5f51e95ec458cf0d3.tar.gz
chat-bfa04c0ab0eca5d812ad64e5f51e95ec458cf0d3.tar.bz2
chat-bfa04c0ab0eca5d812ad64e5f51e95ec458cf0d3.zip
PLT-2408 Adds here mention for online users (#3619)
* Added @here mention that notifies online users * Fixed existing race condition that would sometime cause clients to miss mention count changes * Added missing localization strings * Prevent @here from mentioning the user who posted it
Diffstat (limited to 'api')
-rw-r--r--api/post.go45
-rw-r--r--api/status.go4
2 files changed, 39 insertions, 10 deletions
diff --git a/api/post.go b/api/post.go
index 951ccb527..9bf6cff40 100644
--- a/api/post.go
+++ b/api/post.go
@@ -477,6 +477,8 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
mentionedUserIds := make(map[string]bool)
alwaysNotifyUserIds := []string{}
+ hereNotification := false
+ updateMentionChans := []store.StoreChannel{}
if channel.Type == model.CHANNEL_DIRECT {
@@ -537,6 +539,11 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
splitMessage := strings.Fields(post.Message)
var userIds []string
for _, word := range splitMessage {
+ if word == "@here" {
+ hereNotification = true
+ continue
+ }
+
// Non-case-sensitive check for regular keys
if ids, match := keywordMap[strings.ToLower(word)]; match {
userIds = append(userIds, ids...)
@@ -591,7 +598,7 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
}
for id := range mentionedUserIds {
- go updateMentionCount(post.ChannelId, id)
+ updateMentionChans = append(updateMentionChans, Srv.Store.Channel().IncrementMentionCount(post.ChannelId, id))
}
}
@@ -624,6 +631,28 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
}
}
+ if hereNotification {
+ if result := <-Srv.Store.Status().GetOnline(); result.Err != nil {
+ l4g.Warn(utils.T("api.post.notification.here.warn"), result.Err)
+ return
+ } else {
+ statuses := result.Data.([]*model.Status)
+ for _, status := range statuses {
+ if status.UserId == post.UserId {
+ continue
+ }
+
+ _, profileFound := profileMap[status.UserId]
+ _, alreadyAdded := mentionedUserIds[status.UserId]
+
+ if status.Status == model.STATUS_ONLINE && profileFound && !alreadyAdded {
+ mentionedUsersList = append(mentionedUsersList, status.UserId)
+ updateMentionChans = append(updateMentionChans, Srv.Store.Channel().IncrementMentionCount(post.ChannelId, status.UserId))
+ }
+ }
+ }
+ }
+
sendPushNotifications := false
if *utils.Cfg.EmailSettings.SendPushNotifications {
pushServer := *utils.Cfg.EmailSettings.PushNotificationServer
@@ -671,6 +700,14 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
message.Add("mentions", model.ArrayToJson(mentionedUsersList))
}
+ // Make sure all mention updates are complete to prevent race
+ // Probably better to batch these DB updates in the future
+ for _, uchan := range updateMentionChans {
+ if result := <-uchan; result.Err != nil {
+ l4g.Warn(utils.T("api.post.update_mention_count_and_forget.update_error"), post.Id, post.ChannelId, result.Err)
+ }
+ }
+
go Publish(message)
}
@@ -837,12 +874,6 @@ func sendPushNotification(post *model.Post, user *model.User, channel *model.Cha
}
}
-func updateMentionCount(channelId, userId string) {
- if result := <-Srv.Store.Channel().IncrementMentionCount(channelId, userId); result.Err != nil {
- l4g.Error(utils.T("api.post.update_mention_count_and_forget.update_error"), userId, channelId, result.Err)
- }
-}
-
func checkForOutOfChannelMentions(c *Context, post *model.Post, channel *model.Channel, allProfiles map[string]*model.User, members []model.ChannelMember) {
// don't check for out of channel mentions in direct channels
if channel.Type == model.CHANNEL_DIRECT {
diff --git a/api/status.go b/api/status.go
index 88f024f4e..2a5a73c4a 100644
--- a/api/status.go
+++ b/api/status.go
@@ -55,14 +55,12 @@ func GetAllStatuses() (map[string]interface{}, *model.AppError) {
func SetStatusOnline(userId string, sessionId string) {
broadcast := false
- saveStatus := false
var status *model.Status
var err *model.AppError
if status, err = GetStatus(userId); err != nil {
status = &model.Status{userId, model.STATUS_ONLINE, model.GetMillis()}
broadcast = true
- saveStatus = true
} else {
if status.Status != model.STATUS_ONLINE {
broadcast = true
@@ -76,7 +74,7 @@ func SetStatusOnline(userId string, sessionId string) {
achan := Srv.Store.Session().UpdateLastActivityAt(sessionId, model.GetMillis())
var schan store.StoreChannel
- if saveStatus {
+ if broadcast {
schan = Srv.Store.Status().SaveOrUpdate(status)
} else {
schan = Srv.Store.Status().UpdateLastActivityAt(status.UserId, status.LastActivityAt)