diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 3d01052ccf..dbc970511a 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -38,14 +38,19 @@ export default class MessageComposer extends React.Component { this.onDownArrow = this.onDownArrow.bind(this); this._tryComplete = this._tryComplete.bind(this); this._onAutocompleteConfirm = this._onAutocompleteConfirm.bind(this); + this.onToggleFormattingClicked = this.onToggleFormattingClicked.bind(this); + this.onToggleMarkdownClicked = this.onToggleMarkdownClicked.bind(this); + this.onInputStateChanged = this.onInputStateChanged.bind(this); this.state = { autocompleteQuery: '', selection: null, - selectionInfo: { + inputState: { style: [], blockType: null, + isRichtextEnabled: true, }, + showFormatting: false, }; } @@ -131,14 +136,17 @@ export default class MessageComposer extends React.Component { }); } - onInputContentChanged(content: string, selection: {start: number, end: number}, selectionInfo) { + onInputContentChanged(content: string, selection: {start: number, end: number}) { this.setState({ autocompleteQuery: content, selection, - selectionInfo, }); } + onInputStateChanged(inputState) { + this.setState({inputState}); + } + onUpArrow() { return this.refs.autocomplete.onUpArrow(); } @@ -161,9 +169,18 @@ export default class MessageComposer extends React.Component { } onFormatButtonClicked(name: "bold" | "italic" | "strike" | "quote" | "bullet" | "numbullet", event) { + event.preventDefault(); this.messageComposerInput.onFormatButtonClicked(name, event); } + onToggleFormattingClicked() { + this.setState({showFormatting: !this.state.showFormatting}); + } + + onToggleMarkdownClicked() { + this.messageComposerInput.enableRichtext(!this.state.inputState.isRichtextEnabled); + } + render() { var me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId); var uploadInputStyle = {display: 'none'}; @@ -217,8 +234,11 @@ export default class MessageComposer extends React.Component { ); const formattingButton = ( - ); @@ -232,7 +252,8 @@ export default class MessageComposer extends React.Component { onUpArrow={this.onUpArrow} onDownArrow={this.onDownArrow} tabComplete={this.props.tabComplete} // used for old messagecomposerinput/tabcomplete - onContentChanged={this.onInputContentChanged} />, + onContentChanged={this.onInputContentChanged} + onInputStateChanged={this.onInputStateChanged} />, formattingButton, uploadButton, hangupButton, @@ -259,7 +280,7 @@ export default class MessageComposer extends React.Component { } - const {style, blockType} = this.state.selectionInfo; + const {style, blockType} = this.state.inputState; const formatButtons = ["bold", "italic", "strike", "quote", "bullet", "numbullet"].map( name => { const active = style.includes(name) || blockType === name; @@ -278,8 +299,17 @@ export default class MessageComposer extends React.Component { {UserSettingsStore.isFeatureEnabled('rich_text_editor') ? -
${formatted_body}`); + if (!this.state.isRichtextEnabled) { + content = ContentState.createFromText(stateToMarkdown(content)); + } + + const blockMap = content.getBlockMap(); + let startSelection = SelectionState.createEmpty(contentState.getFirstBlock().getKey()); + contentState = Modifier.splitBlock(contentState, startSelection); + startSelection = SelectionState.createEmpty(contentState.getFirstBlock().getKey()); + contentState = Modifier.replaceWithFragment(contentState, + startSelection, + blockMap); + startSelection = SelectionState.createEmpty(contentState.getFirstBlock().getKey()); + if (this.state.isRichtextEnabled) + contentState = Modifier.setBlockType(contentState, startSelection, 'blockquote'); + let editorState = EditorState.push(this.state.editorState, contentState, 'insert-characters'); + this.setEditorState(editorState); editor.focus(); } - break; + } + break; } } @@ -363,9 +395,8 @@ export default class MessageComposerInput extends React.Component { const textContent = editorState.getCurrentContent().getPlainText(); const selection = RichText.selectionStateToTextOffsets(editorState.getSelection(), editorState.getCurrentContent().getBlocksAsArray()); - const selectionInfo = this.getSelectionInfo(editorState); - this.props.onContentChanged(textContent, selection, selectionInfo); + this.props.onContentChanged(textContent, selection); } } @@ -428,7 +459,8 @@ export default class MessageComposerInput extends React.Component { handleReturn(ev) { if (ev.shiftKey) { - return false; + this.setEditorState(RichUtils.insertSoftNewline(this.state.editorState)); + return true; } const contentState = this.state.editorState.getCurrentContent(); @@ -469,7 +501,7 @@ export default class MessageComposerInput extends React.Component { return true; } - if(this.state.isRichtextEnabled) { + if (this.state.isRichtextEnabled) { contentHTML = RichText.contentStateToHTML(contentState); } else { contentHTML = mdownToHtml(contentText); @@ -618,6 +650,9 @@ export default class MessageComposerInput extends React.Component { return (