Merge branch 'compose-refactor' into 'master'
Fix composer issues Closes #95, #86, and #116 See merge request soapbox-pub/soapbox-fe!25
This commit is contained in:
commit
6f76e1796b
3 changed files with 18 additions and 50 deletions
|
@ -1,5 +1,4 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import CharacterCounter from './character_counter';
|
||||
import Button from '../../../components/button';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
@ -32,19 +31,11 @@ const messages = defineMessages({
|
|||
publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
maxTootChars: state.getIn(['instance', 'max_toot_chars']),
|
||||
};
|
||||
};
|
||||
|
||||
export default @connect(mapStateToProps)
|
||||
@injectIntl
|
||||
export default @injectIntl
|
||||
class ComposeForm extends ImmutablePureComponent {
|
||||
|
||||
state = {
|
||||
composeFocused: false,
|
||||
caretPosition: 0,
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
|
@ -60,7 +51,6 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
spoilerText: PropTypes.string,
|
||||
focusDate: PropTypes.instanceOf(Date),
|
||||
caretPosition: PropTypes.number,
|
||||
preselectDate: PropTypes.instanceOf(Date),
|
||||
isSubmitting: PropTypes.bool,
|
||||
isChangingUpload: PropTypes.bool,
|
||||
isUploading: PropTypes.bool,
|
||||
|
@ -87,9 +77,6 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
|
||||
handleChange = (e) => {
|
||||
this.props.onChange(e.target.value);
|
||||
this.setState({
|
||||
caretPosition: e.target.selectionStart,
|
||||
});
|
||||
}
|
||||
|
||||
handleComposeFocus = () => {
|
||||
|
@ -109,8 +96,10 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
return clickableAreaRef ? clickableAreaRef.current : this.form;
|
||||
}
|
||||
|
||||
shouldCollapse = (e) => {
|
||||
isClickOutside = (e) => {
|
||||
return ![
|
||||
// List of elements that shouldn't collapse the composer when clicked
|
||||
// FIXME: Make this less brittle
|
||||
this.getClickableArea(),
|
||||
document.querySelector('.privacy-dropdown__dropdown'),
|
||||
document.querySelector('.emoji-picker-dropdown__menu'),
|
||||
|
@ -119,7 +108,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
handleClick = (e) => {
|
||||
if (this.shouldCollapse(e)) {
|
||||
if (this.isClickOutside(e)) {
|
||||
this.handleClickOutside();
|
||||
}
|
||||
}
|
||||
|
@ -168,43 +157,25 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
this.props.onChangeSpoilerText(e.target.value);
|
||||
}
|
||||
|
||||
doFocus = () => {
|
||||
if (!this.autosuggestTextarea) return;
|
||||
this.autosuggestTextarea.textarea.focus();
|
||||
}
|
||||
|
||||
setCursor = (start, end = start) => {
|
||||
if (!this.autosuggestTextarea) return;
|
||||
this.autosuggestTextarea.textarea.setSelectionRange(start, end);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('click', this.handleClick, true);
|
||||
this.setCursor(this.props.text.length); // Set cursor at end
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('click', this.handleClick, true);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (!this.autosuggestTextarea) return;
|
||||
|
||||
// This statement does several things:
|
||||
// - If we're beginning a reply, and,
|
||||
// - Replying to zero or one users, places the cursor at the end of the textbox.
|
||||
// - Replying to more than one user, selects any usernames past the first;
|
||||
// this provides a convenient shortcut to drop everyone else from the conversation.
|
||||
let selectionEnd, selectionStart;
|
||||
if (this.props.focusDate !== prevProps.focusDate) {
|
||||
|
||||
if (this.props.preselectDate !== prevProps.preselectDate) {
|
||||
selectionEnd = this.props.text.length;
|
||||
selectionStart = this.props.text.search(/\s/) + 1;
|
||||
} else if (typeof this.state.caretPosition === 'number') {
|
||||
selectionStart = this.state.caretPosition;
|
||||
selectionEnd = this.state.caretPosition;
|
||||
}
|
||||
this.autosuggestTextarea.textarea.setSelectionRange(selectionStart, selectionEnd);
|
||||
this.autosuggestTextarea.textarea.focus();
|
||||
} else {
|
||||
if (this.props.preselectDate !== this.props.focusDate) {
|
||||
selectionStart = selectionEnd = this.props.text.length + 1;
|
||||
this.autosuggestTextarea.textarea.setSelectionRange(selectionStart, selectionEnd);
|
||||
this.autosuggestTextarea.textarea.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setAutosuggestTextarea = (c) => {
|
||||
this.autosuggestTextarea = c;
|
||||
}
|
||||
|
|
|
@ -19,13 +19,13 @@ const mapStateToProps = state => ({
|
|||
privacy: state.getIn(['compose', 'privacy']),
|
||||
focusDate: state.getIn(['compose', 'focusDate']),
|
||||
caretPosition: state.getIn(['compose', 'caretPosition']),
|
||||
preselectDate: state.getIn(['compose', 'preselectDate']),
|
||||
isSubmitting: state.getIn(['compose', 'is_submitting']),
|
||||
isChangingUpload: state.getIn(['compose', 'is_changing_upload']),
|
||||
isUploading: state.getIn(['compose', 'is_uploading']),
|
||||
showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
|
||||
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
|
||||
isModalOpen: state.get('modal').modalType === 'COMPOSE',
|
||||
maxTootChars: state.getIn(['instance', 'max_toot_chars']),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
|
|
@ -54,7 +54,6 @@ const initialState = ImmutableMap({
|
|||
text: '',
|
||||
focusDate: null,
|
||||
caretPosition: null,
|
||||
preselectDate: null,
|
||||
in_reply_to: null,
|
||||
is_composing: false,
|
||||
is_submitting: false,
|
||||
|
@ -237,8 +236,7 @@ export default function compose(state = initialState, action) {
|
|||
case COMPOSE_CHANGE:
|
||||
return state
|
||||
.set('text', action.text)
|
||||
.set('idempotencyKey', uuid())
|
||||
.set('focusDate', new Date());
|
||||
.set('idempotencyKey', uuid());
|
||||
case COMPOSE_COMPOSING_CHANGE:
|
||||
return state.set('is_composing', action.value);
|
||||
case COMPOSE_REPLY:
|
||||
|
@ -248,7 +246,6 @@ export default function compose(state = initialState, action) {
|
|||
map.set('privacy', privacyPreference(action.status.get('visibility'), state.get('default_privacy')));
|
||||
map.set('focusDate', new Date());
|
||||
map.set('caretPosition', null);
|
||||
map.set('preselectDate', new Date());
|
||||
map.set('idempotencyKey', uuid());
|
||||
|
||||
if (action.status.get('spoiler_text').length > 0) {
|
||||
|
|
Loading…
Reference in a new issue