From 6b90bcfc9efc04d786dab7d452efe7bd694df277 Mon Sep 17 00:00:00 2001 From: armandgray Date: Thu, 22 Mar 2018 11:00:21 -0700 Subject: [PATCH 1/7] =?UTF-8?q?[#156101143]=20after=20deleting=20an=20@=20?= =?UTF-8?q?mention=20moving=20the=20cursor=20to=20right=20after=20the=20?= =?UTF-8?q?=E2=80=9C@=E2=80=9D=20symbol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MentionsTextInput.js | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/MentionsTextInput.js b/src/MentionsTextInput.js index 1350ffa..e6d857c 100644 --- a/src/MentionsTextInput.js +++ b/src/MentionsTextInput.js @@ -27,6 +27,7 @@ export default class MentionsTextInput extends Component { textInputHeight: '', suggestionRowHeight: new Animated.Value(0), text: this.props.value ? this.props.value : '', + selection: { start: 0, end: 0 }, }; this.lastTextLength = 0; @@ -371,6 +372,27 @@ export default class MentionsTextInput extends Component { } } + setSelection(start, end = start) { + if (this._textInput) { + this._textInput.focus(); + this.setState({ selection: { start, end } }); + } + } + + updateStateForDeletedTrigger(text, selectionIndex) { + this.didTextChange = true; + this.didDeleteTriggerKeyword = true; + this.shouldDeleteTriggerOnBackspace = false; + this.handleTriggerMatrixShiftLeft(selectionIndex - 1, this.getSubsequentTriggerIndex(selectionIndex), 1); + + this.setState({ + text: text, + }, () => { + this.setSelection(selectionIndex + 1); + this.startTracking(selectionIndex); + }); + } + deleteTriggerKeyword(index, addSpace) { const start = this.triggerMatrix[index][0]; const end = this.triggerMatrix[index][1]; @@ -382,17 +404,12 @@ export default class MentionsTextInput extends Component { const preTriggerText = this.state.text.slice(0, start + 1); const postTriggerText = this.state.text.slice(end, this.state.text.length); const space = postTriggerText.length && addSpace ? ' ' : ''; + const text = preTriggerText + space + postTriggerText; this.handleTriggerDeletion(index); setTimeout(() => { - this.didTextChange = true; - this.didDeleteTriggerKeyword = true; - this.shouldDeleteTriggerOnBackspace = false; - this.handleTriggerMatrixShiftLeft(start - 1, this.getSubsequentTriggerIndex(start), 1); - this.setState({ text: preTriggerText + space + postTriggerText }, () => { - this.startTracking(start); - }); + this.updateStateForDeletedTrigger(text, start); }, SET_STATE_DELAY); } @@ -507,6 +524,10 @@ export default class MentionsTextInput extends Component { this.props.onSelectionChange(); } + if (!this.didDeleteTriggerKeyword) { + this.setState({ selection }); + } + if (this.didTextChange) { this.handleSelectionChange(selection); return; @@ -593,6 +614,7 @@ export default class MentionsTextInput extends Component { onContentSizeChange={this.onContentSizeChange.bind(this)} ref={component => this._textInput = component} accessibilityLabel={ 'chat_input_text' } + selection={ this.state.selection } onChangeText={this.onChangeText.bind(this)} onSelectionChange={(event) => { this.onSelectionChange(event.nativeEvent.selection); }} disableFullscreenUI={!!this.props.disableFullscreenUI} From ab2aec47733e2cd75662091146066bade1c1cdff Mon Sep 17 00:00:00 2001 From: armandgray Date: Thu, 22 Mar 2018 16:40:26 -0700 Subject: [PATCH 2/7] [#156101143] completing initial setup for moving cursor on deletes --- src/MentionsTextInput.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/MentionsTextInput.js b/src/MentionsTextInput.js index e6d857c..8b9c807 100644 --- a/src/MentionsTextInput.js +++ b/src/MentionsTextInput.js @@ -27,7 +27,7 @@ export default class MentionsTextInput extends Component { textInputHeight: '', suggestionRowHeight: new Animated.Value(0), text: this.props.value ? this.props.value : '', - selection: { start: 0, end: 0 }, + selection: null, }; this.lastTextLength = 0; @@ -385,6 +385,10 @@ export default class MentionsTextInput extends Component { this.shouldDeleteTriggerOnBackspace = false; this.handleTriggerMatrixShiftLeft(selectionIndex - 1, this.getSubsequentTriggerIndex(selectionIndex), 1); + if (this.props.onChangeText) { + this.props.onChangeText(text); + } + this.setState({ text: text, }, () => { @@ -500,7 +504,17 @@ export default class MentionsTextInput extends Component { } } - handleSelectionChange(selection = {start: 0, end: 0}) { + handleSelectionStateReset() { + if (this.state.selection && this.shouldResetSelectionState) { + this.setState({ selection: null }); + } + + this.shouldResetSelectionState = this.didDeleteTriggerKeyword && !!this.state.selection; + } + + handleSelectionChange(selection) { + this.handleSelectionStateReset(); + this.isSelectionChangeHandled = true; this.didDeleteTriggerKeyword = false; @@ -524,10 +538,6 @@ export default class MentionsTextInput extends Component { this.props.onSelectionChange(); } - if (!this.didDeleteTriggerKeyword) { - this.setState({ selection }); - } - if (this.didTextChange) { this.handleSelectionChange(selection); return; From 8cc3932a524874783927a34df684e90be25d792f Mon Sep 17 00:00:00 2001 From: armandgray Date: Thu, 22 Mar 2018 17:31:44 -0700 Subject: [PATCH 3/7] [#156213326] sending on enter when clicked anywhere in the message --- src/MentionsTextInput.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/MentionsTextInput.js b/src/MentionsTextInput.js index 8b9c807..df234d5 100644 --- a/src/MentionsTextInput.js +++ b/src/MentionsTextInput.js @@ -557,12 +557,17 @@ export default class MentionsTextInput extends Component { return !text1 && text2.length > 1 || text1.length < text2.length - 1; } + hasNewLineChar(text) { + return text && text.length > 0 && text[text.length - 1] == '\n' + || text.indexOf('\n') !== -1; + } + onChangeText(text) { if (this.isResetting) { return; } - if (text && text.length > 0 && text[text.length - 1] == '\n') { + if (this.hasNewLineChar(text)) { this.props.onKeyPress({ nativeEvent: { key: "Enter" } }); return; } From f6b17723ff14e15ab7163836e818e6336306cc98 Mon Sep 17 00:00:00 2001 From: armandgray Date: Fri, 23 Mar 2018 14:23:09 -0700 Subject: [PATCH 4/7] fixing android selection updates --- src/MentionsTextInput.js | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/MentionsTextInput.js b/src/MentionsTextInput.js index df234d5..b2381ff 100644 --- a/src/MentionsTextInput.js +++ b/src/MentionsTextInput.js @@ -38,9 +38,7 @@ export default class MentionsTextInput extends Component { } componentWillMount() { - this.setState({ - textInputHeight: this.props.textInputMinHeight - }); + this.setState({ textInputHeight: this.props.textInputMinHeight }); } reloadTriggerMatrix(text) { @@ -504,16 +502,31 @@ export default class MentionsTextInput extends Component { } } - handleSelectionStateReset() { - if (this.state.selection && this.shouldResetSelectionState) { - this.setState({ selection: null }); - } + wasDeletionFromIndexOne() { + const lastSelection = this.state.selection; + return lastSelection && lastSelection.start == 1 && this.getTextDifference() == 1; + } - this.shouldResetSelectionState = this.didDeleteTriggerKeyword && !!this.state.selection; + isZeroWithText(selection) { + return Platform.OS == 'ios' && selection.start == 0 && selection.start == selection.end + && this.state.text.length != 0; + } + + isUnchangedSelectionState(selection) { + return this.state.selection && selection && selection.start == this.state.selection.start + && selection.end == this.state.selection.end; + } + + shouldUpdateSelectionState(selection) { + return selection && this.isUnchangedSelectionState(selection) && !this.didDeleteTriggerKeyword + && selection.start <= this.state.text.length + && (!this.isZeroWithText(selection) || this.wasDeletionFromIndexOne()); } handleSelectionChange(selection) { - this.handleSelectionStateReset(); + if (this.shouldUpdateSelectionState(selection)) { + this.setSelection(selection.start, selection.end); + } this.isSelectionChangeHandled = true; this.didDeleteTriggerKeyword = false; From d2f3fff9efde47791f8a795807d169572a8f8bdb Mon Sep 17 00:00:00 2001 From: armandgray Date: Fri, 23 Mar 2018 14:50:43 -0700 Subject: [PATCH 5/7] fixing ios cursor jumping around --- src/MentionsTextInput.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/MentionsTextInput.js b/src/MentionsTextInput.js index b2381ff..889fc3b 100644 --- a/src/MentionsTextInput.js +++ b/src/MentionsTextInput.js @@ -502,9 +502,8 @@ export default class MentionsTextInput extends Component { } } - wasDeletionFromIndexOne() { - const lastSelection = this.state.selection; - return lastSelection && lastSelection.start == 1 && this.getTextDifference() == 1; + wasLastSelectionIndexOne() { + return this.state.selection && this.state.selection.start == 1; } isZeroWithText(selection) { @@ -518,9 +517,9 @@ export default class MentionsTextInput extends Component { } shouldUpdateSelectionState(selection) { - return selection && this.isUnchangedSelectionState(selection) && !this.didDeleteTriggerKeyword + return selection && this.state.text && !this.isUnchangedSelectionState(selection) && !this.didDeleteTriggerKeyword && selection.start <= this.state.text.length - && (!this.isZeroWithText(selection) || this.wasDeletionFromIndexOne()); + && (!this.isZeroWithText(selection) || this.wasLastSelectionIndexOne()); } handleSelectionChange(selection) { @@ -642,7 +641,7 @@ export default class MentionsTextInput extends Component { onContentSizeChange={this.onContentSizeChange.bind(this)} ref={component => this._textInput = component} accessibilityLabel={ 'chat_input_text' } - selection={ this.state.selection } + selection={ this.state.text && this.state.text.length > 0 ? this.state.selection : { start: 0, end: 0 } } onChangeText={this.onChangeText.bind(this)} onSelectionChange={(event) => { this.onSelectionChange(event.nativeEvent.selection); }} disableFullscreenUI={!!this.props.disableFullscreenUI} From a870479b7882d4d211dd81670663d27e366a4c2a Mon Sep 17 00:00:00 2001 From: armandgray Date: Fri, 23 Mar 2018 14:54:20 -0700 Subject: [PATCH 6/7] setting initial state to 0 --- src/MentionsTextInput.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MentionsTextInput.js b/src/MentionsTextInput.js index 889fc3b..7c6620e 100644 --- a/src/MentionsTextInput.js +++ b/src/MentionsTextInput.js @@ -27,7 +27,7 @@ export default class MentionsTextInput extends Component { textInputHeight: '', suggestionRowHeight: new Animated.Value(0), text: this.props.value ? this.props.value : '', - selection: null, + selection: { start: 0, end: 0 }, }; this.lastTextLength = 0; From 4771e908ea0f5b23c9525a641e0bc1292060f869 Mon Sep 17 00:00:00 2001 From: armandgray Date: Fri, 23 Mar 2018 15:06:10 -0700 Subject: [PATCH 7/7] requested changes --- src/MentionsTextInput.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/MentionsTextInput.js b/src/MentionsTextInput.js index 7c6620e..a968a77 100644 --- a/src/MentionsTextInput.js +++ b/src/MentionsTextInput.js @@ -570,8 +570,7 @@ export default class MentionsTextInput extends Component { } hasNewLineChar(text) { - return text && text.length > 0 && text[text.length - 1] == '\n' - || text.indexOf('\n') !== -1; + return text && text.length > 0 && text.indexOf('\n') !== -1; } onChangeText(text) {