diff options
author | Joram Wilander <jwawilander@gmail.com> | 2016-04-27 16:05:39 -0400 |
---|---|---|
committer | Harrison Healey <harrisonmhealey@gmail.com> | 2016-04-27 16:05:39 -0400 |
commit | 7695cbd1b4a62b1cc7c31b16f70309a287296385 (patch) | |
tree | 15a7f35bb56f0c72a9c13192380d795a48339d48 | |
parent | ada513a0146cfb570e3614f9b26c0465de3a1d94 (diff) | |
download | chat-7695cbd1b4a62b1cc7c31b16f70309a287296385.tar.gz chat-7695cbd1b4a62b1cc7c31b16f70309a287296385.tar.bz2 chat-7695cbd1b4a62b1cc7c31b16f70309a287296385.zip |
Add websocket event and cache invalidation for deleting channels (#2807)
-rw-r--r-- | api/channel.go | 22 | ||||
-rw-r--r-- | api/web_conn.go | 4 | ||||
-rw-r--r-- | api/web_hub.go | 39 | ||||
-rw-r--r-- | model/message.go | 1 | ||||
-rw-r--r-- | model/post.go | 1 | ||||
-rw-r--r-- | webapp/action_creators/websocket_actions.jsx | 15 | ||||
-rw-r--r-- | webapp/stores/team_store.jsx | 20 | ||||
-rw-r--r-- | webapp/utils/constants.jsx | 1 |
8 files changed, 68 insertions, 35 deletions
diff --git a/api/channel.go b/api/channel.go index d47109045..4b0e99b20 100644 --- a/api/channel.go +++ b/api/channel.go @@ -687,14 +687,20 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("name=" + channel.Name) - post := &model.Post{ChannelId: channel.Id, Message: fmt.Sprintf( - c.T("api.channel.delete_channel.archived"), - user.Username)} - if _, err := CreatePost(c, post, false); err != nil { - l4g.Error(utils.T("api.channel.delete_channel.failed_post.error"), err) - c.Err = model.NewLocAppError("deleteChannel", "api.channel.delete_channel.failed_send.app_error", nil, "") - return - } + go func() { + InvalidateCacheForChannel(channel.Id) + message := model.NewMessage(c.TeamId, channel.Id, c.Session.UserId, model.ACTION_CHANNEL_DELETED) + PublishAndForget(message) + + post := &model.Post{ + ChannelId: channel.Id, + Message: fmt.Sprintf(c.T("api.channel.delete_channel.archived"), user.Username), + Type: model.POST_CHANNEL_DELETED, + } + if _, err := CreatePost(c, post, false); err != nil { + l4g.Error(utils.T("api.channel.delete_channel.failed_post.error"), err) + } + }() result := make(map[string]string) result["id"] = channel.Id diff --git a/api/web_conn.go b/api/web_conn.go index 397af0696..21b6f5b91 100644 --- a/api/web_conn.go +++ b/api/web_conn.go @@ -118,6 +118,10 @@ func (c *WebConn) InvalidateCache() { c.hasPermissionsToTeam = make(map[string]bool) } +func (c *WebConn) InvalidateCacheForChannel(channelId string) { + delete(c.hasPermissionsToChannel, channelId) +} + func (c *WebConn) HasPermissionsToTeam(teamId string) bool { perm, ok := c.hasPermissionsToTeam[teamId] if !ok { diff --git a/api/web_hub.go b/api/web_hub.go index 241ebcef0..066ae3474 100644 --- a/api/web_hub.go +++ b/api/web_hub.go @@ -10,21 +10,23 @@ import ( ) type Hub struct { - connections map[*WebConn]bool - register chan *WebConn - unregister chan *WebConn - broadcast chan *model.Message - stop chan string - invalidateUser chan string + connections map[*WebConn]bool + register chan *WebConn + unregister chan *WebConn + broadcast chan *model.Message + stop chan string + invalidateUser chan string + invalidateChannel chan string } var hub = &Hub{ - register: make(chan *WebConn), - unregister: make(chan *WebConn), - connections: make(map[*WebConn]bool), - broadcast: make(chan *model.Message), - stop: make(chan string), - invalidateUser: make(chan string), + register: make(chan *WebConn), + unregister: make(chan *WebConn), + connections: make(map[*WebConn]bool), + broadcast: make(chan *model.Message), + stop: make(chan string), + invalidateUser: make(chan string), + invalidateChannel: make(chan string), } func PublishAndForget(message *model.Message) { @@ -37,6 +39,10 @@ func InvalidateCacheForUser(userId string) { hub.invalidateUser <- userId } +func InvalidateCacheForChannel(channelId string) { + hub.invalidateChannel <- channelId +} + func (h *Hub) Register(webConn *WebConn) { h.register <- webConn } @@ -74,6 +80,11 @@ func (h *Hub) Start() { } } + case channelId := <-h.invalidateChannel: + for webCon := range h.connections { + webCon.InvalidateCacheForChannel(channelId) + } + case msg := <-h.broadcast: for webCon := range h.connections { if shouldSendEvent(webCon, msg) { @@ -136,8 +147,8 @@ func shouldSendEvent(webCon *WebConn, msg *model.Message) bool { } } - // Only report events to users who are in the channel for the event - if len(msg.ChannelId) > 0 { + // Only report events to users who are in the channel for the event execept deleted events + if len(msg.ChannelId) > 0 && msg.Action != model.ACTION_CHANNEL_DELETED { allowed := webCon.HasPermissionsToChannel(msg.ChannelId) if !allowed { diff --git a/model/message.go b/model/message.go index cce0ec094..53ce4c154 100644 --- a/model/message.go +++ b/model/message.go @@ -13,6 +13,7 @@ const ( ACTION_POSTED = "posted" ACTION_POST_EDITED = "post_edited" ACTION_POST_DELETED = "post_deleted" + ACTION_CHANNEL_DELETED = "channel_deleted" ACTION_CHANNEL_VIEWED = "channel_viewed" ACTION_NEW_USER = "new_user" ACTION_USER_ADDED = "user_added" diff --git a/model/post.go b/model/post.go index 8a451831c..173c99e37 100644 --- a/model/post.go +++ b/model/post.go @@ -16,6 +16,7 @@ const ( POST_SYSTEM_GENERIC = "system_generic" POST_JOIN_LEAVE = "system_join_leave" POST_HEADER_CHANGE = "system_header_change" + POST_CHANNEL_DELETED = "system_channel_deleted" POST_EPHEMERAL = "system_ephemeral" ) diff --git a/webapp/action_creators/websocket_actions.jsx b/webapp/action_creators/websocket_actions.jsx index a1368ac99..83a000f6d 100644 --- a/webapp/action_creators/websocket_actions.jsx +++ b/webapp/action_creators/websocket_actions.jsx @@ -18,6 +18,8 @@ import * as GlobalActions from 'action_creators/global_actions.jsx'; import Constants from 'utils/constants.jsx'; const SocketEvents = Constants.SocketEvents; +import {browserHistory} from 'react-router'; + const MAX_WEBSOCKET_FAILS = 7; const WEBSOCKET_RETRY_TIME = 3000; @@ -135,6 +137,10 @@ function handleMessage(msg) { handleChannelViewedEvent(msg); break; + case SocketEvents.CHANNEL_DELETED: + handleChannelDeletedEvent(msg); + break; + case SocketEvents.PREFERENCE_CHANGED: handlePreferenceChangedEvent(msg); break; @@ -234,6 +240,15 @@ function handleChannelViewedEvent(msg) { } } +function handleChannelDeletedEvent(msg) { + if (ChannelStore.getCurrentId() === msg.channel_id) { + const teamUrl = TeamStore.getCurrentTeamRelativeUrl(); + browserHistory.push(teamUrl + '/channels/' + Constants.DEFAULT_CHANNEL); + } else { + AsyncClient.getChannels(); + } +} + function handlePreferenceChangedEvent(msg) { const preference = JSON.parse(msg.props.preference); GlobalActions.emitPreferenceChangedEvent(preference); diff --git a/webapp/stores/team_store.jsx b/webapp/stores/team_store.jsx index 356df7b07..29e832633 100644 --- a/webapp/stores/team_store.jsx +++ b/webapp/stores/team_store.jsx @@ -20,19 +20,6 @@ function getWindowLocationOrigin() { class TeamStoreClass extends EventEmitter { constructor() { super(); - - this.emitChange = this.emitChange.bind(this); - this.addChangeListener = this.addChangeListener.bind(this); - this.removeChangeListener = this.removeChangeListener.bind(this); - this.get = this.get.bind(this); - this.getByName = this.getByName.bind(this); - this.getAll = this.getAll.bind(this); - this.getCurrentId = this.getCurrentId.bind(this); - this.getCurrent = this.getCurrent.bind(this); - this.getCurrentTeamUrl = this.getCurrentTeamUrl.bind(this); - this.getCurrentInviteLink = this.getCurrentInviteLink.bind(this); - this.saveTeam = this.saveTeam.bind(this); - this.clear(); } @@ -104,6 +91,13 @@ class TeamStoreClass extends EventEmitter { return null; } + getCurrentTeamRelativeUrl() { + if (this.getCurrent()) { + return '/' + this.getCurrent().name; + } + return null; + } + getCurrentInviteLink() { const current = this.getCurrent(); diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx index 9bdf348cd..3f8980bfa 100644 --- a/webapp/utils/constants.jsx +++ b/webapp/utils/constants.jsx @@ -147,6 +147,7 @@ export default { POSTED: 'posted', POST_EDITED: 'post_edited', POST_DELETED: 'post_deleted', + CHANNEL_DELETED: 'channel_deleted', CHANNEL_VIEWED: 'channel_viewed', NEW_USER: 'new_user', USER_ADDED: 'user_added', |