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
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
0e89d9be1d
Коммит
98ac903fce
@@ -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) => {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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];
|
||||
|
||||
Ссылка в новой задаче
Block a user