From 98ac903fce24418538edbec77a218bcac9e20cd2 Mon Sep 17 00:00:00 2001 From: David Meza Date: Thu, 15 Jun 2017 07:11:35 -0500 Subject: PLT-6481 Create platform route and logic to be able to DM a user by email or username (#6310) * Add logic to be able to DM a user by email or username * PLT-6481 update DM url to be in the format https://servername.com/teamname/messages/xxxxxxxx * PLT-6481 Adding logic to get user by full email * PLT-6481 logic for routes /messages/user_id and /messages/id1_id2 to redirect to /messages/@username * PLT-6481 logic for GM route /messages/generated_id --- webapp/routes/route_team.jsx | 132 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) (limited to 'webapp/routes') diff --git a/webapp/routes/route_team.jsx b/webapp/routes/route_team.jsx index fe2b0050c..c7ccc5392 100644 --- a/webapp/routes/route_team.jsx +++ b/webapp/routes/route_team.jsx @@ -9,11 +9,16 @@ import TeamStore from 'stores/team_store.jsx'; import UserStore from 'stores/user_store.jsx'; import * as GlobalActions from 'actions/global_actions.jsx'; import {loadStatusesForChannelAndSidebar} from 'actions/status_actions.jsx'; +import {openDirectChannelToUser} from 'actions/channel_actions.jsx'; import {reconnect} from 'actions/websocket_actions.jsx'; +import AppDispatcher from 'dispatcher/app_dispatcher.jsx'; import Constants from 'utils/constants.jsx'; +const ActionTypes = Constants.ActionTypes; import * as AsyncClient from 'utils/async_client.jsx'; +import Client from 'client/web_client.jsx'; import ChannelStore from 'stores/channel_store.jsx'; import BrowserStore from 'stores/browser_store.jsx'; +import * as Utils from 'utils/utils.jsx'; import emojiRoute from 'routes/route_emoji.jsx'; import integrationsRoute from 'routes/route_integrations.jsx'; @@ -104,7 +109,8 @@ function preNeedsTeam(nextState, replace, callback) { GlobalActions.emitCloseRightHandSide(); if (nextState.location.pathname.indexOf('/channels/') > -1 || - nextState.location.pathname.indexOf('/pl/') > -1) { + nextState.location.pathname.indexOf('/pl/') > -1 || + nextState.location.pathname.indexOf('/messages/') > -1) { AsyncClient.getMyTeamsUnread(); fetchMyChannelsAndMembers(team.id)(dispatch, getState); } @@ -147,6 +153,117 @@ function onPermalinkEnter(nextState, replace, callback) { ); } +/** +* identifier may either be: +* - A DM user_id length 26 chars +* - A DM channel_id (id1_id2) length 54 chars +* - A GM generated_id length 40 chars +* - A username that starts with an @ sign +* - An email containing an @ sign +**/ +function onChannelByIdentifierEnter(state, replace, callback) { + const {identifier} = state.params; + if (identifier.indexOf('@') === -1) { + // DM user_id or id1_id2 identifier + if (identifier.length === 26 || identifier.length === 54) { + const userId = (identifier.length === 26) ? identifier : Utils.getUserIdFromChannelId(identifier); + const teammate = UserStore.getProfile(userId); + if (teammate) { + replace(`/${state.params.team}/messages/@${teammate.username}`); + callback(); + } else { + Client.getUser( + userId, + (profile) => { + replace(`/${state.params.team}/messages/@${profile.username}`); + callback(); + }, () => { + handleError(state, replace, callback); + } + ); + } + + // GM generated_id identifier + } else if (identifier.length === 40) { + const channel = ChannelStore.getByName(identifier); + if (channel) { + loadNewGMIfNeeded(channel.id); + GlobalActions.emitChannelClickEvent(channel); + callback(); + } else { + joinChannel(UserStore.getCurrentId(), TeamStore.getCurrentId(), null, identifier)(dispatch, getState).then( + (data) => { + if (data) { + GlobalActions.emitChannelClickEvent(data.channel); + callback(); + } else if (data == null) { + handleError(state, replace, callback); + } + } + ); + } + } else { + handleError(state, replace, callback); + } + } else { + function success(profile) { + AppDispatcher.handleServerAction({ + type: ActionTypes.RECEIVED_PROFILE, + profile + }); + directChannelToUser(profile, state, replace, callback); + } + + function error() { + handleError(state, replace, callback); + } + + if (identifier.indexOf('@') === 0) { // @username identifier + const username = identifier.slice(1, identifier.length); + const teammate = UserStore.getProfileByUsername(username); + if (teammate) { + directChannelToUser(teammate, state, replace, callback); + } else { + Client.getByUsername(username, success, error); + } + } else if (identifier.indexOf('@') > 0) { // email identifier + const email = identifier; + const teammate = UserStore.getProfileByEmail(email); + if (teammate) { + directChannelToUser(teammate, state, replace, callback); + } else { + Client.getByEmail(email, success, error); + } + } + } +} + +function directChannelToUser(profile, state, replace, callback) { + openDirectChannelToUser( + profile.id, + (channel) => { + AppDispatcher.handleServerAction({ + type: ActionTypes.RECEIVED_CHANNEL, + channel + }); + GlobalActions.emitChannelClickEvent(channel); + callback(); + }, + () => { + handleError(state, replace, callback); + } + ); +} + +function handleError(state, replace, callback) { + if (state.params.team) { + replace(`/${state.params.team}/channels/${Constants.DEFAULT_CHANNEL}`); + } else { + replace('/'); + } + callback(); +} + export default { path: ':team', onEnter: preNeedsTeam, @@ -185,6 +302,19 @@ export default { ); } }, + { + path: 'messages/:identifier', + onEnter: onChannelByIdentifierEnter, + getComponents: (location, callback) => { + Promise.all([ + System.import('components/team_sidebar'), + System.import('components/sidebar.jsx'), + System.import('components/channel_view.jsx') + ]).then( + (comarr) => callback(null, {team_sidebar: comarr[0].default, sidebar: comarr[1].default, center: comarr[2].default}) + ); + } + }, { path: 'tutorial', getComponents: (location, callback) => { -- cgit v1.2.3-1-g7c22