Get basic keyboard selection working
This commit is contained in:
parent
fb6eec0f7d
commit
a74db3a815
3 changed files with 84 additions and 6 deletions
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
|
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import {getCompletions} from '../../../autocomplete/Autocompleter';
|
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() {
|
render() {
|
||||||
|
let position = 0;
|
||||||
let renderedCompletions = this.state.completions.map((completionResult, i) => {
|
let renderedCompletions = this.state.completions.map((completionResult, i) => {
|
||||||
let completions = completionResult.completions.map((completion, i) => {
|
let completions = completionResult.completions.map((completion, i) => {
|
||||||
let Component = completion.component;
|
let Component = completion.component;
|
||||||
|
let className = classNames('mx_Autocomplete_Completion', {
|
||||||
|
'selected': position == this.state.selectionOffset
|
||||||
|
});
|
||||||
|
let componentPosition = position;
|
||||||
|
position++;
|
||||||
if(Component) {
|
if(Component) {
|
||||||
return Component;
|
return Component;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={i} className="mx_Autocomplete_Completion" tabIndex={0}>
|
<div key={i}
|
||||||
|
className={className}
|
||||||
|
onMouseOver={() => this.setState({selectionOffset: componentPosition})}>
|
||||||
<span style={{fontWeight: 600}}>{completion.title}</span>
|
<span style={{fontWeight: 600}}>{completion.title}</span>
|
||||||
<span>{completion.subtitle}</span>
|
<span>{completion.subtitle}</span>
|
||||||
<span style={{flex: 1}} />
|
<span style={{flex: 1}} />
|
||||||
|
|
|
@ -34,6 +34,9 @@ export default class MessageComposer extends React.Component {
|
||||||
this.onUploadFileSelected = this.onUploadFileSelected.bind(this);
|
this.onUploadFileSelected = this.onUploadFileSelected.bind(this);
|
||||||
this.onVoiceCallClick = this.onVoiceCallClick.bind(this);
|
this.onVoiceCallClick = this.onVoiceCallClick.bind(this);
|
||||||
this.onInputContentChanged = this.onInputContentChanged.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 = {
|
this.state = {
|
||||||
autocompleteQuery: '',
|
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() {
|
render() {
|
||||||
var me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId);
|
var me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId);
|
||||||
var uploadInputStyle = {display: 'none'};
|
var uploadInputStyle = {display: 'none'};
|
||||||
|
@ -182,9 +197,14 @@ export default class MessageComposer extends React.Component {
|
||||||
);
|
);
|
||||||
|
|
||||||
controls.push(
|
controls.push(
|
||||||
<MessageComposerInput key="controls_input" tabComplete={this.props.tabComplete}
|
<MessageComposerInput
|
||||||
onResize={this.props.onResize} room={this.props.room}
|
key="controls_input"
|
||||||
onContentChanged={this.onInputContentChanged} />,
|
onResize={this.props.onResize}
|
||||||
|
room={this.props.room}
|
||||||
|
onUpArrow={this.onUpArrow}
|
||||||
|
onDownArrow={this.onDownArrow}
|
||||||
|
onTab={this.onTab}
|
||||||
|
onContentChanged={this.onInputContentChanged} />,
|
||||||
uploadButton,
|
uploadButton,
|
||||||
hangupButton,
|
hangupButton,
|
||||||
callButton,
|
callButton,
|
||||||
|
@ -201,7 +221,10 @@ export default class MessageComposer extends React.Component {
|
||||||
return (
|
return (
|
||||||
<div className="mx_MessageComposer mx_fadable" style={{ opacity: this.props.opacity }}>
|
<div className="mx_MessageComposer mx_fadable" style={{ opacity: this.props.opacity }}>
|
||||||
<div className="mx_MessageComposer_autocomplete_wrapper">
|
<div className="mx_MessageComposer_autocomplete_wrapper">
|
||||||
<Autocomplete query={this.state.autocompleteQuery} selection={this.state.selection} />
|
<Autocomplete
|
||||||
|
ref="autocomplete"
|
||||||
|
query={this.state.autocompleteQuery}
|
||||||
|
selection={this.state.selection} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_MessageComposer_wrapper">
|
<div className="mx_MessageComposer_wrapper">
|
||||||
<div className="mx_MessageComposer_row">
|
<div className="mx_MessageComposer_row">
|
||||||
|
|
|
@ -73,6 +73,9 @@ export default class MessageComposerInput extends React.Component {
|
||||||
this.handleReturn = this.handleReturn.bind(this);
|
this.handleReturn = this.handleReturn.bind(this);
|
||||||
this.handleKeyCommand = this.handleKeyCommand.bind(this);
|
this.handleKeyCommand = this.handleKeyCommand.bind(this);
|
||||||
this.setEditorState = this.setEditorState.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');
|
let isRichtextEnabled = window.localStorage.getItem('mx_editor_rte_enabled');
|
||||||
if(isRichtextEnabled == null) {
|
if(isRichtextEnabled == null) {
|
||||||
|
@ -489,6 +492,30 @@ export default class MessageComposerInput extends React.Component {
|
||||||
return true;
|
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() {
|
render() {
|
||||||
let className = "mx_MessageComposer_input";
|
let className = "mx_MessageComposer_input";
|
||||||
|
|
||||||
|
@ -507,6 +534,9 @@ export default class MessageComposerInput extends React.Component {
|
||||||
handleKeyCommand={this.handleKeyCommand}
|
handleKeyCommand={this.handleKeyCommand}
|
||||||
handleReturn={this.handleReturn}
|
handleReturn={this.handleReturn}
|
||||||
stripPastedStyles={!this.state.isRichtextEnabled}
|
stripPastedStyles={!this.state.isRichtextEnabled}
|
||||||
|
onTab={this.onTab}
|
||||||
|
onUpArrow={this.onUpArrow}
|
||||||
|
onDownArrow={this.onDownArrow}
|
||||||
spellCheck={true} />
|
spellCheck={true} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -524,5 +554,11 @@ MessageComposerInput.propTypes = {
|
||||||
room: React.PropTypes.object.isRequired,
|
room: React.PropTypes.object.isRequired,
|
||||||
|
|
||||||
// called with current plaintext content (as a string) whenever it changes
|
// 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
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue