mirror of https://github.com/vector-im/riot-web
				
				
				
			Get basic keyboard selection working
							parent
							
								
									fb6eec0f7d
								
							
						
					
					
						commit
						a74db3a815
					
				| 
						 | 
					@ -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 New Issue