bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/text-input/component.jsx

182 lines
4.1 KiB
React
Raw Normal View History

import React, { PureComponent } from 'react';
import { defineMessages, injectIntl } from 'react-intl';
import PropTypes from 'prop-types';
2023-04-28 05:31:11 +08:00
import { isMobile } from '/imports/utils/deviceInfo';
import logger from '/imports/startup/client/logger';
2023-04-28 05:31:11 +08:00
import ClickOutside from '/imports/ui/components/click-outside/component';
2021-10-27 03:50:59 +08:00
import Styled from './styles';
2023-04-28 05:31:11 +08:00
const EMOJI_BUTTON = Meteor.settings.public.app.enableEmojiButton;
const propTypes = {
placeholder: PropTypes.string,
send: PropTypes.func.isRequired,
2023-04-28 05:31:11 +08:00
emojiPickerDown: PropTypes.bool,
};
const defaultProps = {
placeholder: '',
send: () => logger.warn({ logCode: 'text_input_send_function' }, `Missing`),
2023-04-28 05:31:11 +08:00
emojiPickerDown: false,
enableEmoji: true,
};
const messages = defineMessages({
sendLabel: {
id: 'app.textInput.sendLabel',
description: 'Text input send button label',
},
});
class TextInput extends PureComponent {
constructor(props) {
super(props);
2023-04-28 05:31:11 +08:00
this.state = {
message: '',
showEmojiPicker: false
};
}
hasClickOutsideActions() {
return this.emojiEnabled();
}
handleOnChange(e) {
const message = e.target.value;
this.setState({ message });
}
2023-04-28 05:31:11 +08:00
handleOnClick() {
const { send } = this.props;
const { message } = this.state;
send(message);
this.setState({
message: '',
showEmojiPicker: false,
});
}
handleOnKeyDown(e) {
if (e.keyCode === 13 && e.shiftKey === false) {
e.preventDefault();
this.handleOnClick();
2023-04-28 05:31:11 +08:00
} else if (e.keyCode === 27) { //Escape key
const { showEmojiPicker } = this.state;
//if the emoji picker is opened, close it
if (showEmojiPicker) {
this.setState({ showEmojiPicker: false });
}
}
}
2023-04-28 05:31:11 +08:00
handleEmojiButtonClick() {
const { showEmojiPicker } = this.state;
if (this.textarea) this.textarea.focus();
this.setState({ showEmojiPicker: !showEmojiPicker });
}
handleEmojiSelect(emojiObject) {
const { message } = this.state;
2023-04-28 05:31:11 +08:00
if (this.textarea) this.textarea.focus();
this.setState({ message: message + emojiObject.native });
}
2023-04-28 05:31:11 +08:00
handleClickOutside() {
if (this.emojiEnabled()) {
const { showEmojiPicker } = this.state;
if (showEmojiPicker) {
this.setState({ showEmojiPicker: false });
}
}
}
2023-04-28 05:31:11 +08:00
emojiEnabled() {
if (isMobile) return false;
const { enableEmoji } = this.props;
return enableEmoji && EMOJI_BUTTON;
}
renderEmojiPicker() {
const { showEmojiPicker } = this.state;
if (this.emojiEnabled() && showEmojiPicker) {
return (
<EmojiPicker
onEmojiSelect={emojiObject => this.handleEmojiSelect(emojiObject)}
/>
);
}
return null;
}
renderEmojiButton = () => {
if (!this.emojiEnabled()) return null;
return (
<Styled.EmojiButtonWrapper
onClick={() => this.handleEmojiButtonClick()}
>
<Icon
iconName="happy"
/>
</Styled.EmojiButtonWrapper>
);
}
renderInput() {
const {
intl,
maxLength,
placeholder,
2023-04-28 05:31:11 +08:00
emojiPickerDown,
} = this.props;
const { message } = this.state;
return (
2021-10-27 03:50:59 +08:00
<Styled.Wrapper>
<Styled.TextArea
2023-04-28 05:31:11 +08:00
emojiEnabled={this.emojiEnabled()}
maxLength={maxLength}
onChange={(e) => this.handleOnChange(e)}
onKeyDown={(e) => this.handleOnKeyDown(e)}
onPaste={(e) => { e.stopPropagation(); }}
onCut={(e) => { e.stopPropagation(); }}
onCopy={(e) => { e.stopPropagation(); }}
placeholder={placeholder}
value={message}
/>
2021-10-27 03:50:59 +08:00
<Styled.TextInputButton
circle
color="primary"
hideLabel
icon="send"
label={intl.formatMessage(messages.sendLabel)}
onClick={() => this.handleOnClick()}
/>
2021-10-27 03:50:59 +08:00
</Styled.Wrapper>
);
}
2023-04-28 05:31:11 +08:00
render() {
return this.hasClickOutsideActions() ? (
<ClickOutside
onClick={() => this.handleClickOutside()}
>
{this.renderInput()}
</ClickOutside>
) : this.renderInput();
}
}
TextInput.propTypes = propTypes;
TextInput.defaultProps = defaultProps;
export default injectIntl(TextInput);