fix: auto focus while reply message
This commit is contained in:
+132
-145
@@ -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}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user