Files
mostlymatter/webapp/components/quick_switch_modal/quick_switch_modal.jsx
Joram Wilander 528f2dc6c3 Merge release-3.10 into master (#6654)
* PLT-6787 Fixed being able to send a post before files finished uploading (#6617)

* Fix quick switcher for channels/users not stored locally (#6610)

* Fix button text on confirm mention modal (#6609)

* fix post delete permission of channel admin (#6608)

* open comment thread for the most recent reply-able message (#6605)

* Use mutex flag with yarn to prevent concurrent builds interfering (#6619)

* Use mutex flag with yarn to prevent concurrent builds interfering

* Remove yarn mutex file with clean

* Minor bug fixes (#6615)

* PLT-6774 - Fixing color for offline icon

* PLT-6784 - Fixing status icon

* Fixing icon margin

* Updating caret position

* PLT-6070 Have ChannelMentionProvider stop searching after a term returns no results (#6620)

* Fixing JS error (#6623)

* Minor bug fixes (#6622)

* PLT-6808 - Updating channel switcher on mobile

* PLT-6743 - Updating scrollbar styling

* Login instead of failing if user exists in OAuth sign-up flow (#6627)

* PLT-6802 Disable team switcher (#6626)

* Disable team switcher

* Fix ESLint errors

* PLT-6807 Ensured select teams page can scroll on iOS (#6630)

* Do not redirect from account switch pages on 401 (#6631)

* Fixing loadtest command and renaming to /test (#6624)

* PLT-6820 Update mattermost-redux dependency (#6632)

* translations PR 20170612 (#6629)

* Bump HTTP client timeout to 30 seconds (#6633)

* For team unreads return empty array instead of null (#6636)

* PLT-6831 Fix status modal localization IDs (#6637)

* Fix status modal localization IDs

* Update test snapshot
2017-06-15 11:05:43 -04:00

326 строки
10 KiB
JavaScript

// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import SuggestionList from 'components/suggestion/suggestion_list.jsx';
import SuggestionBox from 'components/suggestion/suggestion_box.jsx';
import SwitchChannelProvider from 'components/suggestion/switch_channel_provider.jsx';
import SwitchTeamProvider from 'components/suggestion/switch_team_provider.jsx';
import {goToChannel, openDirectChannelToUser} from 'actions/channel_actions.jsx';
import Constants from 'utils/constants.jsx';
import * as Utils from 'utils/utils.jsx';
import React from 'react';
import PropTypes from 'prop-types';
import {browserHistory} from 'react-router/es6';
import {Modal} from 'react-bootstrap';
import {FormattedMessage} from 'react-intl';
// Redux actions
import store from 'stores/redux_store.jsx';
const getState = store.getState;
import {getChannel} from 'mattermost-redux/selectors/entities/channels';
const CHANNEL_MODE = 'channel';
const TEAM_MODE = 'team';
export default class QuickSwitchModal extends React.PureComponent {
static propTypes = {
/**
* The mode to start in when showing the modal, either 'channel' or 'team'
*/
initialMode: PropTypes.string.isRequired,
/**
* Set to show the modal
*/
show: PropTypes.bool.isRequired,
/**
* The function called to hide the modal
*/
onHide: PropTypes.func.isRequired,
/**
* Set to show team switcher
*/
showTeamSwitcher: PropTypes.bool
}
static defaultProps = {
initialMode: CHANNEL_MODE
}
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onShow = this.onShow.bind(this);
this.onHide = this.onHide.bind(this);
this.onExited = this.onExited.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.switchToChannel = this.switchToChannel.bind(this);
this.switchMode = this.switchMode.bind(this);
this.focusTextbox = this.focusTextbox.bind(this);
this.enableChannelProvider = this.enableChannelProvider.bind(this);
this.enableTeamProvider = this.enableTeamProvider.bind(this);
this.channelProviders = [new SwitchChannelProvider()];
this.teamProviders = [new SwitchTeamProvider()];
this.state = {
text: '',
mode: props.initialMode
};
}
componentDidUpdate(prevProps) {
if (this.props.show && !prevProps.show) {
this.focusTextbox();
}
}
componentWillReceiveProps(nextProps) {
if (!this.props.show && nextProps.show) {
this.setState({mode: nextProps.initialMode, text: ''});
}
}
focusTextbox() {
if (this.refs.switchbox == null) {
return;
}
const textbox = this.refs.switchbox.getTextbox();
textbox.focus();
Utils.placeCaretAtEnd(textbox);
}
onShow() {
this.setState({
text: ''
});
}
onHide() {
this.setState({
text: ''
});
this.props.onHide();
}
onExited() {
setTimeout(() => {
document.querySelector('#post_textbox').focus();
});
}
onChange(e) {
this.setState({text: e.target.value});
}
handleKeyDown(e) {
if (e.keyCode === Constants.KeyCodes.TAB) {
e.preventDefault();
this.switchMode();
}
}
handleSubmit(selected) {
let channel = null;
if (!selected) {
return;
}
if (this.state.mode === CHANNEL_MODE) {
const selectedChannel = selected.channel;
if (selectedChannel.type === Constants.DM_CHANNEL) {
openDirectChannelToUser(
selectedChannel.id,
(ch) => {
channel = ch;
this.switchToChannel(channel);
},
() => {
channel = null;
this.switchToChannel(channel);
}
);
} else if (selectedChannel.type === Constants.GM_CHANNEL) {
channel = getChannel(getState(), selectedChannel.id);
this.switchToChannel(channel);
} else {
this.switchToChannel(selectedChannel);
}
} else {
browserHistory.push('/' + selected.name);
this.onHide();
}
}
switchToChannel(channel) {
if (channel != null) {
goToChannel(channel);
this.onHide();
}
}
enableChannelProvider() {
this.channelProviders[0].disableDispatches = false;
this.teamProviders[0].disableDispatches = true;
}
enableTeamProvider() {
this.teamProviders[0].disableDispatches = false;
this.channelProviders[0].disableDispatches = true;
}
switchMode() {
if (this.state.mode === CHANNEL_MODE && this.props.showTeamSwitcher) {
this.enableTeamProvider();
this.setState({mode: TEAM_MODE});
} else if (this.state.mode === TEAM_MODE) {
this.enableChannelProvider();
this.setState({mode: CHANNEL_MODE});
}
}
render() {
let providers = this.channelProviders;
let header;
let renderDividers = true;
let channelShortcut = 'quick_switch_modal.channelsShortcut.windows';
let defaultChannelShortcut = 'CTRL+K';
if (Utils.isMac()) {
channelShortcut = 'quick_switch_modal.channelsShortcut.mac';
defaultChannelShortcut = 'CMD+K';
}
let teamShortcut = 'quick_switch_modal.teamsShortcut.windows';
let defaultTeamShortcut = 'CTRL+ALT+K';
if (Utils.isMac()) {
teamShortcut = 'quick_switch_modal.teamsShortcut.mac';
defaultTeamShortcut = 'CMD+ALT+K';
}
if (this.props.showTeamSwitcher) {
let channelsActiveClass = '';
let teamsActiveClass = '';
if (this.state.mode === TEAM_MODE) {
providers = this.teamProviders;
renderDividers = false;
teamsActiveClass = 'active';
} else {
channelsActiveClass = 'active';
}
header = (
<div className='nav nav-tabs'>
<li className={channelsActiveClass}>
<a
href='#'
onClick={(e) => {
e.preventDefault();
this.enableChannelProvider();
this.setState({mode: 'channel'});
this.focusTextbox();
}}
>
<FormattedMessage
id='quick_switch_modal.channels'
defaultMessage='Channels'
/>
<span className='small'>
<FormattedMessage
id={channelShortcut}
defaultMessage={defaultChannelShortcut}
/>
</span>
</a>
</li>
<li className={teamsActiveClass}>
<a
href='#'
onClick={(e) => {
e.preventDefault();
this.enableTeamProvider();
this.setState({mode: 'team'});
this.focusTextbox();
}}
>
<FormattedMessage
id='quick_switch_modal.teams'
defaultMessage='Teams'
/>
<span className='small'>
<FormattedMessage
id={teamShortcut}
defaultMessage={defaultTeamShortcut}
/>
</span>
</a>
</li>
</div>
);
}
let help;
if (Utils.isMobile()) {
help = null;
} else if (this.props.showTeamSwitcher) {
help = (
<FormattedMessage
id='quick_switch_modal.help'
defaultMessage='Start typing then use TAB to toggle channels/teams, ↑↓ to browse, ↵ to select, and ESC to dismiss.'
/>
);
} else {
help = (
<FormattedMessage
id='quick_switch_modal.help_no_team'
defaultMessage='Type to find a channel. Use ↑↓ to browse, ↵ to select, ESC to dismiss.'
/>
);
}
return (
<Modal
dialogClassName='channel-switch-modal modal--overflow'
ref='modal'
show={this.props.show}
onHide={this.onHide}
onExited={this.onExited}
>
<Modal.Header closeButton={true}/>
<Modal.Body>
{header}
<div className='modal__hint hidden-xs'>
{help}
</div>
<SuggestionBox
ref='switchbox'
className='form-control focused'
type='input'
onChange={this.onChange}
value={this.state.text}
onKeyDown={this.handleKeyDown}
onItemSelected={this.handleSubmit}
listComponent={SuggestionList}
maxLength='64'
providers={providers}
listStyle='bottom'
completeOnTab={false}
renderDividers={renderDividers}
/>
</Modal.Body>
</Modal>
);
}
}