From 50ab9626eb61dbb73b89f3435acd900a6e7921bb Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 21 Nov 2016 12:17:21 -0500 Subject: [PATCH 01/11] Properly load profile for new posts that have unloaded users (#4578) --- webapp/actions/websocket_actions.jsx | 6 +++++- webapp/components/rhs_root_post.jsx | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/webapp/actions/websocket_actions.jsx b/webapp/actions/websocket_actions.jsx index 36c6cbdc91..b61d039af2 100644 --- a/webapp/actions/websocket_actions.jsx +++ b/webapp/actions/websocket_actions.jsx @@ -18,7 +18,7 @@ import * as Utils from 'utils/utils.jsx'; import * as AsyncClient from 'utils/async_client.jsx'; import * as GlobalActions from 'actions/global_actions.jsx'; -import {handleNewPost, loadPosts} from 'actions/post_actions.jsx'; +import {handleNewPost, loadPosts, loadProfilesForPosts} from 'actions/post_actions.jsx'; import {loadProfilesAndTeamMembersForDMSidebar} from 'actions/user_actions.jsx'; import {loadChannelsForCurrentUser} from 'actions/channel_actions.jsx'; import * as StatusActions from 'actions/status_actions.jsx'; @@ -172,6 +172,10 @@ function handleNewPostEvent(msg) { const post = JSON.parse(msg.data.post); handleNewPost(post, msg); + const posts = {}; + posts[post.id] = post; + loadProfilesForPosts(posts); + if (UserStore.getStatus(post.user_id) !== UserStatuses.ONLINE) { StatusActions.loadStatusesByIds([post.user_id]); } diff --git a/webapp/components/rhs_root_post.jsx b/webapp/components/rhs_root_post.jsx index 0dae5976fa..22795967ad 100644 --- a/webapp/components/rhs_root_post.jsx +++ b/webapp/components/rhs_root_post.jsx @@ -90,7 +90,7 @@ export default class RhsRootPost extends React.Component { var isOwner = this.props.currentUser.id === post.user_id; var isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); const isSystemMessage = post.type && post.type.startsWith(Constants.SYSTEM_MESSAGE_PREFIX); - var timestamp = user.update_at; + var timestamp = user ? user.update_at : 0; var channel = ChannelStore.get(post.channel_id); const flagIcon = Constants.FLAG_ICON_SVG; From 3241b3abe4b574d5f1e21a8945229525c9240e3c Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 21 Nov 2016 12:17:28 -0500 Subject: [PATCH 02/11] Lower autocomplete timeout to 100ms (#4579) --- webapp/utils/constants.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx index 0da17e4b98..95d1f01f5f 100644 --- a/webapp/utils/constants.jsx +++ b/webapp/utils/constants.jsx @@ -849,7 +849,7 @@ export const Constants = { MENTION_SPECIAL: 'mention.special', DEFAULT_NOTIFICATION_DURATION: 5000, STATUS_INTERVAL: 60000, - AUTOCOMPLETE_TIMEOUT: 200 + AUTOCOMPLETE_TIMEOUT: 100 }; export default Constants; From 477dc6c4b62aad9102cb2c86f1d722ea996270d5 Mon Sep 17 00:00:00 2001 From: Corey Hulen Date: Mon, 21 Nov 2016 09:17:39 -0800 Subject: [PATCH 03/11] Hotfix: Fixing 'more' channel truncating purpose (#4581) * Fixing more channel purpose * Fixing to match master --- webapp/sass/components/_modal.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/sass/components/_modal.scss b/webapp/sass/components/_modal.scss index f89fb5c402..beb9ee8a16 100644 --- a/webapp/sass/components/_modal.scss +++ b/webapp/sass/components/_modal.scss @@ -612,7 +612,7 @@ .more-modal__row { border-bottom: 1px solid $light-gray; display: flex; - min-height: 50px; + min-height: 70px; padding: 8px 15px; } From a9824a3653a30779f7fd0cc62e329c988f02b519 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Mon, 21 Nov 2016 12:17:46 -0500 Subject: [PATCH 04/11] Hotfix: PLT-4779 Fixing scrolling on loading a channel and missing DM channel headers (#4584) * Added all parameters to call tracker ids when getting profiles * Changed channel header rendering to not depend on knowing all users in a DM channel * Added comment about a race condition in UserActions.populateDMChannelsWithProfiles * Added a fixed-height placeholder for the ChannelHeader when its state isn't valid for rendering --- webapp/actions/user_actions.jsx | 1 + webapp/components/channel_header.jsx | 18 ++++++--- webapp/sass/layout/_headers.scss | 2 +- webapp/utils/async_client.jsx | 60 +++++++++++++++++----------- 4 files changed, 51 insertions(+), 30 deletions(-) diff --git a/webapp/actions/user_actions.jsx b/webapp/actions/user_actions.jsx index 304d36a622..9b5bc985c1 100644 --- a/webapp/actions/user_actions.jsx +++ b/webapp/actions/user_actions.jsx @@ -135,6 +135,7 @@ function populateDMChannelsWithProfiles(userIds) { const currentUserId = UserStore.getCurrentId(); for (let i = 0; i < userIds.length; i++) { + // TODO There's a race condition here for DM channels if those channels aren't loaded yet const channelName = getDirectChannelName(currentUserId, userIds[i]); const channel = ChannelStore.getByName(channelName); if (channel) { diff --git a/webapp/components/channel_header.jsx b/webapp/components/channel_header.jsx index 1ce7b4a0ef..213f7fd0af 100644 --- a/webapp/components/channel_header.jsx +++ b/webapp/components/channel_header.jsx @@ -68,12 +68,18 @@ export default class ChannelHeader extends React.Component { const stats = ChannelStore.getStats(this.props.channelId); const users = UserStore.getProfileListInChannel(this.props.channelId); + let otherUserId = null; + if (channel.type === 'D') { + otherUserId = Utils.getUserIdFromChannelName(channel); + } + return { channel, memberChannel: ChannelStore.getMyMember(this.props.channelId), users, userCount: stats.member_count, currentUser: UserStore.getCurrentUser(), + otherUserId, enableFormatting: PreferenceStore.getBool(Preferences.CATEGORY_ADVANCED_SETTINGS, 'formatting', true), isBusy: WebrtcStore.isBusy(), isFavorite: channel && ChannelUtils.isFavoriteChannel(channel) @@ -84,7 +90,6 @@ export default class ChannelHeader extends React.Component { if (!this.state.channel || !this.state.memberChannel || !this.state.users || - (Object.keys(this.state.users).length === 0 && this.state.channel.type === 'D') || !this.state.userCount || !this.state.currentUser) { return false; @@ -240,7 +245,10 @@ export default class ChannelHeader extends React.Component { const flagIcon = Constants.FLAG_ICON_SVG; if (!this.validState()) { - return null; + // Use an empty div to make sure the header's height stays constant + return ( +
+ ); } const channel = this.state.channel; @@ -285,7 +293,7 @@ export default class ChannelHeader extends React.Component { if (isDirect) { const userMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; - const contact = this.state.users[0]; + const otherUserId = this.state.otherUserId; const teammateId = Utils.getUserIdFromChannelName(channel); channelTitle = Utils.displayUsername(teammateId); @@ -293,7 +301,7 @@ export default class ChannelHeader extends React.Component { const webrtcEnabled = global.mm_config.EnableWebrtc === 'true' && userMedia && Utils.isFeatureEnabled(PreReleaseFeatures.WEBRTC_PREVIEW); if (webrtcEnabled) { - const isOffline = UserStore.getStatus(contact.id) === UserStatuses.OFFLINE; + const isOffline = UserStore.getStatus(otherUserId) === UserStatuses.OFFLINE; const busy = this.state.isBusy; let circleClass = ''; let webrtcMessage; @@ -321,7 +329,7 @@ export default class ChannelHeader extends React.Component {
this.initWebrtc(contact.id, !isOffline)} + onClick={() => this.initWebrtc(otherUserId, !isOffline)} disabled={isOffline} > { - callTracker[`getUser${userId}`] = 0; + callTracker[callName] = 0; AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_PROFILE, @@ -314,23 +316,25 @@ export function getUser(userId) { }); }, (err) => { - callTracker[`getUser${userId}`] = 0; + callTracker[callName] = 0; dispatchError(err, 'getUser'); } ); } export function getProfiles(offset = UserStore.getPagingOffset(), limit = Constants.PROFILE_CHUNK_SIZE) { - if (isCallInProgress(`getProfiles${offset}${limit}`)) { + const callName = `getProfiles${offset}${limit}`; + + if (isCallInProgress(callName)) { return; } - callTracker[`getProfiles${offset}${limit}`] = utils.getTimestamp(); + callTracker[callName] = utils.getTimestamp(); Client.getProfiles( offset, limit, (data) => { - callTracker[`getProfiles${offset}${limit}`] = 0; + callTracker[callName] = 0; AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_PROFILES, @@ -338,24 +342,26 @@ export function getProfiles(offset = UserStore.getPagingOffset(), limit = Consta }); }, (err) => { - callTracker[`getProfiles${offset}${limit}`] = 0; + callTracker[callName] = 0; dispatchError(err, 'getProfiles'); } ); } export function getProfilesInTeam(teamId = TeamStore.getCurrentId(), offset = UserStore.getInTeamPagingOffset(), limit = Constants.PROFILE_CHUNK_SIZE) { - if (isCallInProgress(`getProfilesInTeam${offset}${limit}`)) { + const callName = `getProfilesInTeam${teamId}${offset}${limit}`; + + if (isCallInProgress(callName)) { return; } - callTracker[`getProfilesInTeam${offset}${limit}`] = utils.getTimestamp(); + callTracker[callName] = utils.getTimestamp(); Client.getProfilesInTeam( teamId, offset, limit, (data) => { - callTracker[`getProfilesInTeam${offset}${limit}`] = 0; + callTracker[callName] = 0; AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_PROFILES_IN_TEAM, @@ -366,24 +372,26 @@ export function getProfilesInTeam(teamId = TeamStore.getCurrentId(), offset = Us }); }, (err) => { - callTracker[`getProfilesInTeam${offset}${limit}`] = 0; + callTracker[callName] = 0; dispatchError(err, 'getProfilesInTeam'); } ); } export function getProfilesInChannel(channelId = ChannelStore.getCurrentId(), offset = UserStore.getInChannelPagingOffset(), limit = Constants.PROFILE_CHUNK_SIZE) { - if (isCallInProgress(`getProfilesInChannel${offset}${limit}`)) { + const callName = `getProfilesInChannel${channelId}${offset}${limit}`; + + if (isCallInProgress()) { return; } - callTracker[`getProfilesInChannel${offset}${limit}`] = utils.getTimestamp(); + callTracker[callName] = utils.getTimestamp(); Client.getProfilesInChannel( channelId, offset, limit, (data) => { - callTracker[`getProfilesInChannel${offset}${limit}`] = 0; + callTracker[callName] = 0; AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_PROFILES_IN_CHANNEL, @@ -396,24 +404,26 @@ export function getProfilesInChannel(channelId = ChannelStore.getCurrentId(), of loadStatusesForProfilesMap(data); }, (err) => { - callTracker[`getProfilesInChannel${offset}${limit}`] = 0; + callTracker[callName] = 0; dispatchError(err, 'getProfilesInChannel'); } ); } export function getProfilesNotInChannel(channelId = ChannelStore.getCurrentId(), offset = UserStore.getNotInChannelPagingOffset(), limit = Constants.PROFILE_CHUNK_SIZE) { - if (isCallInProgress(`getProfilesNotInChannel${offset}${limit}`)) { + const callName = `getProfilesNotInChannel${channelId}${offset}${limit}`; + + if (isCallInProgress(callName)) { return; } - callTracker[`getProfilesNotInChannel${offset}${limit}`] = utils.getTimestamp(); + callTracker[callName] = utils.getTimestamp(); Client.getProfilesNotInChannel( channelId, offset, limit, (data) => { - callTracker[`getProfilesNotInChannel${offset}${limit}`] = 0; + callTracker[callName] = 0; AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_PROFILES_NOT_IN_CHANNEL, @@ -426,14 +436,16 @@ export function getProfilesNotInChannel(channelId = ChannelStore.getCurrentId(), loadStatusesForProfilesMap(data); }, (err) => { - callTracker[`getProfilesNotInChannel${offset}${limit}`] = 0; + callTracker[callName] = 0; dispatchError(err, 'getProfilesNotInChannel'); } ); } export function getProfilesByIds(userIds) { - if (isCallInProgress('getProfilesByIds')) { + const callName = 'getProfilesByIds' + JSON.stringify(userIds); + + if (isCallInProgress(callName)) { return; } @@ -441,11 +453,11 @@ export function getProfilesByIds(userIds) { return; } - callTracker.getProfilesByIds = utils.getTimestamp(); + callTracker[callName] = utils.getTimestamp(); Client.getProfilesByIds( userIds, (data) => { - callTracker.getProfilesByIds = 0; + callTracker[callName] = 0; AppDispatcher.handleServerAction({ type: ActionTypes.RECEIVED_PROFILES, @@ -453,7 +465,7 @@ export function getProfilesByIds(userIds) { }); }, (err) => { - callTracker.getProfilesByIds = 0; + callTracker[callName] = 0; dispatchError(err, 'getProfilesByIds'); } ); From 062f758e47cda90a9ae783cbaee6bf3bec571178 Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 21 Nov 2016 12:17:53 -0500 Subject: [PATCH 05/11] Fix user search when using an asterisk (#4586) --- store/sql_user_store.go | 15 ++++++++++++++- store/sql_user_store_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/store/sql_user_store.go b/store/sql_user_store.go index aa3bb4380c..1a38e89e8e 100644 --- a/store/sql_user_store.go +++ b/store/sql_user_store.go @@ -1217,11 +1217,24 @@ func (us SqlUserStore) SearchInChannel(channelId string, term string, options ma return storeChannel } +var specialUserSearchChar = []string{ + "<", + ">", + "+", + "-", + "(", + ")", + "~", + "@", + ":", + "*", +} + func (us SqlUserStore) performSearch(searchQuery string, term string, options map[string]bool, parameters map[string]interface{}) StoreResult { result := StoreResult{} // these chars have special meaning and can be treated as spaces - for _, c := range specialSearchChar { + for _, c := range specialUserSearchChar { term = strings.Replace(term, c, " ", -1) } diff --git a/store/sql_user_store_test.go b/store/sql_user_store_test.go index e58e1fe407..acd87a036b 100644 --- a/store/sql_user_store_test.go +++ b/store/sql_user_store_test.go @@ -981,6 +981,32 @@ func TestUserStoreSearch(t *testing.T) { } } + // * should be treated as a space + if r1 := <-store.User().Search(tid, "jimb*", searchOptions); r1.Err != nil { + t.Fatal(r1.Err) + } else { + profiles := r1.Data.([]*model.User) + found1 := false + found2 := false + for _, profile := range profiles { + if profile.Id == u1.Id { + found1 = true + } + + if profile.Id == u3.Id { + found2 = true + } + } + + if !found1 { + t.Fatal("should have found user") + } + + if found2 { + t.Fatal("should not have found inactive user") + } + } + if r1 := <-store.User().Search(tid, "harol", searchOptions); r1.Err != nil { t.Fatal(r1.Err) } else { From 0ef77dff13bc74a396a412d7d416c7a7a3a9f447 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 21 Nov 2016 12:17:58 -0500 Subject: [PATCH 06/11] Fixing new messages indicator (#4614) --- webapp/components/post_view/post_view_controller.jsx | 9 +++++++-- webapp/stores/channel_store.jsx | 6 ++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/webapp/components/post_view/post_view_controller.jsx b/webapp/components/post_view/post_view_controller.jsx index 57b488b54e..53cd0b28c7 100644 --- a/webapp/components/post_view/post_view_controller.jsx +++ b/webapp/components/post_view/post_view_controller.jsx @@ -202,8 +202,13 @@ export default class PostViewController extends React.Component { } } - onSetNewMessageIndicator(lastViewed, ownNewMessage) { - this.setState({lastViewed, ownNewMessage}); + onSetNewMessageIndicator() { + let lastViewed = Number.MAX_VALUE; + const member = ChannelStore.getMyMember(this.props.channel.id); + if (member != null) { + lastViewed = member.last_viewed_at; + } + this.setState({lastViewed}); } onPostListScroll(atBottom) { diff --git a/webapp/stores/channel_store.jsx b/webapp/stores/channel_store.jsx index 136423d45a..d578a5d294 100644 --- a/webapp/stores/channel_store.jsx +++ b/webapp/stores/channel_store.jsx @@ -59,8 +59,8 @@ class ChannelStoreClass extends EventEmitter { this.removeListener(STATS_EVENT, callback); } - emitLastViewed(lastViewed, ownNewMessage) { - this.emit(LAST_VIEVED_EVENT, lastViewed, ownNewMessage); + emitLastViewed() { + this.emit(LAST_VIEVED_EVENT); } addLastViewedListener(callback) { @@ -373,6 +373,7 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => { } ChannelStore.setUnreadCountsByMembers(action.members); ChannelStore.emitChange(); + ChannelStore.emitLastViewed(); break; case ActionTypes.RECEIVED_CHANNEL_MEMBER: ChannelStore.storeMyChannelMember(action.member); @@ -382,6 +383,7 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => { } ChannelStore.setUnreadCountsByCurrentMembers(); ChannelStore.emitChange(); + ChannelStore.emitLastViewed(); break; case ActionTypes.RECEIVED_MORE_CHANNELS: ChannelStore.storeMoreChannels(action.channels); From 43c703e216c4145f5c61ed3b7453d72bd20306d0 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Mon, 21 Nov 2016 13:03:54 -0500 Subject: [PATCH 07/11] PLT-4787 Fixed not being able to join a channel through a link after opening the More Channels modal (#4616) --- webapp/components/post_view/post_view_cache.jsx | 7 ++++--- webapp/routes/route_team.jsx | 9 ++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/webapp/components/post_view/post_view_cache.jsx b/webapp/components/post_view/post_view_cache.jsx index c1b278c357..3b6123b097 100644 --- a/webapp/components/post_view/post_view_cache.jsx +++ b/webapp/components/post_view/post_view_cache.jsx @@ -17,11 +17,12 @@ export default class PostViewCache extends React.Component { this.onChannelChange = this.onChannelChange.bind(this); + const currentChannelId = ChannelStore.getCurrentId(); const channel = ChannelStore.getCurrent(); this.state = { - currentChannelId: channel.id, - channels: [channel] + currentChannelId, + channels: channel ? [channel] : [] }; } @@ -40,7 +41,7 @@ export default class PostViewCache extends React.Component { const channels = Object.assign([], this.state.channels); const currentChannel = ChannelStore.getCurrent(); - if (currentChannel == null) { + if (!currentChannel) { return; } diff --git a/webapp/routes/route_team.jsx b/webapp/routes/route_team.jsx index 4bdfd1cc66..7d4c0c80cf 100644 --- a/webapp/routes/route_team.jsx +++ b/webapp/routes/route_team.jsx @@ -29,13 +29,16 @@ function doChannelChange(state, replace, callback) { channel = JSON.parse(state.location.query.fakechannel); } else { channel = ChannelStore.getByName(state.params.channel); - if (!channel) { - channel = ChannelStore.getMoreByName(state.params.channel); - } + if (!channel) { Client.joinChannelByName( state.params.channel, (data) => { + AppDispatcher.handleServerAction({ + type: ActionTypes.RECEIVED_CHANNEL, + channel: data + }); + GlobalActions.emitChannelClickEvent(data); callback(); }, From 3c0f8c29db3d5cc5901b1e30710f1b900980920a Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Mon, 21 Nov 2016 16:08:29 -0500 Subject: [PATCH 08/11] Fixed error being thrown by ChannelHeader when switching teams (#4619) * Fixed error being thrown by ChannelHeader when switching teams * Close SidebarHeaderDropdown after switching teams --- webapp/components/channel_header.jsx | 2 +- webapp/components/sidebar_header_dropdown.jsx | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/webapp/components/channel_header.jsx b/webapp/components/channel_header.jsx index 213f7fd0af..50b860287e 100644 --- a/webapp/components/channel_header.jsx +++ b/webapp/components/channel_header.jsx @@ -69,7 +69,7 @@ export default class ChannelHeader extends React.Component { const users = UserStore.getProfileListInChannel(this.props.channelId); let otherUserId = null; - if (channel.type === 'D') { + if (channel && channel.type === 'D') { otherUserId = Utils.getUserIdFromChannelName(channel); } diff --git a/webapp/components/sidebar_header_dropdown.jsx b/webapp/components/sidebar_header_dropdown.jsx index b665eef52c..aa52267022 100644 --- a/webapp/components/sidebar_header_dropdown.jsx +++ b/webapp/components/sidebar_header_dropdown.jsx @@ -45,6 +45,7 @@ export default class SidebarHeaderDropdown extends React.Component { this.showGetTeamInviteLinkModal = this.showGetTeamInviteLinkModal.bind(this); this.showTeamMembersModal = this.showTeamMembersModal.bind(this); this.hideTeamMembersModal = this.hideTeamMembersModal.bind(this); + this.handleSwitchTeams = this.handleSwitchTeams.bind(this); this.onTeamChange = this.onTeamChange.bind(this); this.openAccountSettings = this.openAccountSettings.bind(this); @@ -131,6 +132,11 @@ export default class SidebarHeaderDropdown extends React.Component { }); } + handleSwitchTeams() { + // The actual switching of teams is handled by the react-router Link + this.setState({showDropdown: false}); + } + componentDidMount() { TeamStore.addChangeListener(this.onTeamChange); document.addEventListener('keydown', this.openAccountSettings); @@ -367,6 +373,7 @@ export default class SidebarHeaderDropdown extends React.Component {
  • Date: Mon, 21 Nov 2016 16:48:27 -0500 Subject: [PATCH 09/11] Fixed error logged when joining a team from another tab (#4620) --- webapp/actions/websocket_actions.jsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/webapp/actions/websocket_actions.jsx b/webapp/actions/websocket_actions.jsx index b61d039af2..60ed44fc90 100644 --- a/webapp/actions/websocket_actions.jsx +++ b/webapp/actions/websocket_actions.jsx @@ -211,6 +211,11 @@ function handleNewUserEvent(msg) { return; } + if (msg.data.user_id === UserStore.getCurrentId()) { + // We should already have ourselves + return; + } + AsyncClient.getUser(msg.data.user_id); AsyncClient.getChannelStats(); loadProfilesAndTeamMembersForDMSidebar(); From 48533aa483879a19fdd2c1e09c596aa6c028d439 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Wed, 23 Nov 2016 11:12:37 -0500 Subject: [PATCH 10/11] Fixed json and xml file rendering in code preview (#4642) --- webapp/components/code_preview.jsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/webapp/components/code_preview.jsx b/webapp/components/code_preview.jsx index 46782cd2dc..b06d9855a3 100644 --- a/webapp/components/code_preview.jsx +++ b/webapp/components/code_preview.jsx @@ -51,13 +51,18 @@ export default class CodePreview extends React.Component { async: true, url: props.fileUrl, type: 'GET', + dataType: 'text', error: this.handleReceivedError, success: this.handleReceivedCode }); } handleReceivedCode(data) { - this.setState({code: data, loading: false, success: true}); + this.setState({ + code: data, + loading: false, + success: true + }); } handleReceivedError() { From 36f62c9e82350f58c902f64a5d3304872431ad41 Mon Sep 17 00:00:00 2001 From: enahum Date: Wed, 23 Nov 2016 14:20:28 -0300 Subject: [PATCH 11/11] return posted message without waiting for email and push notifications to be sent (#4645) --- api/post.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/post.go b/api/post.go index e5e18cb525..5d1a04e00a 100644 --- a/api/post.go +++ b/api/post.go @@ -644,7 +644,7 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel * } if userAllowsEmails && status.Status != model.STATUS_ONLINE { - sendNotificationEmail(c, post, profileMap[id], channel, team, senderName, sender) + go sendNotificationEmail(c, post, profileMap[id], channel, team, senderName, sender) } } } @@ -700,7 +700,7 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel * } if DoesStatusAllowPushNotification(profileMap[id], status, post.ChannelId) { - sendPushNotification(post, profileMap[id], channel, senderName, true) + go sendPushNotification(post, profileMap[id], channel, senderName, true) } } @@ -713,7 +713,7 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel * } if DoesStatusAllowPushNotification(profileMap[id], status, post.ChannelId) { - sendPushNotification(post, profileMap[id], channel, senderName, false) + go sendPushNotification(post, profileMap[id], channel, senderName, false) } } }