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
Этот коммит содержится в:
Joram Wilander
2017-06-15 11:05:43 -04:00
коммит произвёл GitHub
родитель c0a0065472
Коммит 528f2dc6c3
52 изменённых файлов: 784 добавлений и 612 удалений

Просмотреть файл

@@ -21,16 +21,18 @@ export default function CommentIcon(props) {
iconStyle = iconStyle + ' ' + props.searchStyle;
}
let commentIconId = props.channelId + props.idPrefix;
let selectorId = props.idPrefix;
if (props.idCount > -1) {
commentIconId += props.idCount;
selectorId += props.idCount;
}
const id = Utils.createSafeId(props.idPrefix + '_' + props.id);
return (
<a
id={Utils.createSafeId(commentIconId)}
id={id}
href='#'
className={iconStyle}
className={iconStyle + ' ' + selectorId}
onClick={props.handleCommentClick}
>
<span
@@ -48,12 +50,12 @@ CommentIcon.propTypes = {
handleCommentClick: PropTypes.func.isRequired,
searchStyle: PropTypes.string,
commentCount: PropTypes.number,
channelId: PropTypes.string
id: PropTypes.string
};
CommentIcon.defaultProps = {
idCount: -1,
searchStyle: '',
commentCount: 0,
channelId: ''
};
id: ''
};

Просмотреть файл

@@ -142,11 +142,7 @@ export default class CreateComment extends React.Component {
handleSubmit(e) {
e.preventDefault();
if (this.state.uploadsInProgress.length > 0) {
return;
}
if (this.state.submitting) {
if (this.state.uploadsInProgress.length > 0 || this.state.submitting) {
return;
}

Просмотреть файл

@@ -115,6 +115,10 @@ export default class CreatePost extends React.Component {
e.preventDefault();
}
if (this.state.uploadsInProgress.length > 0 || this.state.submitting) {
return;
}
const post = {};
post.file_ids = [];
post.message = this.state.message;
@@ -493,7 +497,9 @@ export default class CreatePost extends React.Component {
return;
}
const lastPostEl = document.getElementById(this.state.channelId + 'commentIcon0');
const latestNonEphemeralPost = PostStore.getLatestNonEphemeralPost(this.state.channelId);
const latestNonEphemeralPostId = latestNonEphemeralPost == null ? '' : latestNonEphemeralPost.id;
const lastPostEl = document.getElementById(`commentIcon_${this.state.channelId}_${latestNonEphemeralPostId}`);
if (!e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey && e.keyCode === KeyCodes.UP && this.state.message === '') {
e.preventDefault();
@@ -761,7 +767,7 @@ export default class CreatePost extends React.Component {
<ConfirmModal
title={notifyAllTitle}
message={notifyAllMessage}
confirmButton={notifyAllConfirm}
confirmButtonText={notifyAllConfirm}
show={this.state.showConfirmModal}
onConfirm={this.handleNotifyAllConfirmation}
onCancel={this.handleNotifyModalCancel}

Просмотреть файл

@@ -45,8 +45,6 @@ import {Link} from 'react-router/es6';
import PropTypes from 'prop-types';
import React from 'react';
import store from 'stores/redux_store.jsx';
import {getMyTeams} from 'mattermost-redux/selectors/entities/teams';
export default class Navbar extends React.Component {
constructor(props) {
@@ -220,14 +218,9 @@ export default class Navbar extends React.Component {
}
handleQuickSwitchKeyPress(e) {
if (Utils.cmdOrCtrlPressed(e, true) && !e.shiftKey && e.keyCode === Constants.KeyCodes.K) {
e.preventDefault();
if (e.altKey) {
if (getMyTeams(store.getState()).length <= 1) {
return;
}
this.toggleQuickSwitchModal('team');
} else {
if (Utils.cmdOrCtrlPressed(e) && !e.shiftKey && e.keyCode === Constants.KeyCodes.K) {
if (!e.altKey) {
e.preventDefault();
this.toggleQuickSwitchModal('channel');
}
}

Просмотреть файл

@@ -94,7 +94,7 @@ export default class PostInfo extends React.Component {
idCount={idCount}
handleCommentClick={this.props.handleCommentClick}
commentCount={this.props.commentCount}
channelId={ChannelStore.getCurrentId()}
id={ChannelStore.getCurrentId() + '_' + post.id}
/>
);

Просмотреть файл

@@ -2,14 +2,13 @@
// See License.txt for license information.
import {connect} from 'react-redux';
import {getMyTeams} from 'mattermost-redux/selectors/entities/teams';
import QuickSwitchModal from './quick_switch_modal.jsx';
function mapStateToProps(state, ownProps) {
return {
...ownProps,
showTeamSwitcher: getMyTeams(state).length > 1
showTeamSwitcher: false
};
}

Просмотреть файл

@@ -22,7 +22,6 @@ import store from 'stores/redux_store.jsx';
const getState = store.getState;
import {getChannel} from 'mattermost-redux/selectors/entities/channels';
import {getUserByUsername} from 'mattermost-redux/selectors/entities/users';
const CHANNEL_MODE = 'channel';
const TEAM_MODE = 'team';
@@ -141,24 +140,22 @@ export default class QuickSwitchModal extends React.PureComponent {
if (this.state.mode === CHANNEL_MODE) {
const selectedChannel = selected.channel;
if (selectedChannel.type === Constants.DM_CHANNEL) {
const user = getUserByUsername(getState(), selectedChannel.name);
if (user) {
openDirectChannelToUser(
user.id,
(ch) => {
channel = ch;
this.switchToChannel(channel);
},
() => {
channel = null;
this.switchToChannel(channel);
}
);
}
} else {
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);
@@ -287,7 +284,7 @@ export default class QuickSwitchModal extends React.PureComponent {
help = (
<FormattedMessage
id='quick_switch_modal.help_no_team'
defaultMessage='Start typing then use ↑↓ to browse, ↵ to select, and ESC to dismiss.'
defaultMessage='Type to find a channel. Use ↑↓ to browse, ↵ to select, ESC to dismiss.'
/>
);
}

Просмотреть файл

@@ -86,7 +86,7 @@ export default class ResetStatusModal extends React.PureComponent {
const userStatus = toTitleCase(this.state.currentUserStatus.status || '');
const manualStatusTitle = (
<FormattedMessage
id='modal.manual_status.title'
id='modal.manaul_status.title'
defaultMessage='Your status is set to "{status}"'
values={{
status: userStatus
@@ -96,21 +96,21 @@ export default class ResetStatusModal extends React.PureComponent {
const manualStatusMessage = (
<FormattedMessage
id='modal.manual_status.message'
id='modal.manaul_status.message'
defaultMessage='Would you like to switch your status to "Online"?'
/>
);
const manualStatusButton = (
<FormattedMessage
id='modal.manual_status.button'
id='modal.manaul_status.button'
defaultMessage='Yes, set my status to "Online"'
/>
);
const manualStatusCancel = (
<FormattedMessage
id='modal.manual_status.cancel'
id='modal.manaul_status.cancel'
defaultMessage='No, keep it as "{status}"'
values={{
status: userStatus
@@ -120,7 +120,7 @@ export default class ResetStatusModal extends React.PureComponent {
const manualStatusCheckbox = (
<FormattedMessage
id='modal.manual_status.ask'
id='modal.manaul_status.ask'
defaultMessage='Do not ask me again'
/>
);

Просмотреть файл

@@ -54,6 +54,7 @@ export default class ChannelMentionProvider extends Provider {
constructor() {
super();
this.lastTermWithNoResults = '';
this.lastCompletedWord = '';
}
@@ -65,6 +66,11 @@ export default class ChannelMentionProvider extends Provider {
return false;
}
if (this.lastTermWithNoResults && pretext.startsWith(this.lastTermWithNoResults)) {
// Just give up since we know it won't return any results
return false;
}
if (this.lastCompletedWord && captured[0].startsWith(this.lastCompletedWord)) {
// It appears we're still matching a channel handle that we already completed
return false;
@@ -79,12 +85,14 @@ export default class ChannelMentionProvider extends Provider {
autocompleteChannels(
prefix,
(data) => {
(channels) => {
if (this.shouldCancelDispatch(prefix)) {
return;
}
const channels = data;
if (channels.length === 0) {
this.lastTermWithNoResults = pretext;
}
// Wrap channels in an outer object to avoid overwriting the 'type' property.
const wrappedChannels = [];

Просмотреть файл

@@ -109,7 +109,7 @@ export default class SwitchChannelProvider extends Provider {
// Dispatch suggestions for local data
const channels = getChannelsInCurrentTeam(getState()).concat(getGroupChannels(getState()));
const users = Object.assign([], searchProfiles(getState(), channelPrefix, true), true);
const users = Object.assign([], searchProfiles(getState(), channelPrefix, true));
this.formatChannelsAndDispatch(channelPrefix, suggestionId, channels, users, true);
// Fetch data from the server and dispatch
@@ -141,7 +141,7 @@ export default class SwitchChannelProvider extends Provider {
return;
}
const users = Object.assign([], searchProfiles(getState(), channelPrefix, true), usersFromServer);
const users = Object.assign([], searchProfiles(getState(), channelPrefix, true), usersFromServer.users);
const channels = getChannelsInCurrentTeam(getState()).concat(getGroupChannels(getState())).concat(channelsFromServer);
this.formatChannelsAndDispatch(channelPrefix, suggestionId, channels, users);
}