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.

137 lines
2.8 KiB

3 months ago
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withRoomContext } from '../RoomContext';
3 months ago
import * as requestActions from '../redux/requestActions';
3 months ago
const BotMessageRegex = new RegExp('^@bot (.*)');
3 months ago
class ChatInput extends React.Component {
constructor(props) {
3 months ago
super(props);
this.state =
{
3 months ago
text: ''
3 months ago
};
// TextArea element got via React ref.
// @type {HTMLElement}
this._textareaElem = null;
}
3 months ago
render() {
3 months ago
const {
connected,
chatDataProducer,
3 months ago
botDataProducer,
sendUserInfo
3 months ago
} = this.props;
const { text } = this.state;
const disabled = !connected || (!chatDataProducer && !botDataProducer);
return (
<div data-component='ChatInput'>
<textarea
ref={(elem) => { this._textareaElem = elem; }}
3 months ago
placeholder={disabled ? '当前聊天不可用' : '说点什么...'}
3 months ago
dir='auto'
autoComplete='off'
disabled={disabled}
3 months ago
value={text || ''}
3 months ago
onChange={this.handleChange.bind(this)}
3 months ago
onKeyPress={this.handleKeyPress.bind(this, sendUserInfo)}
3 months ago
/>
3 months ago
<div className='sendOut' onClick={() => {
this.sendOut(sendUserInfo);
}}>发送</div>
3 months ago
</div>
);
}
3 months ago
handleChange(event) {
3 months ago
const text = event.target.value;
this.setState({ text });
}
3 months ago
handleKeyPress(sendUserInfo, event) {
3 months ago
// If Shift + Enter do nothing.
if (event.key !== 'Enter' || (event.shiftKey || event.ctrlKey))
return;
// Don't add the sending Enter into the value.
event.preventDefault();
3 months ago
this.sendOut(sendUserInfo)
}
sendOut(sendUserInfo) {
3 months ago
let text = this.state.text.trim();
this.setState({ text: '' });
3 months ago
if (text) {
3 months ago
const { roomClient } = this.props;
const match = BotMessageRegex.exec(text);
// Chat message.
3 months ago
if (!match) {
3 months ago
text = text.trim();
roomClient.sendChatMessage(text);
3 months ago
sendUserInfo(text);
3 months ago
}
// Message to the bot.
3 months ago
else {
3 months ago
text = match[1].trim();
roomClient.sendBotMessage(text);
}
}
}
}
ChatInput.propTypes =
{
3 months ago
roomClient: PropTypes.any.isRequired,
connected: PropTypes.bool.isRequired,
chatDataProducer: PropTypes.any,
botDataProducer: PropTypes.any
3 months ago
};
3 months ago
const mapStateToProps = (state) => {
3 months ago
const dataProducersArray = Object.values(state.dataProducers);
const chatDataProducer = dataProducersArray
.find((dataProducer) => dataProducer.label === 'chat');
const botDataProducer = dataProducersArray
.find((dataProducer) => dataProducer.label === 'bot');
return {
3 months ago
connected: state.room.state === 'connected',
3 months ago
chatDataProducer,
botDataProducer
};
};
3 months ago
const mapDispatchToProps = (dispatch) => {
return {
sendUserInfo: (text) => {
dispatch(requestActions.notify({
type: 'userMessage',
isMe: true,
text: text,
}));
}
};
};
3 months ago
const ChatInputContainer = withRoomContext(connect(
mapStateToProps,
3 months ago
mapDispatchToProps,
3 months ago
)(ChatInput));
export default ChatInputContainer;