You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 

156 lines
4.0 KiB

import './console.scss';
import { connect } from 'react-redux';
import React from 'react';
import Input from './console/Input';
import Completion from './console/Completion';
import Message from './console/Message';
import * as consoleActions from '../../console/actions/console';
import { State as AppState } from '../reducers';
const COMPLETION_MAX_ITEMS = 33;
type StateProps = ReturnType<typeof mapStateToProps>;
interface DispatchProps {
dispatch: (action: any) => void,
}
type Props = StateProps & DispatchProps
class Console extends React.Component<Props> {
private input: React.RefObject<Input>;
constructor(props: Props) {
super(props);
this.input = React.createRef();
}
onBlur() {
if (this.props.mode === 'command' || this.props.mode === 'find') {
return this.props.dispatch(consoleActions.hideCommand());
}
}
doEnter(e: React.KeyboardEvent<HTMLInputElement>) {
e.stopPropagation();
e.preventDefault();
let value = (e.target as HTMLInputElement).value;
if (this.props.mode === 'command') {
return this.props.dispatch(consoleActions.enterCommand(value));
} else if (this.props.mode === 'find') {
return this.props.dispatch(consoleActions.enterFind(
value === '' ? undefined : value));
}
}
selectNext(e: React.KeyboardEvent<HTMLInputElement>) {
this.props.dispatch(consoleActions.completionNext());
e.stopPropagation();
e.preventDefault();
}
selectPrev(e: React.KeyboardEvent<HTMLInputElement>) {
this.props.dispatch(consoleActions.completionPrev());
e.stopPropagation();
e.preventDefault();
}
onKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
switch (e.key) {
case 'Escape':
return this.props.dispatch(consoleActions.hideCommand());
case 'Enter':
return this.doEnter(e);
case 'Tab':
if (e.shiftKey) {
this.props.dispatch(consoleActions.completionPrev());
} else {
this.props.dispatch(consoleActions.completionNext());
}
e.stopPropagation();
e.preventDefault();
break;
case '[':
if (e.ctrlKey) {
return this.props.dispatch(consoleActions.hideCommand());
}
break;
case 'm':
if (e.ctrlKey) {
return this.doEnter(e);
}
break;
case 'n':
if (e.ctrlKey) {
this.selectNext(e);
}
break;
case 'p':
if (e.ctrlKey) {
this.selectPrev(e);
}
break;
}
}
onChange(e: React.ChangeEvent<HTMLInputElement>) {
let text = e.target.value;
this.props.dispatch(consoleActions.setConsoleText(text));
if (this.props.mode === 'command') {
this.props.dispatch(consoleActions.getCompletions(text));
}
}
componentDidUpdate(prevProps: Props) {
if (prevProps.mode !== 'command' && this.props.mode === 'command') {
this.props.dispatch(
consoleActions.getCompletions(this.props.consoleText));
this.focus();
} else if (prevProps.mode !== 'find' && this.props.mode === 'find') {
this.focus();
}
}
render() {
switch (this.props.mode) {
case 'command':
case 'find':
return <div className='vimvixen-console-command-wrapper'>
<Completion
size={COMPLETION_MAX_ITEMS}
completions={this.props.completions}
select={this.props.select}
/>
<Input
ref={this.input}
mode={this.props.mode}
onBlur={this.onBlur.bind(this)}
onKeyDown={this.onKeyDown.bind(this)}
onChange={this.onChange.bind(this)}
value={this.props.consoleText}
/>
</div>;
case 'info':
case 'error':
return <Message mode={ this.props.mode } >
{ this.props.messageText }
</Message>;
default:
return null;
}
}
focus() {
window.focus();
if (this.input.current) {
this.input.current.focus();
}
}
}
const mapStateToProps = (state: AppState) => ({ ...state });
export default connect(
mapStateToProps,
)(Console);