aboutsummaryrefslogtreecommitdiff
path: root/vnext/src/ui/MessageInput.js
diff options
context:
space:
mode:
Diffstat (limited to 'vnext/src/ui/MessageInput.js')
-rw-r--r--vnext/src/ui/MessageInput.js107
1 files changed, 107 insertions, 0 deletions
diff --git a/vnext/src/ui/MessageInput.js b/vnext/src/ui/MessageInput.js
new file mode 100644
index 00000000..e4988d59
--- /dev/null
+++ b/vnext/src/ui/MessageInput.js
@@ -0,0 +1,107 @@
+import React, { useState, useEffect, useRef } from 'react';
+import PropTypes from 'prop-types';
+
+import { useFormState } from 'react-use-form-state';
+
+import { MessageType } from './Types';
+
+import Icon from './Icon';
+import Button from './Button';
+
+import UploadButton from './UploadButton';
+
+export default function MessageInput({ text, data, rows, children, onSend }) {
+ let textareaRef = useRef();
+ let fileinput = useRef();
+
+ let updateFocus = () => {
+ const isDesktop = window.matchMedia('(min-width: 62.5rem)');
+ if (isDesktop.matches) {
+ textareaRef.current.focus();
+ }
+ };
+ useEffect(() => {
+ textareaRef.current.value = text || '';
+ updateFocus();
+ }, [text]);
+
+ let handleCtrlEnter = (event) => {
+ if (event.ctrlKey && (event.charCode == 10 || event.charCode == 13)) {
+ onSubmit({});
+ }
+ };
+ let textChanged = (event) => {
+ const el = textareaRef.current;
+ const offset = el.offsetHeight - el.clientHeight;
+ const height = el.scrollHeight + offset;
+ el.style.height = `${height + offset}px`;
+ };
+ const [attach, setAttach] = useState('');
+ const [formState, { textarea }] = useFormState();
+ let uploadValueChanged = (attach) => {
+ setAttach(attach);
+ };
+ let onSubmit = (event) => {
+ if (event.preventDefault) {
+ event.preventDefault();
+ }
+ const input = fileinput.current;
+ onSend({
+ mid: data.mid,
+ rid: data.rid || 0,
+ body: formState.values.body,
+ attach: attach ? input.files[0] : '',
+ to: data.to || {}
+ });
+ setAttach('');
+ formState.clearField('body');
+ textareaRef.current.style.height = '';
+ updateFocus();
+ };
+ return (
+ <form className="msg-comment-target" style={{ padding: '12px' }} onSubmit={onSubmit}>
+ <div style={commentStyle}>
+ <textarea onChange={textChanged} onKeyPress={handleCtrlEnter}
+ ref={textareaRef} style={textInputStyle} value={formState.values.body}
+ rows={rows || '1'} placeholder={children} {...textarea('body')} />
+ <div style={inputBarStyle}>
+ <UploadButton inputRef={fileinput} value={attach} onChange={uploadValueChanged} />
+ <Button onClick={onSubmit}><Icon name="ei-envelope" size="s" />Send</Button>
+ </div>
+ </div>
+ </form>
+ );
+}
+
+const commentStyle = {
+ display: 'flex',
+ flexDirection: 'column',
+ borderTop: '1px #eee solid',
+ width: '100%',
+ marginTop: '10px'
+};
+
+const inputBarStyle = {
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ padding: '3px'
+};
+
+const textInputStyle = {
+ overflow: 'hidden',
+ resize: 'none',
+ display: 'block',
+ boxSizing: 'border-box',
+ border: 0,
+ outline: 'none',
+ padding: '4px'
+};
+
+MessageInput.propTypes = {
+ children: PropTypes.node,
+ data: MessageType.isRequired,
+ onSend: PropTypes.func.isRequired,
+ rows: PropTypes.string,
+ text: PropTypes.string
+};