Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composer: Control selection using setSelection #17687

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 0 additions & 124 deletions src/components/Composer/index.ios.js

This file was deleted.

16 changes: 0 additions & 16 deletions src/components/Composer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,6 @@ const propTypes = {
/** Update selection position on change */
onSelectionChange: PropTypes.func,

/** Selection Object */
selection: PropTypes.shape({
start: PropTypes.number,
end: PropTypes.number,
}),

/** Whether the full composer can be opened */
isFullComposerAvailable: PropTypes.bool,

Expand Down Expand Up @@ -92,10 +86,6 @@ const defaultProps = {
autoFocus: false,
forwardedRef: null,
onSelectionChange: () => {},
selection: {
start: 0,
end: 0,
},
isFullComposerAvailable: false,
setIsFullComposerAvailable: () => {},
isComposerFullSize: false,
Expand Down Expand Up @@ -174,11 +164,6 @@ class Composer extends React.Component {
|| prevProps.numberOfLines !== this.props.numberOfLines) {
this.updateNumberOfLines();
}

if (prevProps.selection !== this.props.selection) {
// eslint-disable-next-line react/no-did-update-set-state
this.setState({selection: this.props.selection});
}
}

componentWillUnmount() {
Expand Down Expand Up @@ -365,7 +350,6 @@ class Composer extends React.Component {
autoCorrect={!Browser.isMobileSafari()}
placeholderTextColor={themeColors.placeholderText}
ref={el => this.textInput = el}
selection={this.state.selection}
onChange={this.shouldCallUpdateNumberOfLines}
onSelectionChange={this.onSelectionChange}
style={[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ const propTypes = {
/** Prevent edits and interactions like focus for this input. */
isDisabled: PropTypes.bool,

/** Selection Object */
selection: PropTypes.shape({
start: PropTypes.number,
end: PropTypes.number,
}),

/** Whether the full composer can be opened */
isFullComposerAvailable: PropTypes.bool,

Expand All @@ -51,10 +45,6 @@ const defaultProps = {
autoFocus: false,
isDisabled: false,
forwardedRef: null,
selection: {
start: 0,
end: 0,
},
isFullComposerAvailable: false,
setIsFullComposerAvailable: () => {},
isComposerFullSize: false,
Expand Down
51 changes: 23 additions & 28 deletions src/pages/home/report/ReportActionCompose.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import KeyboardShortcut from '../../../libs/KeyboardShortcut';
import * as ComposerUtils from '../../../libs/ComposerUtils';
import * as Welcome from '../../../libs/actions/Welcome';
import Permissions from '../../../libs/Permissions';
import setSelection from '../../../libs/setSelection';

const propTypes = {
/** Beta features list */
Expand Down Expand Up @@ -491,15 +492,12 @@ class ReportActionCompose extends React.Component {
const emojiObject = this.state.suggestedEmojis[highlightedEmojiIndex];
const emojiCode = emojiObject.types && emojiObject.types[this.props.preferredSkinTone] ? emojiObject.types[this.props.preferredSkinTone] : emojiObject.code;
const commentAfterColonWithEmojiNameRemoved = this.state.value.slice(this.state.selection.end).replace(CONST.REGEX.EMOJI_REPLACER, CONST.SPACE);
const oldColonIndex = this.state.colonIndex;

this.updateComment(`${commentBeforeColon}${emojiCode} ${commentAfterColonWithEmojiNameRemoved}`, true);
this.setState(prevState => ({
selection: {
start: prevState.colonIndex + emojiCode.length + CONST.SPACE_LENGTH,
end: prevState.colonIndex + emojiCode.length + CONST.SPACE_LENGTH,
},
suggestedEmojis: [],
}));
this.setState({suggestedEmojis: []}, () => {
setSelection(this.textInput, oldColonIndex + emojiCode.length + CONST.SPACE_LENGTH, oldColonIndex + emojiCode.length + CONST.SPACE_LENGTH);
});
EmojiUtils.addToFrequentlyUsedEmojis(this.props.frequentlyUsedEmojis, emojiObject);
}

Expand All @@ -513,13 +511,11 @@ class ReportActionCompose extends React.Component {
* @param {String} emoji
*/
addEmojiToTextBox(emoji) {
this.setState(prevState => ({
selection: {
start: prevState.selection.start + emoji.length,
end: prevState.selection.start + emoji.length,
},
}));
this.updateComment(ComposerUtils.insertText(this.comment, this.state.selection, emoji));
const newSelection = {
start: this.state.selection.start + emoji.length,
end: this.state.selection.start + emoji.length,
};
this.updateComment(ComposerUtils.insertText(this.comment, this.state.selection, emoji), false, newSelection);
}

/**
Expand Down Expand Up @@ -570,22 +566,22 @@ class ReportActionCompose extends React.Component {
*
* @param {String} comment
* @param {Boolean} shouldDebounceSaveComment
* @param {Object} selection
*/
updateComment(comment, shouldDebounceSaveComment) {
updateComment(comment, shouldDebounceSaveComment, selection) {
const oldComment = this.state.value;
const oldSelection = this.state.selection;
const newComment = EmojiUtils.replaceEmojis(comment, this.props.isSmallScreenWidth, this.props.preferredSkinTone);
this.setState((prevState) => {
const newState = {
isCommentEmpty: !!newComment.match(/^(\s)*$/),
value: newComment,
};
if (comment !== newComment) {
const remainder = prevState.value.slice(prevState.selection.end).length;
newState.selection = {
start: newComment.length - remainder,
end: newComment.length - remainder,
};
this.setState({
isCommentEmpty: !!newComment.match(/^(\s)*$/),
value: newComment,
}, () => {
if (selection) {
setSelection(this.textInput, selection.start, selection.end);
} else if (comment !== newComment) {
const remainder = oldComment.slice(oldSelection.end).length;
setSelection(this.textInput, newComment.length - remainder, newComment.length - remainder);
}
return newState;
});

// Indicate that draft has been created.
Expand Down Expand Up @@ -896,7 +892,6 @@ class ReportActionCompose extends React.Component {
shouldClear={this.state.textInputShouldClear}
onClear={() => this.setTextInputShouldClear(false)}
isDisabled={isComposeDisabled || isBlockedFromConcierge || this.props.disabled}
selection={this.state.selection}
onSelectionChange={this.onSelectionChange}
isFullComposerAvailable={this.state.isFullComposerAvailable}
setIsFullComposerAvailable={this.setIsFullComposerAvailable}
Expand Down
34 changes: 16 additions & 18 deletions src/pages/home/report/ReportActionItemMessageEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import CONST from '../../../CONST';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
import withKeyboardState, {keyboardStatePropTypes} from '../../../components/withKeyboardState';
import setSelection from '../../../libs/setSelection';
import * as ComposerUtils from '../../../libs/ComposerUtils';

const propTypes = {
Expand Down Expand Up @@ -129,19 +130,19 @@ class ReportActionItemMessageEdit extends React.Component {
* Update the value of the draft in Onyx
*
* @param {String} draft
* @param {Object} selection
*/
updateDraft(draft) {
updateDraft(draft, selection) {
const oldDraft = this.state.draft;
const oldSelection = this.state.selection;
const newDraft = EmojiUtils.replaceEmojis(draft, this.props.isSmallScreenWidth, this.props.preferredSkinTone);
this.setState((prevState) => {
const newState = {draft: newDraft};
if (draft !== newDraft) {
const remainder = prevState.draft.slice(prevState.selection.end).length;
newState.selection = {
start: newDraft.length - remainder,
end: newDraft.length - remainder,
};
this.setState({draft: newDraft}, () => {
if (selection) {
setSelection(this.textInput, selection.start, selection.end);
} else if (draft !== newDraft) {
const remainder = oldDraft.slice(oldSelection.end).length;
setSelection(this.textInput, newDraft.length - remainder, newDraft.length - remainder);
}
return newState;
});

// This component is rendered only when draft is set to a non-empty string. In order to prevent component
Expand Down Expand Up @@ -215,13 +216,11 @@ class ReportActionItemMessageEdit extends React.Component {
* @param {String} emoji
*/
addEmojiToTextBox(emoji) {
this.setState(prevState => ({
selection: {
start: prevState.selection.start + emoji.length,
end: prevState.selection.start + emoji.length,
},
}));
this.updateDraft(ComposerUtils.insertText(this.state.draft, this.state.selection, emoji));
const newSelection = {
start: this.state.selection.start + emoji.length,
end: this.state.selection.start + emoji.length,
};
this.updateDraft(ComposerUtils.insertText(this.state.draft, this.state.selection, emoji), newSelection);
}

/**
Expand Down Expand Up @@ -286,7 +285,6 @@ class ReportActionItemMessageEdit extends React.Component {
}
openReportActionComposeViewWhenClosingMessageEdit(this.props.isSmallScreenWidth);
}}
selection={this.state.selection}
onSelectionChange={this.onSelectionChange}
/>
<View style={styles.editChatItemEmojiWrapper}>
Expand Down