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.js81
1 files changed, 47 insertions, 34 deletions
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<boolean>} onSend onSend
+ * @property {number=} rows rows
+ * @property {string=} placeholder placeholder
*/
/**
* MessageInput
- * @param {React.ReactNode & MessageInputProps} props
+ *
+ * @param {React.ComponentProps<React.FC> & MessageInputProps} props props
*/
-export default function MessageInput({ text, data, rows, children, onSend }) {
+export default function MessageInput({ text, rows, placeholder, onSend }) {
/**
- * @type {React.MutableRefObject<HTMLTextAreaElement>}
+ * @type {React.MutableRefObject<HTMLTextAreaElement?>}
*/
- let textareaRef = useRef();
+ let textareaRef = useRef(null);
/**
- * @type {React.MutableRefObject<HTMLInputElement>}
+ * @type {React.MutableRefObject<HTMLInputElement?>}
*/
- 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 (
<form className="msg-comment-target" style={{ padding: '12px', width: '100%' }} onSubmit={onSubmit}>
<div style={commentStyle}>
<textarea onChange={textChanged} onKeyPress={handleCtrlEnter}
ref={textareaRef} style={textInputStyle}
- rows={rows || 1} placeholder={children} value={body} />
+ rows={rows || 1} placeholder={placeholder} value={body || ''} />
<div style={inputBarStyle}>
<UploadButton inputRef={fileinput} value={attach} onChange={uploadValueChanged} />
<Button onClick={onSubmit}><Icon name="ei-envelope" size="s" />Send</Button>