summaryrefslogtreecommitdiffstats
path: root/app/channel.go
diff options
context:
space:
mode:
Diffstat (limited to 'app/channel.go')
-rw-r--r--app/channel.go340
1 files changed, 337 insertions, 3 deletions
diff --git a/app/channel.go b/app/channel.go
index aa84e12be..b8e02a149 100644
--- a/app/channel.go
+++ b/app/channel.go
@@ -5,6 +5,7 @@ package app
import (
"fmt"
+ "net/http"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/model"
@@ -190,6 +191,128 @@ func CreateDirectChannel(userId string, otherUserId string) (*model.Channel, *mo
}
}
+func UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError) {
+ if result := <-Srv.Store.Channel().Update(channel); result.Err != nil {
+ return nil, result.Err
+ } else {
+ InvalidateCacheForChannel(channel.Id)
+ return channel, nil
+ }
+}
+
+func UpdateChannelMemberRoles(channelId string, userId string, newRoles string) (*model.ChannelMember, *model.AppError) {
+ var member *model.ChannelMember
+ var err *model.AppError
+ if member, err = GetChannelMember(channelId, userId); err != nil {
+ return nil, err
+ }
+
+ member.Roles = newRoles
+
+ if result := <-Srv.Store.Channel().UpdateMember(member); result.Err != nil {
+ return nil, result.Err
+ }
+
+ InvalidateCacheForUser(userId)
+ return member, nil
+}
+
+func UpdateChannelMemberNotifyProps(data map[string]string, channelId string, userId string) (*model.ChannelMember, *model.AppError) {
+ var member *model.ChannelMember
+ var err *model.AppError
+ if member, err = GetChannelMember(channelId, userId); err != nil {
+ return nil, err
+ }
+
+ // update whichever notify properties have been provided, but don't change the others
+ if markUnread, exists := data["mark_unread"]; exists {
+ member.NotifyProps["mark_unread"] = markUnread
+ }
+
+ if desktop, exists := data["desktop"]; exists {
+ member.NotifyProps["desktop"] = desktop
+ }
+
+ if result := <-Srv.Store.Channel().UpdateMember(member); result.Err != nil {
+ return nil, result.Err
+ } else {
+ InvalidateCacheForUser(userId)
+ return member, nil
+ }
+}
+
+func DeleteChannel(channel *model.Channel, userId string) *model.AppError {
+ uc := Srv.Store.User().Get(userId)
+ scm := Srv.Store.Channel().GetMember(channel.Id, userId)
+ ihc := Srv.Store.Webhook().GetIncomingByChannel(channel.Id)
+ ohc := Srv.Store.Webhook().GetOutgoingByChannel(channel.Id)
+
+ if uresult := <-uc; uresult.Err != nil {
+ return uresult.Err
+ } else if scmresult := <-scm; scmresult.Err != nil {
+ return scmresult.Err
+ } else if ihcresult := <-ihc; ihcresult.Err != nil {
+ return ihcresult.Err
+ } else if ohcresult := <-ohc; ohcresult.Err != nil {
+ return ohcresult.Err
+ } else {
+ user := uresult.Data.(*model.User)
+ incomingHooks := ihcresult.Data.([]*model.IncomingWebhook)
+ outgoingHooks := ohcresult.Data.([]*model.OutgoingWebhook)
+ // Don't need to do anything with channel member, just wanted to confirm it exists
+
+ if channel.DeleteAt > 0 {
+ err := model.NewLocAppError("deleteChannel", "api.channel.delete_channel.deleted.app_error", nil, "")
+ err.StatusCode = http.StatusBadRequest
+ return err
+ }
+
+ if channel.Name == model.DEFAULT_CHANNEL {
+ err := model.NewLocAppError("deleteChannel", "api.channel.delete_channel.cannot.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "")
+ err.StatusCode = http.StatusBadRequest
+ return err
+ }
+
+ T := utils.GetUserTranslations(user.Locale)
+
+ post := &model.Post{
+ ChannelId: channel.Id,
+ Message: fmt.Sprintf(T("api.channel.delete_channel.archived"), user.Username),
+ Type: model.POST_CHANNEL_DELETED,
+ UserId: userId,
+ }
+
+ if _, err := CreatePost(post, channel.TeamId, false); err != nil {
+ l4g.Error(utils.T("api.channel.delete_channel.failed_post.error"), err)
+ }
+
+ now := model.GetMillis()
+ for _, hook := range incomingHooks {
+ if result := <-Srv.Store.Webhook().DeleteIncoming(hook.Id, now); result.Err != nil {
+ l4g.Error(utils.T("api.channel.delete_channel.incoming_webhook.error"), hook.Id)
+ }
+ }
+
+ for _, hook := range outgoingHooks {
+ if result := <-Srv.Store.Webhook().DeleteOutgoing(hook.Id, now); result.Err != nil {
+ l4g.Error(utils.T("api.channel.delete_channel.outgoing_webhook.error"), hook.Id)
+ }
+ }
+
+ if dresult := <-Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); dresult.Err != nil {
+ return dresult.Err
+ }
+ InvalidateCacheForChannel(channel.Id)
+
+ message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_DELETED, channel.TeamId, "", "", nil)
+ message.Add("channel_id", channel.Id)
+
+ Publish(message)
+ }
+
+ return nil
+}
+
func AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelMember, *model.AppError) {
if channel.DeleteAt > 0 {
return nil, model.NewLocAppError("AddUserToChannel", "api.channel.add_user_to_channel.deleted.app_error", nil, "")
@@ -205,7 +328,7 @@ func AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelM
if result := <-tmchan; result.Err != nil {
return nil, result.Err
} else {
- teamMember := result.Data.(model.TeamMember)
+ teamMember := result.Data.(*model.TeamMember)
if teamMember.DeleteAt > 0 {
return nil, model.NewLocAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.deleted.app_error", nil, "")
}
@@ -216,8 +339,8 @@ func AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelM
return nil, result.Err
}
} else {
- channelMember := result.Data.(model.ChannelMember)
- return &channelMember, nil
+ channelMember := result.Data.(*model.ChannelMember)
+ return channelMember, nil
}
newMember := &model.ChannelMember{
@@ -396,6 +519,62 @@ func GetChannelByName(channelName, teamId string) (*model.Channel, *model.AppErr
}
}
+func GetChannelsForUser(teamId string, userId string) (*model.ChannelList, *model.AppError) {
+ if result := <-Srv.Store.Channel().GetChannels(teamId, userId); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.ChannelList), nil
+ }
+}
+
+func GetChannelsUserNotIn(teamId string, userId string, offset int, limit int) (*model.ChannelList, *model.AppError) {
+ if result := <-Srv.Store.Channel().GetMoreChannels(teamId, userId, offset, limit); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.ChannelList), nil
+ }
+}
+
+func GetChannelMember(channelId string, userId string) (*model.ChannelMember, *model.AppError) {
+ if result := <-Srv.Store.Channel().GetMember(channelId, userId); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.ChannelMember), nil
+ }
+}
+
+func GetChannelMembersByIds(channelId string, userIds []string) (*model.ChannelMembers, *model.AppError) {
+ if result := <-Srv.Store.Channel().GetMembersByIds(channelId, userIds); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.ChannelMembers), nil
+ }
+}
+
+func GetChannelMembersForUser(teamId string, userId string) (*model.ChannelMembers, *model.AppError) {
+ if result := <-Srv.Store.Channel().GetMembersForUser(teamId, userId); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.ChannelMembers), nil
+ }
+}
+
+func GetChannelMemberCount(channelId string) (int64, *model.AppError) {
+ if result := <-Srv.Store.Channel().GetMemberCount(channelId, true); result.Err != nil {
+ return 0, result.Err
+ } else {
+ return result.Data.(int64), nil
+ }
+}
+
+func GetChannelCounts(teamId string, userId string) (*model.ChannelCounts, *model.AppError) {
+ if result := <-Srv.Store.Channel().GetChannelCounts(teamId, userId); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.ChannelCounts), nil
+ }
+}
+
func JoinChannel(channel *model.Channel, userId string) *model.AppError {
userChan := Srv.Store.User().Get(userId)
memberChan := Srv.Store.Channel().GetMember(channel.Id, userId)
@@ -421,6 +600,76 @@ func JoinChannel(channel *model.Channel, userId string) *model.AppError {
return nil
}
+func LeaveChannel(channelId string, userId string) *model.AppError {
+ sc := Srv.Store.Channel().Get(channelId, true)
+ uc := Srv.Store.User().Get(userId)
+ ccm := Srv.Store.Channel().GetMemberCount(channelId, false)
+
+ if cresult := <-sc; cresult.Err != nil {
+ return cresult.Err
+ } else if uresult := <-uc; uresult.Err != nil {
+ return cresult.Err
+ } else if ccmresult := <-ccm; ccmresult.Err != nil {
+ return ccmresult.Err
+ } else {
+ channel := cresult.Data.(*model.Channel)
+ user := uresult.Data.(*model.User)
+ membersCount := ccmresult.Data.(int64)
+
+ if channel.Type == model.CHANNEL_DIRECT {
+ err := model.NewLocAppError("LeaveChannel", "api.channel.leave.direct.app_error", nil, "")
+ err.StatusCode = http.StatusBadRequest
+ return err
+ }
+
+ if channel.Type == model.CHANNEL_PRIVATE && membersCount == 1 {
+ err := model.NewLocAppError("LeaveChannel", "api.channel.leave.last_member.app_error", nil, "userId="+user.Id)
+ err.StatusCode = http.StatusBadRequest
+ return err
+ }
+
+ if err := RemoveUserFromChannel(userId, userId, channel); err != nil {
+ return err
+ }
+
+ go PostUserAddRemoveMessage(userId, channel.Id, channel.TeamId, fmt.Sprintf(utils.T("api.channel.leave.left"), user.Username), model.POST_JOIN_LEAVE)
+ }
+
+ return nil
+}
+
+func RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel *model.Channel) *model.AppError {
+ if channel.DeleteAt > 0 {
+ err := model.NewLocAppError("RemoveUserFromChannel", "api.channel.remove_user_from_channel.deleted.app_error", nil, "")
+ err.StatusCode = http.StatusBadRequest
+ return err
+ }
+
+ if channel.Name == model.DEFAULT_CHANNEL {
+ return model.NewLocAppError("RemoveUserFromChannel", "api.channel.remove.default.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "")
+ }
+
+ if cmresult := <-Srv.Store.Channel().RemoveMember(channel.Id, userIdToRemove); cmresult.Err != nil {
+ return cmresult.Err
+ }
+
+ InvalidateCacheForUser(userIdToRemove)
+ InvalidateCacheForChannel(channel.Id)
+
+ message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", channel.Id, "", nil)
+ message.Add("user_id", userIdToRemove)
+ message.Add("remover_id", removerUserId)
+ go Publish(message)
+
+ // because the removed user no longer belongs to the channel we need to send a separate websocket event
+ userMsg := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", "", userIdToRemove, nil)
+ userMsg.Add("channel_id", channel.Id)
+ userMsg.Add("remover_id", removerUserId)
+ go Publish(userMsg)
+
+ return nil
+}
+
func PostUserAddRemoveMessage(userId, channelId, teamId, message, postType string) *model.AppError {
post := &model.Post{
ChannelId: channelId,
@@ -434,3 +683,88 @@ func PostUserAddRemoveMessage(userId, channelId, teamId, message, postType strin
return nil
}
+
+func GetNumberOfChannelsOnTeam(teamId string) (int, *model.AppError) {
+ // Get total number of channels on current team
+ if result := <-Srv.Store.Channel().GetTeamChannels(teamId); result.Err != nil {
+ return 0, result.Err
+ } else {
+ return len(*result.Data.(*model.ChannelList)), nil
+ }
+}
+
+func SetActiveChannel(userId string, channelId string) *model.AppError {
+ status, err := GetStatus(userId)
+ if err != nil {
+ status = &model.Status{userId, model.STATUS_ONLINE, false, model.GetMillis(), channelId}
+ } else {
+ status.ActiveChannel = channelId
+ if !status.Manual {
+ status.Status = model.STATUS_ONLINE
+ }
+ status.LastActivityAt = model.GetMillis()
+ }
+
+ AddStatusCache(status)
+
+ return nil
+}
+
+func UpdateChannelLastViewedAt(channelIds []string, userId string) *model.AppError {
+ if result := <-Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId); result.Err != nil {
+ return result.Err
+ }
+
+ return nil
+}
+
+func SearchChannels(teamId string, term string) (*model.ChannelList, *model.AppError) {
+ if result := <-Srv.Store.Channel().SearchInTeam(teamId, term); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.ChannelList), nil
+ }
+}
+
+func SearchChannelsUserNotIn(teamId string, userId string, term string) (*model.ChannelList, *model.AppError) {
+ if result := <-Srv.Store.Channel().SearchMore(userId, teamId, term); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.ChannelList), nil
+ }
+}
+
+func ViewChannel(view *model.ChannelView, teamId string, userId string, clearPushNotifications bool) *model.AppError {
+ channelIds := []string{view.ChannelId}
+
+ var pchan store.StoreChannel
+ if len(view.PrevChannelId) > 0 {
+ channelIds = append(channelIds, view.PrevChannelId)
+
+ if *utils.Cfg.EmailSettings.SendPushNotifications && clearPushNotifications {
+ pchan = Srv.Store.User().GetUnreadCountForChannel(userId, view.ChannelId)
+ }
+ }
+
+ uchan := Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId)
+
+ if pchan != nil {
+ if result := <-pchan; result.Err != nil {
+ return result.Err
+ } else {
+ if result.Data.(int64) > 0 {
+ ClearPushNotification(userId, view.ChannelId)
+ }
+ }
+ }
+
+ if result := <-uchan; result.Err != nil {
+ return result.Err
+ }
+
+ message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, teamId, "", userId, nil)
+ message.Add("channel_id", view.ChannelId)
+ go Publish(message)
+
+ return nil
+}