summaryrefslogtreecommitdiffstats
path: root/webapp
diff options
context:
space:
mode:
authorDavid Meza <dmeza@users.noreply.github.com>2017-06-15 07:11:35 -0500
committerJoram Wilander <jwawilander@gmail.com>2017-06-15 08:11:35 -0400
commit98ac903fce24418538edbec77a218bcac9e20cd2 (patch)
tree794595c84946be50d44b11651232d2e490d6a189 /webapp
parent0e89d9be1d6a2a1ca470f9ca92e0d59e5945ca18 (diff)
downloadchat-98ac903fce24418538edbec77a218bcac9e20cd2.tar.gz
chat-98ac903fce24418538edbec77a218bcac9e20cd2.tar.bz2
chat-98ac903fce24418538edbec77a218bcac9e20cd2.zip
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
Diffstat (limited to 'webapp')
-rw-r--r--webapp/routes/route_team.jsx132
-rw-r--r--webapp/stores/user_store.jsx4
-rw-r--r--webapp/utils/utils.jsx7
3 files changed, 141 insertions, 2 deletions
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,
@@ -186,6 +303,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) => {
Promise.all([
diff --git a/webapp/stores/user_store.jsx b/webapp/stores/user_store.jsx
index a99c4b37a..b6e867443 100644
--- a/webapp/stores/user_store.jsx
+++ b/webapp/stores/user_store.jsx
@@ -232,6 +232,10 @@ class UserStoreClass extends EventEmitter {
return Selectors.getUsersByUsername(store.getState());
}
+ getProfileByEmail(email) {
+ return Selectors.getUsersByEmail(store.getState())[email];
+ }
+
getActiveOnlyProfiles(skipCurrent) {
const active = {};
const profiles = this.getProfiles();
diff --git a/webapp/utils/utils.jsx b/webapp/utils/utils.jsx
index 1f3716039..9254b17e3 100644
--- a/webapp/utils/utils.jsx
+++ b/webapp/utils/utils.jsx
@@ -1099,7 +1099,12 @@ export function getDirectChannelName(id, otherId) {
// Used to get the id of the other user from a DM channel
export function getUserIdFromChannelName(channel) {
- var ids = channel.name.split('__');
+ return getUserIdFromChannelId(channel.name);
+}
+
+// Used to get the id of the other user from a DM channel id (id1_id2)
+export function getUserIdFromChannelId(channelId) {
+ var ids = channelId.split('__');
var otherUserId = '';
if (ids[0] === UserStore.getCurrentId()) {
otherUserId = ids[1];