Merge 2.5.0rc1 from upstream

This commit is contained in:
Mike Barnes 2018-08-31 23:36:49 +10:00
commit c29f828897
520 changed files with 15340 additions and 5799 deletions

View file

@ -28,6 +28,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
style: PropTypes.object,
items: PropTypes.array.isRequired,
value: PropTypes.string.isRequired,
placement: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
};
@ -119,7 +120,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
render () {
const { mounted } = this.state;
const { style, items, value } = this.props;
const { style, items, placement, value } = this.props;
return (
<Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
@ -127,7 +128,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
// It should not be transformed when mounting because the resulting
// size will be used to determine the coordinate of the menu by
// react-overlays
<div className='privacy-dropdown__dropdown' style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} role='listbox' ref={this.setRef}>
<div className={`privacy-dropdown__dropdown ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} role='listbox' ref={this.setRef}>
{items.map(item => (
<div role='option' tabIndex='0' key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}>
<div className='privacy-dropdown__option__icon'>
@ -226,7 +227,7 @@ export default class PrivacyDropdown extends React.PureComponent {
const valueOption = this.options.find(item => item.value === value);
return (
<div className={classNames('privacy-dropdown', { active: open })} onKeyDown={this.handleKeyDown}>
<div className={classNames('privacy-dropdown', placement, { active: open })} onKeyDown={this.handleKeyDown}>
<div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === 0 })}>
<IconButton
className='privacy-dropdown__value-icon'
@ -247,6 +248,7 @@ export default class PrivacyDropdown extends React.PureComponent {
value={value}
onClose={this.handleClose}
onChange={this.handleChange}
placement={placement}
/>
</Overlay>
</div>

View file

@ -30,7 +30,7 @@ export default class ReplyIndicator extends ImmutablePureComponent {
}
handleAccountClick = (e) => {
if (e.button === 0) {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
}

View file

@ -20,6 +20,7 @@ export default class Upload extends ImmutablePureComponent {
onUndo: PropTypes.func.isRequired,
onDescriptionChange: PropTypes.func.isRequired,
onOpenFocalPoint: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
};
state = {
@ -28,6 +29,17 @@ export default class Upload extends ImmutablePureComponent {
dirtyDescription: null,
};
handleKeyDown = (e) => {
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
this.handleSubmit();
}
}
handleSubmit = () => {
this.handleInputBlur();
this.props.onSubmit();
}
handleUndoClick = () => {
this.props.onUndo(this.props.media.get('id'));
}
@ -93,6 +105,7 @@ export default class Upload extends ImmutablePureComponent {
onFocus={this.handleInputFocus}
onChange={this.handleInputChange}
onBlur={this.handleInputBlur}
onKeyDown={this.handleKeyDown}
/>
</label>
</div>

View file

@ -7,7 +7,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes';
const messages = defineMessages({
upload: { id: 'upload_button.label', defaultMessage: 'Add media' },
upload: { id: 'upload_button.label', defaultMessage: 'Add media (JPEG, PNG, GIF, WebM, MP4)' },
});
const makeMapStateToProps = () => {

View file

@ -2,6 +2,7 @@ import { connect } from 'react-redux';
import Upload from '../components/upload';
import { undoUploadCompose, changeUploadCompose } from '../../../actions/compose';
import { openModal } from '../../../actions/modal';
import { submitCompose } from '../../../actions/compose';
const mapStateToProps = (state, { id }) => ({
media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id),
@ -21,6 +22,10 @@ const mapDispatchToProps = dispatch => ({
dispatch(openModal('FOCAL_POINT', { id }));
},
onSubmit () {
dispatch(submitCompose());
},
});
export default connect(mapStateToProps, mapDispatchToProps)(Upload);

View file

@ -22,6 +22,7 @@ const messages = defineMessages({
community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new toot' },
});
const mapStateToProps = (state, ownProps) => ({
@ -95,7 +96,7 @@ export default class Compose extends React.PureComponent {
}
return (
<div className='drawer'>
<div className='drawer' role='region' aria-label={intl.formatMessage(messages.compose)}>
{header}
{(multiColumn || isSearchPage) && <SearchContainer /> }