From 18d08a3630eb2a3282918fbb394a8120b3000ee2 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 28 Sep 2020 19:05:45 -0500 Subject: [PATCH 1/5] Revert "Composer: remove click listener on unmount" This reverts commit 136965acdd1197bbeeb4123831ca63f8d3c3c65a. --- app/soapbox/components/autosuggest_textarea.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/soapbox/components/autosuggest_textarea.js b/app/soapbox/components/autosuggest_textarea.js index 060e817e8..703aa9797 100644 --- a/app/soapbox/components/autosuggest_textarea.js +++ b/app/soapbox/components/autosuggest_textarea.js @@ -182,10 +182,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { document.addEventListener('click', this.handleClick, true); } - componentWillUnmount() { - document.removeEventListener('click', this.handleClick, true); - } - componentDidUpdate(prevProps, prevState) { const { suggestions } = this.props; if (suggestions !== prevProps.suggestions && suggestions.size > 0 && prevState.suggestionsHidden && prevState.focused) { From b78a00a306b4d91c29103fac128d7cacb5cefef6 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 28 Sep 2020 19:05:56 -0500 Subject: [PATCH 2/5] Revert "pass getClickableArea into autosuggesttextarea as prop" This reverts commit 99f0a069dd6092e7d9c835a5f2ffc2db42bf14bf. --- app/soapbox/components/autosuggest_textarea.js | 8 ++++++-- app/soapbox/features/compose/components/compose_form.js | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/soapbox/components/autosuggest_textarea.js b/app/soapbox/components/autosuggest_textarea.js index 703aa9797..e60661f6b 100644 --- a/app/soapbox/components/autosuggest_textarea.js +++ b/app/soapbox/components/autosuggest_textarea.js @@ -51,7 +51,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { onFocus: PropTypes.func, onBlur: PropTypes.func, clickableAreaRef: PropTypes.object, - getClickableArea: PropTypes.func.isRequired, }; static defaultProps = { @@ -165,9 +164,14 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { this.textarea.focus(); } + getClickableArea = () => { + const { clickableAreaRef } = this.props; + return clickableAreaRef ? clickableAreaRef.current : this.form; + } + isClickInside = (e) => { return [ - this.props.getClickableArea(), + this.getClickableArea(), document.querySelector('.autosuggest-textarea__textarea'), ].some(element => element && element.contains(e.target)); } diff --git a/app/soapbox/features/compose/components/compose_form.js b/app/soapbox/features/compose/components/compose_form.js index 39647c923..af8ce4263 100644 --- a/app/soapbox/features/compose/components/compose_form.js +++ b/app/soapbox/features/compose/components/compose_form.js @@ -286,7 +286,6 @@ class ComposeForm extends ImmutablePureComponent { onSuggestionSelected={this.onSuggestionSelected} onPaste={onPaste} autoFocus={shouldAutoFocus} - getClickableArea={this.getClickableArea} > { !condensed && From f71a1e4ce1ed0c8a81d69177040d382c7a2a2d4b Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 28 Sep 2020 19:06:06 -0500 Subject: [PATCH 3/5] Revert "fix composer jump by reseting lastToken on click and arrow up and down in autosuggesttextarea" This reverts commit 0b7763e7267108b7ef70713b6ecbf9c85c952d48. --- .../components/autosuggest_textarea.js | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/app/soapbox/components/autosuggest_textarea.js b/app/soapbox/components/autosuggest_textarea.js index e60661f6b..d9a044022 100644 --- a/app/soapbox/components/autosuggest_textarea.js +++ b/app/soapbox/components/autosuggest_textarea.js @@ -50,7 +50,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { autoFocus: PropTypes.bool, onFocus: PropTypes.func, onBlur: PropTypes.func, - clickableAreaRef: PropTypes.object, }; static defaultProps = { @@ -108,8 +107,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { if (suggestions.size > 0 && !suggestionsHidden) { e.preventDefault(); this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) }); - } else { - this.setState({ lastToken: null }); } break; @@ -117,8 +114,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { if (suggestions.size > 0 && !suggestionsHidden) { e.preventDefault(); this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) }); - } else { - this.setState({ lastToken: null }); } break; @@ -164,28 +159,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { this.textarea.focus(); } - getClickableArea = () => { - const { clickableAreaRef } = this.props; - return clickableAreaRef ? clickableAreaRef.current : this.form; - } - - isClickInside = (e) => { - return [ - this.getClickableArea(), - document.querySelector('.autosuggest-textarea__textarea'), - ].some(element => element && element.contains(e.target)); - } - - handleClick = (e) => { - if (this.isClickInside(e)) { - this.setState({ lastToken: null }); - } - } - - componentDidMount() { - document.addEventListener('click', this.handleClick, true); - } - componentDidUpdate(prevProps, prevState) { const { suggestions } = this.props; if (suggestions !== prevProps.suggestions && suggestions.size > 0 && prevState.suggestionsHidden && prevState.focused) { From bd12226a848595f96104a1595614bb53514f4be2 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 28 Sep 2020 21:58:56 -0500 Subject: [PATCH 4/5] Composer: fixes #419 jumpy cursor --- .../components/autosuggest_textarea.js | 10 ++++++++++ .../compose/components/compose_form.js | 19 ++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/app/soapbox/components/autosuggest_textarea.js b/app/soapbox/components/autosuggest_textarea.js index d9a044022..f3274c6a2 100644 --- a/app/soapbox/components/autosuggest_textarea.js +++ b/app/soapbox/components/autosuggest_textarea.js @@ -159,6 +159,16 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { this.textarea.focus(); } + shouldComponentUpdate(nextProps, nextState) { + // Skip updating when lastToken changes so the cursor doesn't jump around + // due to re-rendering unnecessarily + if (this.state.lastToken !== nextState.lastToken) { + return false; + } else { + return super.shouldComponentUpdate(nextProps, nextState); + } + } + componentDidUpdate(prevProps, prevState) { const { suggestions } = this.props; if (suggestions !== prevProps.suggestions && suggestions.size > 0 && prevState.suggestionsHidden && prevState.focused) { diff --git a/app/soapbox/features/compose/components/compose_form.js b/app/soapbox/features/compose/components/compose_form.js index af8ce4263..0f3f45f41 100644 --- a/app/soapbox/features/compose/components/compose_form.js +++ b/app/soapbox/features/compose/components/compose_form.js @@ -160,11 +160,6 @@ 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); @@ -219,8 +214,22 @@ class ComposeForm extends ImmutablePureComponent { } } + maybeUpdateCursor = prevProps => { + const shouldUpdate = [ + // Autosuggest has been updated and + // the cursor position explicitly set + this.props.focusDate !== prevProps.focusDate, + typeof this.props.caretPosition === 'number', + ].every(Boolean); + + if (shouldUpdate) { + this.setCursor(this.props.caretPosition); + } + } + componentDidUpdate(prevProps) { this.maybeUpdateFocus(prevProps); + this.maybeUpdateCursor(prevProps); } render() { From a7d2692a71d8546fcba4e580a48212c61ac4c21f Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 28 Sep 2020 23:54:47 -0500 Subject: [PATCH 5/5] AutosuggestTextarea: shouldComponentUpdate fixes --- app/soapbox/components/autosuggest_textarea.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/soapbox/components/autosuggest_textarea.js b/app/soapbox/components/autosuggest_textarea.js index f3274c6a2..baaf3e8b0 100644 --- a/app/soapbox/components/autosuggest_textarea.js +++ b/app/soapbox/components/autosuggest_textarea.js @@ -160,9 +160,12 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { } shouldComponentUpdate(nextProps, nextState) { - // Skip updating when lastToken changes so the cursor doesn't jump around - // due to re-rendering unnecessarily - if (this.state.lastToken !== nextState.lastToken) { + // Skip updating when only the lastToken changes so the + // cursor doesn't jump around due to re-rendering unnecessarily + const lastTokenUpdated = this.state.lastToken !== nextState.lastToken; + const valueUpdated = this.props.value !== nextProps.value; + + if (lastTokenUpdated && !valueUpdated) { return false; } else { return super.shouldComponentUpdate(nextProps, nextState);