From ffb5d1beae77661b505a110e717c88aa44e1c912 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Fri, 28 Oct 2022 14:23:41 +0300 Subject: Merge `Message` and `MessageInput` components from Next version --- vnext/src/ui/MessageInput.js | 81 +++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 34 deletions(-) (limited to 'vnext/src/ui/MessageInput.js') diff --git a/vnext/src/ui/MessageInput.js b/vnext/src/ui/MessageInput.js index 6003a15c..aa4454a1 100644 --- a/vnext/src/ui/MessageInput.js +++ b/vnext/src/ui/MessageInput.js @@ -1,56 +1,63 @@ -import { useState, useEffect, useRef } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import Icon from './Icon'; import Button from './Button'; import UploadButton from './UploadButton'; +import toast from 'react-hot-toast'; /** * StackOverflow-driven development: https://stackoverflow.com/a/10158364/1097384 - * @param {HTMLTextAreaElement} el + * + * @param {HTMLTextAreaElement & {createTextRange?: Function}} el element */ function moveCaretToEnd(el) { if (typeof el.selectionStart == 'number') { el.selectionStart = el.selectionEnd = el.value.length; - // @ts-ignore } else if (typeof el.createTextRange != 'undefined') { + // Internet Explorer el.focus(); - // @ts-ignore var range = el.createTextRange(); range.collapse(false); range.select(); } } + +/** @external Promise */ + /** - * @typedef {Object} MessageInputProps - * @property {string} text - * @property {import('../api').Message=} data - * @property {function} onSend - * @property {number=} rows - * @property {string} children + * @typedef {object} MessageInputProps + * @property {string} text text + * @property {function({body:string, attach:string | File}):Promise} onSend onSend + * @property {number=} rows rows + * @property {string=} placeholder placeholder */ /** * MessageInput - * @param {React.ReactNode & MessageInputProps} props + * + * @param {React.ComponentProps & MessageInputProps} props props */ -export default function MessageInput({ text, data, rows, children, onSend }) { +export default function MessageInput({ text, rows, placeholder, onSend }) { /** - * @type {React.MutableRefObject} + * @type {React.MutableRefObject} */ - let textareaRef = useRef(); + let textareaRef = useRef(null); /** - * @type {React.MutableRefObject} + * @type {React.MutableRefObject} */ - let fileinput = useRef(); + let fileinput = useRef(null); let updateFocus = () => { const isDesktop = window.matchMedia('(min-width: 62.5rem)'); if (isDesktop.matches) { - textareaRef.current.focus(); - moveCaretToEnd(textareaRef.current); + const textarea = textareaRef.current; + if (textarea) { + textarea.focus(); + moveCaretToEnd(textarea); + } } }; useEffect(() => { @@ -72,37 +79,43 @@ export default function MessageInput({ text, data, rows, children, onSend }) { const textChanged = (event) => { setBody(event.target.value); const el = textareaRef.current; - const offset = el.offsetHeight - el.clientHeight; - const height = el.scrollHeight + offset; - el.style.height = `${height + offset}px`; + if (el) { + const offset = el.offsetHeight - el.clientHeight; + const height = el.scrollHeight + offset; + el.style.height = `${height + offset}px`; + } }; const [attach, setAttach] = useState(''); let uploadValueChanged = (attach) => { setAttach(attach); }; - let onSubmit = (event) => { + let onSubmit = async (event) => { if (event.preventDefault) { event.preventDefault(); } const input = fileinput.current; - onSend({ - mid: data.mid, - rid: data.rid || 0, - body: body, - attach: attach ? input.files[0] : '', - to: data.to || {} - }); - setAttach(''); - setBody(''); - textareaRef.current.style.height = ''; - updateFocus(); + if (input && input.files) { + if (await onSend({ + body: body, + attach: attach ? input.files[0] : '' + })) { + setAttach(''); + setBody(''); + if (textareaRef.current) { + textareaRef.current.style.height = ''; + } + updateFocus(); + } else { + toast('Can not update this message'); + } + } }; return (