Files
mattermost/webapp/routes/route_team.jsx
2017-06-27 20:49:03 -07:00

348 lines
13 KiB
JavaScript

// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import $ from 'jquery';
import * as RouteUtils from 'routes/route_utils.jsx';
import {browserHistory} from 'react-router/es6';
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 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';
import {loadNewDMIfNeeded, loadNewGMIfNeeded, loadProfilesForSidebar} from 'actions/user_actions.jsx';
// Redux actions
import store from 'stores/redux_store.jsx';
const dispatch = store.dispatch;
const getState = store.getState;
import {fetchMyChannelsAndMembers, joinChannel} from 'mattermost-redux/actions/channels';
import {getMyTeamUnreads} from 'mattermost-redux/actions/teams';
import {getUser, getUserByUsername, getUserByEmail} from 'mattermost-redux/actions/users';
function onChannelEnter(nextState, replace, callback) {
doChannelChange(nextState, replace, callback);
}
function doChannelChange(state, replace, callback) {
let channel;
if (state.location.query.fakechannel) {
channel = JSON.parse(state.location.query.fakechannel);
} else {
channel = ChannelStore.getByName(state.params.channel);
if (channel && channel.type === Constants.DM_CHANNEL) {
loadNewDMIfNeeded(channel.id);
} else if (channel && channel.type === Constants.GM_CHANNEL) {
loadNewGMIfNeeded(channel.id);
}
if (!channel) {
joinChannel(UserStore.getCurrentId(), TeamStore.getCurrentId(), null, state.params.channel)(dispatch, getState).then(
(data) => {
if (data) {
GlobalActions.emitChannelClickEvent(data.channel);
} else if (data == null) {
if (state.params.team) {
replace('/' + state.params.team + '/channels/town-square');
} else {
replace('/');
}
}
callback();
}
);
return;
}
}
GlobalActions.emitChannelClickEvent(channel);
callback();
}
let wakeUpInterval;
let lastTime = (new Date()).getTime();
const WAKEUP_CHECK_INTERVAL = 30000; // 30 seconds
const WAKEUP_THRESHOLD = 60000; // 60 seconds
function preNeedsTeam(nextState, replace, callback) {
if (RouteUtils.checkIfMFARequired(nextState)) {
browserHistory.push('/mfa/setup');
return;
}
clearInterval(wakeUpInterval);
wakeUpInterval = setInterval(() => {
const currentTime = (new Date()).getTime();
if (currentTime > (lastTime + WAKEUP_THRESHOLD)) { // ignore small delays
console.log('computer woke up - fetching latest'); //eslint-disable-line no-console
reconnect(false);
}
lastTime = currentTime;
}, WAKEUP_CHECK_INTERVAL);
// First check to make sure you're in the current team
// for the current url.
const teamName = nextState.params.team;
const team = TeamStore.getByName(teamName);
if (!team) {
browserHistory.push('/?redirect_to=' + encodeURIComponent(nextState.location.pathname));
return;
}
// If current team is set, then this is not first load
// The first load action pulls team unreads
if (TeamStore.getCurrentId()) {
getMyTeamUnreads()(dispatch, getState);
}
TeamStore.saveMyTeam(team);
BrowserStore.setGlobalItem('team', team.id);
TeamStore.emitChange();
GlobalActions.emitCloseRightHandSide();
const d1 = $.Deferred(); //eslint-disable-line new-cap
fetchMyChannelsAndMembers(team.id)(dispatch, getState).then(
() => {
loadStatusesForChannelAndSidebar();
loadProfilesForSidebar();
d1.resolve();
}
);
$.when(d1).done(() => {
callback();
});
}
function selectLastChannel(nextState, replace, callback) {
const team = TeamStore.getByName(nextState.params.team);
const channelId = BrowserStore.getGlobalItem(team.id);
const channel = ChannelStore.getChannelById(channelId);
let channelName = 'town-square';
if (channel) {
channelName = channel.name;
}
replace(`/${team.name}/channels/${channelName}`);
callback();
}
function onPermalinkEnter(nextState, replace, callback) {
const postId = nextState.params.postid;
GlobalActions.emitPostFocusEvent(
postId,
() => 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 {
getUser(userId)(dispatch, getState).then(
(profile) => {
if (profile) {
replace(`/${state.params.team}/messages/@${profile.username}`);
callback();
} else if (profile == null) {
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 {
getUserByUsername(username)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
} else if (data == null && error) {
const serverError = getState().requests.users.getUserByUsername.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
}
} else if (identifier.indexOf('@') > 0) { // email identifier
const email = identifier;
const teammate = UserStore.getProfileByEmail(email);
if (teammate) {
directChannelToUser(teammate, state, replace, callback);
} else {
getUserByEmail(email)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
} else if (data == null && error) {
const serverError = getState().requests.users.getUser.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
}
}
}
}
function directChannelToUser(profile, state, replace, callback) {
openDirectChannelToUser(
profile.id,
(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,
indexRoute: {onEnter: selectLastChannel},
childRoutes: [
integrationsRoute,
emojiRoute,
{
getComponents: (location, callback) => {
System.import('components/needs_team').then(RouteUtils.importComponentSuccess(callback));
},
childRoutes: [
{
path: 'channels/:channel',
onEnter: onChannelEnter,
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: 'pl/:postid',
onEnter: onPermalinkEnter,
getComponents: (location, callback) => {
Promise.all([
System.import('components/team_sidebar'),
System.import('components/sidebar.jsx'),
System.import('components/permalink_view.jsx')
]).then(
(comarr) => callback(null, {team_sidebar: comarr[0].default, sidebar: comarr[1].default, center: comarr[2].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([
System.import('components/team_sidebar'),
System.import('components/sidebar.jsx'),
System.import('components/tutorial/tutorial_view.jsx')
]).then(
(comarr) => callback(null, {team_sidebar: comarr[0].default, sidebar: comarr[1].default, center: comarr[2].default})
);
}
}
]
}
]
};