force editor rerender when we swap editorStates

This commit is contained in:
Aviral Dasgupta 2017-02-10 03:40:57 +05:30
parent 46d30c378d
commit 5fbe06ed91
No known key found for this signature in database
GPG key ID: 5FD1E9F4FFD3DA80
2 changed files with 25 additions and 17 deletions

View file

@ -58,7 +58,7 @@ export default class Autocomplete extends React.Component {
return; return;
} }
const completionList = flatMap(completions, provider => provider.completions); const completionList = flatMap(completions, (provider) => provider.completions);
// Reset selection when completion list becomes empty. // Reset selection when completion list becomes empty.
let selectionOffset = COMPOSER_SELECTED; let selectionOffset = COMPOSER_SELECTED;
@ -69,7 +69,7 @@ export default class Autocomplete extends React.Component {
const currentSelection = this.state.selectionOffset === 0 ? null : const currentSelection = this.state.selectionOffset === 0 ? null :
this.state.completionList[this.state.selectionOffset - 1].completion; this.state.completionList[this.state.selectionOffset - 1].completion;
selectionOffset = completionList.findIndex( selectionOffset = completionList.findIndex(
completion => completion.completion === currentSelection); (completion) => completion.completion === currentSelection);
if (selectionOffset === -1) { if (selectionOffset === -1) {
selectionOffset = COMPOSER_SELECTED; selectionOffset = COMPOSER_SELECTED;
} else { } else {
@ -82,8 +82,8 @@ export default class Autocomplete extends React.Component {
let hide = this.state.hide; let hide = this.state.hide;
// These are lists of booleans that indicate whether whether the corresponding provider had a matching pattern // These are lists of booleans that indicate whether whether the corresponding provider had a matching pattern
const oldMatches = this.state.completions.map(completion => !!completion.command.command), const oldMatches = this.state.completions.map((completion) => !!completion.command.command),
newMatches = completions.map(completion => !!completion.command.command); newMatches = completions.map((completion) => !!completion.command.command);
// So, essentially, we re-show autocomplete if any provider finds a new pattern or stops finding an old one // So, essentially, we re-show autocomplete if any provider finds a new pattern or stops finding an old one
if (!isEqual(oldMatches, newMatches)) { if (!isEqual(oldMatches, newMatches)) {
@ -170,7 +170,7 @@ export default class Autocomplete extends React.Component {
} }
setSelection(selectionOffset: number) { setSelection(selectionOffset: number) {
this.setState({selectionOffset}); this.setState({selectionOffset, hide: false});
} }
componentDidUpdate() { componentDidUpdate() {
@ -195,17 +195,16 @@ export default class Autocomplete extends React.Component {
const EmojiText = sdk.getComponent('views.elements.EmojiText'); const EmojiText = sdk.getComponent('views.elements.EmojiText');
let position = 1; let position = 1;
let renderedCompletions = this.state.completions.map((completionResult, i) => { const renderedCompletions = this.state.completions.map((completionResult, i) => {
let completions = completionResult.completions.map((completion, i) => { const completions = completionResult.completions.map((completion, i) => {
const className = classNames('mx_Autocomplete_Completion', { const className = classNames('mx_Autocomplete_Completion', {
'selected': position === this.state.selectionOffset, 'selected': position === this.state.selectionOffset,
}); });
let componentPosition = position; const componentPosition = position;
position++; position++;
let onMouseOver = () => this.setSelection(componentPosition); const onMouseOver = () => this.setSelection(componentPosition);
let onClick = () => { const onClick = () => {
this.setSelection(componentPosition); this.setSelection(componentPosition);
this.onCompletionClicked(); this.onCompletionClicked();
}; };
@ -226,7 +225,7 @@ export default class Autocomplete extends React.Component {
{completionResult.provider.renderCompletions(completions)} {completionResult.provider.renderCompletions(completions)}
</div> </div>
) : null; ) : null;
}).filter(completion => !!completion); }).filter((completion) => !!completion);
return !this.state.hide && renderedCompletions.length > 0 ? ( return !this.state.hide && renderedCompletions.length > 0 ? (
<div className="mx_Autocomplete" ref={(e) => this.container = e}> <div className="mx_Autocomplete" ref={(e) => this.container = e}>

View file

@ -414,6 +414,8 @@ export default class MessageComposerInput extends React.Component {
} }
} }
console.log(state);
super.setState(state, () => { super.setState(state, () => {
if (callback != null) { if (callback != null) {
callback(); callback();
@ -425,7 +427,7 @@ export default class MessageComposerInput extends React.Component {
const selection = RichText.selectionStateToTextOffsets( const selection = RichText.selectionStateToTextOffsets(
this.state.editorState.getSelection(), this.state.editorState.getSelection(),
this.state.editorState.getCurrentContent().getBlocksAsArray()); this.state.editorState.getCurrentContent().getBlocksAsArray());
console.log(textContent);
this.props.onContentChanged(textContent, selection); this.props.onContentChanged(textContent, selection);
} }
}); });
@ -629,12 +631,12 @@ export default class MessageComposerInput extends React.Component {
} }
}; };
onEscape = (e) => { onEscape = async (e) => {
e.preventDefault(); e.preventDefault();
if (this.autocomplete) { if (this.autocomplete) {
this.autocomplete.onEscape(e); this.autocomplete.onEscape(e);
} }
this.setDisplayedCompletion(null); // restore originalEditorState await this.setDisplayedCompletion(null); // restore originalEditorState
}; };
/* If passed null, restores the original editor content from state.originalEditorState. /* If passed null, restores the original editor content from state.originalEditorState.
@ -645,7 +647,14 @@ export default class MessageComposerInput extends React.Component {
if (displayedCompletion == null) { if (displayedCompletion == null) {
if (this.state.originalEditorState) { if (this.state.originalEditorState) {
this.setState({editorState: this.state.originalEditorState}); console.log('setting editorState to originalEditorState');
let editorState = this.state.originalEditorState;
// This is a workaround from https://github.com/facebook/draft-js/issues/458
// Due to the way we swap editorStates, Draft does not rerender at times
editorState = EditorState.forceSelection(editorState,
editorState.getSelection());
this.setState({editorState});
} }
return false; return false;
} }
@ -663,7 +672,7 @@ export default class MessageComposerInput extends React.Component {
this.setState({editorState, originalEditorState: activeEditorState}); this.setState({editorState, originalEditorState: activeEditorState});
// for some reason, doing this right away does not update the editor :( // for some reason, doing this right away does not update the editor :(
setTimeout(() => this.refs.editor.focus(), 50); // setTimeout(() => this.refs.editor.focus(), 50);
return true; return true;
}; };