From a74db3a815879558110fcaa4b2f6f322dc1af783 Mon Sep 17 00:00:00 2001 From: Aviral Dasgupta Date: Tue, 21 Jun 2016 18:33:39 +0530 Subject: [PATCH] Get basic keyboard selection working --- src/components/views/rooms/Autocomplete.js | 21 +++++++++- src/components/views/rooms/MessageComposer.js | 31 +++++++++++++-- .../views/rooms/MessageComposerInput.js | 38 ++++++++++++++++++- 3 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/Autocomplete.js b/src/components/views/rooms/Autocomplete.js index babd349c31f..ca0c5df701c 100644 --- a/src/components/views/rooms/Autocomplete.js +++ b/src/components/views/rooms/Autocomplete.js @@ -1,5 +1,6 @@ import React from 'react'; import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; +import classNames from 'classnames'; import {getCompletions} from '../../../autocomplete/Autocompleter'; @@ -41,16 +42,34 @@ export default class Autocomplete extends React.Component { }); } + onUpArrow() { + this.setState({selectionOffset: this.state.selectionOffset - 1}); + return true; + } + + onDownArrow() { + this.setState({selectionOffset: this.state.selectionOffset + 1}); + return true; + } + render() { + let position = 0; let renderedCompletions = this.state.completions.map((completionResult, i) => { let completions = completionResult.completions.map((completion, i) => { let Component = completion.component; + let className = classNames('mx_Autocomplete_Completion', { + 'selected': position == this.state.selectionOffset + }); + let componentPosition = position; + position++; if(Component) { return Component; } return ( -
+
this.setState({selectionOffset: componentPosition})}> {completion.title} {completion.subtitle} diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index ce1ced2b59d..24d0bd25105 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -34,6 +34,9 @@ export default class MessageComposer extends React.Component { this.onUploadFileSelected = this.onUploadFileSelected.bind(this); this.onVoiceCallClick = this.onVoiceCallClick.bind(this); this.onInputContentChanged = this.onInputContentChanged.bind(this); + this.onUpArrow = this.onUpArrow.bind(this); + this.onDownArrow = this.onDownArrow.bind(this); + this.onTab = this.onTab.bind(this); this.state = { autocompleteQuery: '', @@ -129,6 +132,18 @@ export default class MessageComposer extends React.Component { }); } + onUpArrow() { + return this.refs.autocomplete.onUpArrow(); + } + + onDownArrow() { + return this.refs.autocomplete.onDownArrow(); + } + + onTab() { + return this.refs.autocomplete.onTab(); + } + render() { var me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId); var uploadInputStyle = {display: 'none'}; @@ -182,9 +197,14 @@ export default class MessageComposer extends React.Component { ); controls.push( - , + , uploadButton, hangupButton, callButton, @@ -201,7 +221,10 @@ export default class MessageComposer extends React.Component { return (
- +
diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 9b615e7e4e6..313216d54cb 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -73,6 +73,9 @@ export default class MessageComposerInput extends React.Component { this.handleReturn = this.handleReturn.bind(this); this.handleKeyCommand = this.handleKeyCommand.bind(this); this.setEditorState = this.setEditorState.bind(this); + this.onUpArrow = this.onUpArrow.bind(this); + this.onDownArrow = this.onDownArrow.bind(this); + this.onTab = this.onTab.bind(this); let isRichtextEnabled = window.localStorage.getItem('mx_editor_rte_enabled'); if(isRichtextEnabled == null) { @@ -489,6 +492,30 @@ export default class MessageComposerInput extends React.Component { return true; } + onUpArrow(e) { + if(this.props.onUpArrow) { + if(this.props.onUpArrow()) { + e.preventDefault(); + } + } + } + + onDownArrow(e) { + if(this.props.onDownArrow) { + if(this.props.onDownArrow()) { + e.preventDefault(); + } + } + } + + onTab(e) { + if(this.props.onTab) { + if(this.props.onTab()) { + e.preventDefault(); + } + } + } + render() { let className = "mx_MessageComposer_input"; @@ -507,6 +534,9 @@ export default class MessageComposerInput extends React.Component { handleKeyCommand={this.handleKeyCommand} handleReturn={this.handleReturn} stripPastedStyles={!this.state.isRichtextEnabled} + onTab={this.onTab} + onUpArrow={this.onUpArrow} + onDownArrow={this.onDownArrow} spellCheck={true} />
); @@ -524,5 +554,11 @@ MessageComposerInput.propTypes = { room: React.PropTypes.object.isRequired, // called with current plaintext content (as a string) whenever it changes - onContentChanged: React.PropTypes.func + onContentChanged: React.PropTypes.func, + + onUpArrow: React.PropTypes.func, + + onDownArrow: React.PropTypes.func, + + onTab: React.PropTypes.func };