diff options
author | Vitaly Takmazov | 2019-05-04 21:13:12 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2023-01-13 10:37:54 +0300 |
commit | f470636a70943a8ecad8bddc791a1c2dddd28e1e (patch) | |
tree | c43d109d88adbde9a696084070cdd92c6b9a004b /vnext/src/ui/MessageInput.js | |
parent | 3d7d213e3ddc5bf4f71d536f31677b768aa3b7c0 (diff) |
Components -> UI
Diffstat (limited to 'vnext/src/ui/MessageInput.js')
-rw-r--r-- | vnext/src/ui/MessageInput.js | 107 |
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 +}; |