Merge pull request #508 from ThibG/glitch-soc/fixes/remove-leftover-from-attachment-url-insertion
Fix caret position after inserting suggestions
This commit is contained in:
		@@ -56,6 +56,7 @@ function mapStateToProps (state) {
 | 
				
			|||||||
    advancedOptions: state.getIn(['compose', 'advanced_options']),
 | 
					    advancedOptions: state.getIn(['compose', 'advanced_options']),
 | 
				
			||||||
    amUnlocked: !state.getIn(['accounts', me, 'locked']),
 | 
					    amUnlocked: !state.getIn(['accounts', me, 'locked']),
 | 
				
			||||||
    focusDate: state.getIn(['compose', 'focusDate']),
 | 
					    focusDate: state.getIn(['compose', 'focusDate']),
 | 
				
			||||||
 | 
					    caretPosition: state.getIn(['compose', 'caretPosition']),
 | 
				
			||||||
    isSubmitting: state.getIn(['compose', 'is_submitting']),
 | 
					    isSubmitting: state.getIn(['compose', 'is_submitting']),
 | 
				
			||||||
    isUploading: state.getIn(['compose', 'is_uploading']),
 | 
					    isUploading: state.getIn(['compose', 'is_uploading']),
 | 
				
			||||||
    layout: state.getIn(['local_settings', 'layout']),
 | 
					    layout: state.getIn(['local_settings', 'layout']),
 | 
				
			||||||
@@ -117,7 +118,6 @@ const handlers = {
 | 
				
			|||||||
  handleEmoji (data) {
 | 
					  handleEmoji (data) {
 | 
				
			||||||
    const { textarea: { selectionStart } } = this;
 | 
					    const { textarea: { selectionStart } } = this;
 | 
				
			||||||
    const { onInsertEmoji } = this.props;
 | 
					    const { onInsertEmoji } = this.props;
 | 
				
			||||||
    this.caretPos = selectionStart + data.native.length + 1;
 | 
					 | 
				
			||||||
    if (onInsertEmoji) {
 | 
					    if (onInsertEmoji) {
 | 
				
			||||||
      onInsertEmoji(selectionStart, data);
 | 
					      onInsertEmoji(selectionStart, data);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -139,7 +139,6 @@ const handlers = {
 | 
				
			|||||||
  //  Selects a suggestion from the autofill.
 | 
					  //  Selects a suggestion from the autofill.
 | 
				
			||||||
  handleSelect (tokenStart, token, value) {
 | 
					  handleSelect (tokenStart, token, value) {
 | 
				
			||||||
    const { onSelectSuggestion } = this.props;
 | 
					    const { onSelectSuggestion } = this.props;
 | 
				
			||||||
    this.caretPos = null;
 | 
					 | 
				
			||||||
    if (onSelectSuggestion) {
 | 
					    if (onSelectSuggestion) {
 | 
				
			||||||
      onSelectSuggestion(tokenStart, token, value);
 | 
					      onSelectSuggestion(tokenStart, token, value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -191,20 +190,9 @@ class Composer extends React.Component {
 | 
				
			|||||||
    assignHandlers(this, handlers);
 | 
					    assignHandlers(this, handlers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //  Instance variables.
 | 
					    //  Instance variables.
 | 
				
			||||||
    this.caretPos = null;
 | 
					 | 
				
			||||||
    this.textarea = null;
 | 
					    this.textarea = null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //  If this is the update where we've finished uploading,
 | 
					 | 
				
			||||||
  //  save the last caret position so we can restore it below!
 | 
					 | 
				
			||||||
  componentWillReceiveProps (nextProps) {
 | 
					 | 
				
			||||||
    const { textarea } = this;
 | 
					 | 
				
			||||||
    const { isUploading } = this.props;
 | 
					 | 
				
			||||||
    if (textarea && isUploading && !nextProps.isUploading) {
 | 
					 | 
				
			||||||
      this.caretPos = textarea.selectionStart;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //  Tells our state the composer has been mounted.
 | 
					  //  Tells our state the composer has been mounted.
 | 
				
			||||||
  componentDidMount () {
 | 
					  componentDidMount () {
 | 
				
			||||||
    const { onMount } = this.props;
 | 
					    const { onMount } = this.props;
 | 
				
			||||||
@@ -228,17 +216,13 @@ class Composer extends React.Component {
 | 
				
			|||||||
  //      - Replying to more than one user, selects any usernames past
 | 
					  //      - Replying to more than one user, selects any usernames past
 | 
				
			||||||
  //        the first; this provides a convenient shortcut to drop
 | 
					  //        the first; this provides a convenient shortcut to drop
 | 
				
			||||||
  //        everyone else from the conversation.
 | 
					  //        everyone else from the conversation.
 | 
				
			||||||
  // - If we've just finished uploading an image, and have a saved
 | 
					 | 
				
			||||||
  //   caret position, restores the cursor to that position after the
 | 
					 | 
				
			||||||
  //   text changes.
 | 
					 | 
				
			||||||
  componentDidUpdate (prevProps) {
 | 
					  componentDidUpdate (prevProps) {
 | 
				
			||||||
    const {
 | 
					    const {
 | 
				
			||||||
      caretPos,
 | 
					 | 
				
			||||||
      textarea,
 | 
					      textarea,
 | 
				
			||||||
    } = this;
 | 
					    } = this;
 | 
				
			||||||
    const {
 | 
					    const {
 | 
				
			||||||
      focusDate,
 | 
					      focusDate,
 | 
				
			||||||
      isUploading,
 | 
					      caretPosition,
 | 
				
			||||||
      isSubmitting,
 | 
					      isSubmitting,
 | 
				
			||||||
      preselectDate,
 | 
					      preselectDate,
 | 
				
			||||||
      text,
 | 
					      text,
 | 
				
			||||||
@@ -246,14 +230,14 @@ class Composer extends React.Component {
 | 
				
			|||||||
    let selectionEnd, selectionStart;
 | 
					    let selectionEnd, selectionStart;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //  Caret/selection handling.
 | 
					    //  Caret/selection handling.
 | 
				
			||||||
    if (focusDate !== prevProps.focusDate || (prevProps.isUploading && !isUploading && !isNaN(caretPos) && caretPos !== null)) {
 | 
					    if (focusDate !== prevProps.focusDate) {
 | 
				
			||||||
      switch (true) {
 | 
					      switch (true) {
 | 
				
			||||||
      case preselectDate !== prevProps.preselectDate:
 | 
					      case preselectDate !== prevProps.preselectDate:
 | 
				
			||||||
        selectionStart = text.search(/\s/) + 1;
 | 
					        selectionStart = text.search(/\s/) + 1;
 | 
				
			||||||
        selectionEnd = text.length;
 | 
					        selectionEnd = text.length;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case !isNaN(caretPos) && caretPos !== null:
 | 
					      case !isNaN(caretPosition) && caretPosition !== null:
 | 
				
			||||||
        selectionStart = selectionEnd = caretPos;
 | 
					        selectionStart = selectionEnd = caretPosition;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        selectionStart = selectionEnd = text.length;
 | 
					        selectionStart = selectionEnd = text.length;
 | 
				
			||||||
@@ -410,6 +394,7 @@ Composer.propTypes = {
 | 
				
			|||||||
  advancedOptions: ImmutablePropTypes.map,
 | 
					  advancedOptions: ImmutablePropTypes.map,
 | 
				
			||||||
  amUnlocked: PropTypes.bool,
 | 
					  amUnlocked: PropTypes.bool,
 | 
				
			||||||
  focusDate: PropTypes.instanceOf(Date),
 | 
					  focusDate: PropTypes.instanceOf(Date),
 | 
				
			||||||
 | 
					  caretPosition: PropTypes.number,
 | 
				
			||||||
  isSubmitting: PropTypes.bool,
 | 
					  isSubmitting: PropTypes.bool,
 | 
				
			||||||
  isUploading: PropTypes.bool,
 | 
					  isUploading: PropTypes.bool,
 | 
				
			||||||
  layout: PropTypes.string,
 | 
					  layout: PropTypes.string,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,6 +56,7 @@ const initialState = ImmutableMap({
 | 
				
			|||||||
  privacy: null,
 | 
					  privacy: null,
 | 
				
			||||||
  text: '',
 | 
					  text: '',
 | 
				
			||||||
  focusDate: null,
 | 
					  focusDate: null,
 | 
				
			||||||
 | 
					  caretPosition: null,
 | 
				
			||||||
  preselectDate: null,
 | 
					  preselectDate: null,
 | 
				
			||||||
  in_reply_to: null,
 | 
					  in_reply_to: null,
 | 
				
			||||||
  is_submitting: false,
 | 
					  is_submitting: false,
 | 
				
			||||||
@@ -148,6 +149,7 @@ function continueThread (state, status) {
 | 
				
			|||||||
    map.update('media_attachments', list => list.clear());
 | 
					    map.update('media_attachments', list => list.clear());
 | 
				
			||||||
    map.set('idempotencyKey', uuid());
 | 
					    map.set('idempotencyKey', uuid());
 | 
				
			||||||
    map.set('focusDate', new Date());
 | 
					    map.set('focusDate', new Date());
 | 
				
			||||||
 | 
					    map.set('caretPosition', null);
 | 
				
			||||||
    map.set('preselectDate', new Date());
 | 
					    map.set('preselectDate', new Date());
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -159,7 +161,6 @@ function appendMedia(state, media) {
 | 
				
			|||||||
    map.update('media_attachments', list => list.push(media));
 | 
					    map.update('media_attachments', list => list.push(media));
 | 
				
			||||||
    map.set('is_uploading', false);
 | 
					    map.set('is_uploading', false);
 | 
				
			||||||
    map.set('resetFileKey', Math.floor((Math.random() * 0x10000)));
 | 
					    map.set('resetFileKey', Math.floor((Math.random() * 0x10000)));
 | 
				
			||||||
    map.set('focusDate', new Date());
 | 
					 | 
				
			||||||
    map.set('idempotencyKey', uuid());
 | 
					    map.set('idempotencyKey', uuid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (prevSize === 0 && (state.get('default_sensitive') || state.get('spoiler'))) {
 | 
					    if (prevSize === 0 && (state.get('default_sensitive') || state.get('spoiler'))) {
 | 
				
			||||||
@@ -187,6 +188,7 @@ const insertSuggestion = (state, position, token, completion) => {
 | 
				
			|||||||
    map.set('suggestion_token', null);
 | 
					    map.set('suggestion_token', null);
 | 
				
			||||||
    map.update('suggestions', ImmutableList(), list => list.clear());
 | 
					    map.update('suggestions', ImmutableList(), list => list.clear());
 | 
				
			||||||
    map.set('focusDate', new Date());
 | 
					    map.set('focusDate', new Date());
 | 
				
			||||||
 | 
					    map.set('caretPosition', position + completion.length + 1);
 | 
				
			||||||
    map.set('idempotencyKey', uuid());
 | 
					    map.set('idempotencyKey', uuid());
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -197,6 +199,7 @@ const insertEmoji = (state, position, emojiData) => {
 | 
				
			|||||||
  return state.withMutations(map => {
 | 
					  return state.withMutations(map => {
 | 
				
			||||||
    map.update('text', oldText => `${oldText.slice(0, position)}${emoji}\u200B${oldText.slice(position)}`);
 | 
					    map.update('text', oldText => `${oldText.slice(0, position)}${emoji}\u200B${oldText.slice(position)}`);
 | 
				
			||||||
    map.set('focusDate', new Date());
 | 
					    map.set('focusDate', new Date());
 | 
				
			||||||
 | 
					    map.set('caretPosition', position + emoji.length + 1);
 | 
				
			||||||
    map.set('idempotencyKey', uuid());
 | 
					    map.set('idempotencyKey', uuid());
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -278,6 +281,7 @@ export default function compose(state = initialState, action) {
 | 
				
			|||||||
        map => map.merge(new ImmutableMap({ do_not_federate: /👁\ufe0f?\u200b?(?:<\/p>)?$/.test(action.status.get('content')) }))
 | 
					        map => map.merge(new ImmutableMap({ do_not_federate: /👁\ufe0f?\u200b?(?:<\/p>)?$/.test(action.status.get('content')) }))
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
      map.set('focusDate', new Date());
 | 
					      map.set('focusDate', new Date());
 | 
				
			||||||
 | 
					      map.set('caretPosition', null);
 | 
				
			||||||
      map.set('preselectDate', new Date());
 | 
					      map.set('preselectDate', new Date());
 | 
				
			||||||
      map.set('idempotencyKey', uuid());
 | 
					      map.set('idempotencyKey', uuid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -325,6 +329,7 @@ export default function compose(state = initialState, action) {
 | 
				
			|||||||
    return state.withMutations(map => {
 | 
					    return state.withMutations(map => {
 | 
				
			||||||
      map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' '));
 | 
					      map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' '));
 | 
				
			||||||
      map.set('focusDate', new Date());
 | 
					      map.set('focusDate', new Date());
 | 
				
			||||||
 | 
					      map.set('caretPosition', null);
 | 
				
			||||||
      map.set('idempotencyKey', uuid());
 | 
					      map.set('idempotencyKey', uuid());
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  case COMPOSE_DIRECT:
 | 
					  case COMPOSE_DIRECT:
 | 
				
			||||||
@@ -332,6 +337,7 @@ export default function compose(state = initialState, action) {
 | 
				
			|||||||
      map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' '));
 | 
					      map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' '));
 | 
				
			||||||
      map.set('privacy', 'direct');
 | 
					      map.set('privacy', 'direct');
 | 
				
			||||||
      map.set('focusDate', new Date());
 | 
					      map.set('focusDate', new Date());
 | 
				
			||||||
 | 
					      map.set('caretPosition', null);
 | 
				
			||||||
      map.set('idempotencyKey', uuid());
 | 
					      map.set('idempotencyKey', uuid());
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  case COMPOSE_SUGGESTIONS_CLEAR:
 | 
					  case COMPOSE_SUGGESTIONS_CLEAR:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user