113 lines
3.6 KiB
TypeScript
113 lines
3.6 KiB
TypeScript
import { format } from "date-fns";
|
||
import { t } from "i18next";
|
||
import { Trans } from "react-i18next";
|
||
// import useSocketStore from "../stores/useSocketStore";
|
||
import CloseIcon from "./icons/CloseIcon";
|
||
import SendChatIcon from "./icons/SendChatIcon";
|
||
import Button from "./ui/Button";
|
||
import useStreamUserStore from "../stores/useStreamUserStore";
|
||
import { FormEvent, useEffect, useRef, useState } from "react";
|
||
import useSocketStore from "../stores/useSocketStore";
|
||
import useChatStore from "../stores/useChatStore";
|
||
import { isMobile } from "react-device-detect";
|
||
|
||
interface Props {
|
||
onClose: () => void;
|
||
}
|
||
|
||
function Chat2({ onClose }: Props) {
|
||
const { socket } = useSocketStore();
|
||
const { me, users } = useStreamUserStore();
|
||
// const [messages] = useStateRef<IMessage[]>([]);
|
||
const messagesRef = useRef<HTMLDivElement>(null);
|
||
const [messageText, setMessageText] = useState<string>("");
|
||
const messageTextRef = useRef<HTMLInputElement>(null);
|
||
const { messages } = useChatStore();
|
||
|
||
function sendMessage(e: FormEvent) {
|
||
e.preventDefault();
|
||
|
||
if (!messageText || messageText === " ") return;
|
||
|
||
socket?.emit("message", messageText);
|
||
|
||
setMessageText("");
|
||
}
|
||
|
||
useEffect(() => {
|
||
if (!messages.length) return;
|
||
|
||
messagesRef.current?.scrollTo({
|
||
top: messagesRef.current.scrollHeight,
|
||
behavior: "smooth",
|
||
});
|
||
}, [messages]);
|
||
|
||
return (
|
||
<div
|
||
className={`chat fixed top-0 right-0 h-dvh flex flex-col w-[296px] bg-white border-t border-[#DAE0E5]`}
|
||
>
|
||
<div className="p-4 pb-2">
|
||
<div className="flex items-center justify-between border-b border-[#DAE0E5] pb-4">
|
||
<p className="text-sm font-semibold">
|
||
<Trans i18nKey={"chat.demoChat"}>Чат демонстрации</Trans>
|
||
</p>
|
||
<Button
|
||
variant="tertiary"
|
||
icon={<CloseIcon />}
|
||
onlyIcon
|
||
onClick={onClose}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div
|
||
ref={messagesRef}
|
||
className="flex-1 overflow-y-scroll flex flex-col gap-1 px-4 pb-2 pt-0 border-b border-[#DAE0E5]"
|
||
>
|
||
{messages.map((message, index) => (
|
||
<div
|
||
key={index}
|
||
className={`text-sm p-2 flex flex-col gap-1 rounded-lg ${
|
||
users.find((user) => user.id === me?.id)?.id === message.userId
|
||
? "bg-[#C4DDF5]"
|
||
: "bg-[#F0F1F2]"
|
||
}`}
|
||
>
|
||
{users.find((user) => user.id === me?.id)?.id !==
|
||
message.userId && (
|
||
<p className="text-[#49A1F5] font-semibold">
|
||
{users.find((user) => user.id === message.userId)?.name}
|
||
</p>
|
||
)}
|
||
|
||
<p className="break-words">{message.text}</p>
|
||
<p className="text-[#767676] translate-x-1 translate-y-1 self-end leading-none">
|
||
{format(new Date(), "HH:mm")}
|
||
</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
<div className="p-3 pl-4">
|
||
<form onSubmit={sendMessage} className="flex items-center gap-3">
|
||
<input
|
||
autoFocus={isMobile ? false : true}
|
||
ref={messageTextRef}
|
||
type="text"
|
||
placeholder={t("writeAMessage")}
|
||
className="w-full text-sm bg-transparent outline-none"
|
||
value={messageText}
|
||
onChange={(e) =>
|
||
setMessageText(e.target.value.replace(/\s+/g, " "))
|
||
}
|
||
/>
|
||
<button type="submit" className="text-[#49A1F5] outline-none">
|
||
<SendChatIcon />
|
||
</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export default Chat2;
|