fix: auto focus while reply message

This commit is contained in:
zerosoul
2022-03-09 09:33:23 +08:00
parent 4e77c4ba79
commit e6f5b6e428
+132 -145
View File
@@ -1,153 +1,140 @@
import { useState, useEffect, useRef } from "react"; import { useState, useEffect, useRef } from 'react';
import { MdAdd, MdClose } from "react-icons/md"; import { MdAdd, MdClose } from 'react-icons/md';
import TextareaAutosize from "react-textarea-autosize"; import TextareaAutosize from 'react-textarea-autosize';
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from 'react-redux';
import { useKey } from "rooks"; import { useKey } from 'rooks';
import { removeReplyMessage } from "../../../app/slices/message.pending"; import { removeReplyMessage } from '../../../app/slices/message.pending';
import { useSendChannelMsgMutation } from "../../../app/services/channel"; import { useSendChannelMsgMutation } from '../../../app/services/channel';
import { useSendMsgMutation } from "../../../app/services/contact"; import { useSendMsgMutation } from '../../../app/services/contact';
import { useReplyMessageMutation } from "../../../app/services/message"; import { useReplyMessageMutation } from '../../../app/services/message';
import StyledSend from "./styled"; import StyledSend from './styled';
import useFiles from "./useFiles"; import useFiles from './useFiles';
import UploadModal from "./UploadModal"; import UploadModal from './UploadModal';
import EmojiPicker from "./EmojiPicker"; import EmojiPicker from './EmojiPicker';
const Types = { const Types = {
channel: "#", channel: '#',
user: "@", user: '@'
}; };
export default function Send({ export default function Send({
name, name,
type = "channel", type = 'channel',
// 发给谁,或者是channel,或者是user // 发给谁,或者是channel,或者是user
id = "", id = '',
dragFiles = [], dragFiles = []
}) { }) {
const [replyMessage] = useReplyMessageMutation(); const [replyMessage] = useReplyMessageMutation();
const { files, setFiles, resetFiles } = useFiles([]); const { files, setFiles, resetFiles } = useFiles([]);
const inputRef = useRef(); const inputRef = useRef();
const [shift, setShift] = useState(false); const [shift, setShift] = useState(false);
const [enter, setEnter] = useState(false); const [enter, setEnter] = useState(false);
const [msg, setMsg] = useState(""); const [msg, setMsg] = useState('');
const dispatch = useDispatch(); const dispatch = useDispatch();
// 谁发的 // 谁发的
const { from_uid, reply = null, contacts } = useSelector((store) => { const {
return { from_uid,
contacts: store.contacts, reply = null,
from_uid: store.authData.user.uid, contacts
reply: store.pendingMessage.reply[id], } = useSelector((store) => {
}; return {
}); contacts: store.contacts,
useEffect(() => { from_uid: store.authData.user.uid,
if (dragFiles.length) { reply: store.pendingMessage.reply[id]
setFiles((prev) => [...prev, ...dragFiles]); };
} });
}, [dragFiles]); useEffect(() => {
if (dragFiles.length) {
setFiles((prev) => [...prev, ...dragFiles]);
}
}, [dragFiles]);
const [sendMsg, { isLoading: userSending }] = useSendMsgMutation(); const [sendMsg, { isLoading: userSending }] = useSendMsgMutation();
const [ const [sendChannelMsg, { isLoading: channelSending }] = useSendChannelMsgMutation();
sendChannelMsg, const sendMessage = type == 'channel' ? sendChannelMsg : sendMsg;
{ isLoading: channelSending }, const sendingMessage = userSending || channelSending;
] = useSendChannelMsgMutation(); useKey(
const sendMessage = type == "channel" ? sendChannelMsg : sendMsg; 'Shift',
const sendingMessage = userSending || channelSending; (e) => {
useKey( console.log('shift', e.type);
"Shift", setShift(e.type == 'keydown');
(e) => { },
console.log("shift", e.type); { eventTypes: ['keydown', 'keyup'], target: inputRef }
setShift(e.type == "keydown"); );
}, const handleMsgChange = (evt) => {
{ eventTypes: ["keydown", "keyup"], target: inputRef } if (enter && !shift) {
); handleSendMessage();
const handleMsgChange = (evt) => { } else {
if (enter && !shift) { setMsg(evt.target.value);
handleSendMessage(); }
} else { };
setMsg(evt.target.value); const handleInputKeydown = (e) => {
} console.log('keydown event', e);
}; setEnter(e.key === 'Enter');
const handleInputKeydown = (e) => { };
console.log("keydown event", e); const selectEmoji = (emoji) => {
setEnter(e.key === "Enter"); setMsg((prev) => `${prev}${emoji}`);
}; };
const selectEmoji = (emoji) => { useEffect(() => {
setMsg((prev) => `${prev}${emoji}`); inputRef.current.focus();
}; }, [msg, reply]);
useEffect(() => { const handleUpload = (evt) => {
inputRef.current.focus(); setFiles([...evt.target.files]);
}, [msg]); };
const handleUpload = (evt) => { const handleSendMessage = () => {
setFiles([...evt.target.files]); if (!msg || !id || sendingMessage) return;
}; if (reply) {
const handleSendMessage = () => { replyMessage({ mid: reply.mid, content: msg });
if (!msg || !id || sendingMessage) return; dispatch(removeReplyMessage(id));
if (reply) { } else {
replyMessage({ mid: reply.mid, content: msg }); sendMessage({ id, content: msg, from_uid });
dispatch(removeReplyMessage(id)); }
} else { setMsg('');
sendMessage({ id, content: msg, from_uid }); };
} const removeReply = () => {
setMsg(""); dispatch(removeReplyMessage(id));
}; };
const removeReply = () => { return (
dispatch(removeReplyMessage(id)); <>
}; <StyledSend className={`send ${reply ? 'reply' : ''}`}>
return ( {reply && (
<> <div className="reply">
<StyledSend className={`send ${reply ? "reply" : ""}`}> <span className="txt">
{reply && ( Replying to
<div className="reply"> <em>{contacts.find((c) => c.uid == reply.from_uid)?.name}</em>
<span className="txt"> </span>
Replying to <button className="close" onClick={removeReply}>
<em>{contacts.find((c) => c.uid == reply.from_uid)?.name}</em> <MdClose size={20} color="#78787C" />
</span> </button>
<button className="close" onClick={removeReply}> </div>
<MdClose size={20} color="#78787C" /> )}
</button> <div className="addon">
</div> <MdAdd size={20} color="#78787C" />
)} <input multiple={true} onChange={handleUpload} type="file" name="file" id="file" />
<div className="addon"> </div>
<MdAdd size={20} color="#78787C" /> <div className="input">
<input <TextareaAutosize
multiple={true} autoFocus
onChange={handleUpload} onFocus={(e) =>
type="file" e.currentTarget.setSelectionRange(e.currentTarget.value.length, e.currentTarget.value.length)
name="file" }
id="file" ref={inputRef}
/> className="content"
</div> maxRows={8}
<div className="input"> minRows={1}
<TextareaAutosize onKeyDown={handleInputKeydown}
// autoFocus onChange={handleMsgChange}
onFocus={(e) => value={msg}
e.currentTarget.setSelectionRange( placeholder={`${Types[type]}${name} 发消息`}
e.currentTarget.value.length, />
e.currentTarget.value.length </div>
) <div className="emoji">
} <EmojiPicker selectEmoji={selectEmoji} />
ref={inputRef} </div>
className="content" </StyledSend>
maxRows={8} {files.length !== 0 && (
minRows={1} <UploadModal type={type} files={files} sendTo={id} closeModal={resetFiles} />
onKeyDown={handleInputKeydown} )}
onChange={handleMsgChange} </>
value={msg} );
placeholder={`${Types[type]}${name} 发消息`}
/>
</div>
<div className="emoji">
<EmojiPicker selectEmoji={selectEmoji} />
</div>
</StyledSend>
{files.length !== 0 && (
<UploadModal
type={type}
files={files}
sendTo={id}
closeModal={resetFiles}
/>
)}
</>
);
} }