From d9e6efbe794eb159f9bfaa8d27983e9d3b696982 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 26 May 2020 15:21:40 -0500 Subject: [PATCH 1/7] Revert "Merge branch 'compose_caret_to_end' into 'master'" This reverts commit 886e87799633102a15ec3193ebb0e68c0e9dd24b, reversing changes made to b6a74040316efa260f11424269098c9f8d7108c3. --- .gitignore | 1 - .../compose/components/compose_form.js | 24 +++++++------------ app/gabsocial/reducers/compose.js | 3 +-- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index da7dcee8d..e146e98fa 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,3 @@ /.eslintcache /.env /deploy.sh -/.vs/ diff --git a/app/gabsocial/features/compose/components/compose_form.js b/app/gabsocial/features/compose/components/compose_form.js index 7e0e18b27..acb21f5fd 100644 --- a/app/gabsocial/features/compose/components/compose_form.js +++ b/app/gabsocial/features/compose/components/compose_form.js @@ -44,7 +44,6 @@ class ComposeForm extends ImmutablePureComponent { state = { composeFocused: false, - caretPosition: 0, } static contextTypes = { @@ -87,9 +86,6 @@ class ComposeForm extends ImmutablePureComponent { handleChange = (e) => { this.props.onChange(e.target.value); - this.setState({ - caretPosition: e.target.selectionStart, - }); } handleComposeFocus = () => { @@ -184,24 +180,22 @@ class ComposeForm extends ImmutablePureComponent { // - 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) { + let selectionEnd, selectionStart; if (this.props.preselectDate !== prevProps.preselectDate) { - selectionEnd = this.props.text.length; + 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; + } else if (typeof this.props.caretPosition === 'number') { + selectionStart = this.props.caretPosition; + selectionEnd = this.props.caretPosition; + } else { + selectionEnd = this.props.text.length; + selectionStart = selectionEnd; } + 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(); - } } } diff --git a/app/gabsocial/reducers/compose.js b/app/gabsocial/reducers/compose.js index 39cff8eb0..49c9bf97b 100644 --- a/app/gabsocial/reducers/compose.js +++ b/app/gabsocial/reducers/compose.js @@ -237,8 +237,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: From 808e05a03f0a353b767300b35b9cad868938114b Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 26 May 2020 15:24:03 -0500 Subject: [PATCH 2/7] Pass maxTootChars from ComposeFormContainer instead of ComposeForm --- .../features/compose/components/compose_form.js | 10 +--------- .../compose/containers/compose_form_container.js | 1 + 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/app/gabsocial/features/compose/components/compose_form.js b/app/gabsocial/features/compose/components/compose_form.js index acb21f5fd..067b98296 100644 --- a/app/gabsocial/features/compose/components/compose_form.js +++ b/app/gabsocial/features/compose/components/compose_form.js @@ -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,14 +31,7 @@ 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 = { diff --git a/app/gabsocial/features/compose/containers/compose_form_container.js b/app/gabsocial/features/compose/containers/compose_form_container.js index ce33d8174..f1ac1926d 100644 --- a/app/gabsocial/features/compose/containers/compose_form_container.js +++ b/app/gabsocial/features/compose/containers/compose_form_container.js @@ -26,6 +26,7 @@ const mapStateToProps = state => ({ 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) => ({ From 55578a4381bfb3a2accfe34d7c087e7cb23751e4 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 26 May 2020 15:26:07 -0500 Subject: [PATCH 3/7] Composer: shouldCollapse --> isClickOutside --- app/gabsocial/features/compose/components/compose_form.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/gabsocial/features/compose/components/compose_form.js b/app/gabsocial/features/compose/components/compose_form.js index 067b98296..1f0a02e0b 100644 --- a/app/gabsocial/features/compose/components/compose_form.js +++ b/app/gabsocial/features/compose/components/compose_form.js @@ -97,8 +97,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'), @@ -107,7 +109,7 @@ class ComposeForm extends ImmutablePureComponent { } handleClick = (e) => { - if (this.shouldCollapse(e)) { + if (this.isClickOutside(e)) { this.handleClickOutside(); } } From 5633bf431740bac37e3110541d4b31a4a3699e50 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 26 May 2020 16:11:24 -0500 Subject: [PATCH 4/7] Composer: simplify cursor update code --- .../compose/components/compose_form.js | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/app/gabsocial/features/compose/components/compose_form.js b/app/gabsocial/features/compose/components/compose_form.js index 1f0a02e0b..365083e86 100644 --- a/app/gabsocial/features/compose/components/compose_form.js +++ b/app/gabsocial/features/compose/components/compose_form.js @@ -158,6 +158,44 @@ class ComposeForm extends ImmutablePureComponent { this.props.onChangeSpoilerText(e.target.value); } + makeCursorData = opts => { + const { didFocus, isReply, didSuggestion } = opts; + + // Mentions + if (didFocus && isReply) return [ + this.props.text.search(/\s/) + 1, + this.props.text.length, + ]; + + // Autosuggestions + if (didFocus && didSuggestion) return [ + this.props.caretPosition, + ]; + + // Delete & redraft + if (didFocus) return [ + this.props.text.length, + ]; + + return false; + } + + setCursor = (start, end = start) => { + if (!this.autosuggestTextarea) return; + this.autosuggestTextarea.textarea.setSelectionRange(start, end); + this.autosuggestTextarea.textarea.focus(); + } + + updateCursor = prevProps => { + const cursorData = this.makeCursorData({ + didFocus: this.props.focusDate !== prevProps.focusDate, + isReply: this.props.preselectDate !== prevProps.preselectDate, + didSuggestion: typeof this.props.caretPosition === 'number', + }); + + if (cursorData) this.setCursor(...cursorData); + } + componentDidMount() { document.addEventListener('click', this.handleClick, true); } @@ -167,30 +205,7 @@ class ComposeForm extends ImmutablePureComponent { } 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. - if (this.props.focusDate !== prevProps.focusDate) { - let selectionEnd, selectionStart; - - if (this.props.preselectDate !== prevProps.preselectDate) { - selectionEnd = this.props.text.length; - selectionStart = this.props.text.search(/\s/) + 1; - } else if (typeof this.props.caretPosition === 'number') { - selectionStart = this.props.caretPosition; - selectionEnd = this.props.caretPosition; - } else { - selectionEnd = this.props.text.length; - selectionStart = selectionEnd; - } - - this.autosuggestTextarea.textarea.setSelectionRange(selectionStart, selectionEnd); - this.autosuggestTextarea.textarea.focus(); - } + this.updateCursor(prevProps); } setAutosuggestTextarea = (c) => { From 188067ac4847e98d9e323c1f7178247d7e655182 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 26 May 2020 17:22:32 -0500 Subject: [PATCH 5/7] Composer: Always place cursor at the end of text --- .../compose/components/compose_form.js | 39 ++----------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/app/gabsocial/features/compose/components/compose_form.js b/app/gabsocial/features/compose/components/compose_form.js index 365083e86..3ad404fa4 100644 --- a/app/gabsocial/features/compose/components/compose_form.js +++ b/app/gabsocial/features/compose/components/compose_form.js @@ -158,56 +158,25 @@ class ComposeForm extends ImmutablePureComponent { this.props.onChangeSpoilerText(e.target.value); } - makeCursorData = opts => { - const { didFocus, isReply, didSuggestion } = opts; - - // Mentions - if (didFocus && isReply) return [ - this.props.text.search(/\s/) + 1, - this.props.text.length, - ]; - - // Autosuggestions - if (didFocus && didSuggestion) return [ - this.props.caretPosition, - ]; - - // Delete & redraft - if (didFocus) return [ - this.props.text.length, - ]; - - return false; + doFocus = () => { + if (!this.autosuggestTextarea) return; + this.autosuggestTextarea.textarea.focus(); } setCursor = (start, end = start) => { if (!this.autosuggestTextarea) return; this.autosuggestTextarea.textarea.setSelectionRange(start, end); - this.autosuggestTextarea.textarea.focus(); - } - - updateCursor = prevProps => { - const cursorData = this.makeCursorData({ - didFocus: this.props.focusDate !== prevProps.focusDate, - isReply: this.props.preselectDate !== prevProps.preselectDate, - didSuggestion: typeof this.props.caretPosition === 'number', - }); - - if (cursorData) this.setCursor(...cursorData); } 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) { - this.updateCursor(prevProps); - } - setAutosuggestTextarea = (c) => { this.autosuggestTextarea = c; } From e06f8ce894436e2a903aad1439026b53a2bd89a5 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 26 May 2020 17:36:56 -0500 Subject: [PATCH 6/7] Composer: Remove preselectDate This value is only used to track when a reply happens. On soapbox-fe, a reply causes a new ComposeForm to mount, so we can track it that way instead. --- app/gabsocial/features/compose/components/compose_form.js | 1 - .../features/compose/containers/compose_form_container.js | 1 - app/gabsocial/reducers/compose.js | 2 -- 3 files changed, 4 deletions(-) diff --git a/app/gabsocial/features/compose/components/compose_form.js b/app/gabsocial/features/compose/components/compose_form.js index 3ad404fa4..4784544f3 100644 --- a/app/gabsocial/features/compose/components/compose_form.js +++ b/app/gabsocial/features/compose/components/compose_form.js @@ -51,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, diff --git a/app/gabsocial/features/compose/containers/compose_form_container.js b/app/gabsocial/features/compose/containers/compose_form_container.js index f1ac1926d..0a7cefc96 100644 --- a/app/gabsocial/features/compose/containers/compose_form_container.js +++ b/app/gabsocial/features/compose/containers/compose_form_container.js @@ -19,7 +19,6 @@ 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']), diff --git a/app/gabsocial/reducers/compose.js b/app/gabsocial/reducers/compose.js index 49c9bf97b..a19d4ed3d 100644 --- a/app/gabsocial/reducers/compose.js +++ b/app/gabsocial/reducers/compose.js @@ -54,7 +54,6 @@ const initialState = ImmutableMap({ text: '', focusDate: null, caretPosition: null, - preselectDate: null, in_reply_to: null, is_composing: false, is_submitting: false, @@ -247,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) { From e14e7ba6a3786ae151c944c3becddbb1a7e266a2 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 26 May 2020 18:22:50 -0500 Subject: [PATCH 7/7] gitignore VisualStudio files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e146e98fa..da7dcee8d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /.eslintcache /.env /deploy.sh +/.vs/