From b348055eeebc96716a3615c156e7bf88b41cab57 Mon Sep 17 00:00:00 2001 From: C4rnivore Date: Thu, 9 Oct 2025 12:33:45 +0500 Subject: [PATCH] Chat popup --- client/public/img/popups/EmptyMessageFeed.svg | 31 +++ client/public/img/popups/MessageUserPfp.png | Bin 0 -> 1205 bytes client/src/components/popups/ChatPopup.tsx | 188 ++++++++++++++++++ .../ShareModal.tsx => popups/SharePopup.tsx} | 2 +- client/src/pages/HomePage.tsx | 8 +- 5 files changed, 221 insertions(+), 8 deletions(-) create mode 100644 client/public/img/popups/EmptyMessageFeed.svg create mode 100644 client/public/img/popups/MessageUserPfp.png create mode 100644 client/src/components/popups/ChatPopup.tsx rename client/src/components/{modals/ShareModal.tsx => popups/SharePopup.tsx} (94%) diff --git a/client/public/img/popups/EmptyMessageFeed.svg b/client/public/img/popups/EmptyMessageFeed.svg new file mode 100644 index 0000000..57a444a --- /dev/null +++ b/client/public/img/popups/EmptyMessageFeed.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/img/popups/MessageUserPfp.png b/client/public/img/popups/MessageUserPfp.png new file mode 100644 index 0000000000000000000000000000000000000000..e481b8b7ac6430bdcf73b9fc88d65ff8df52f77c GIT binary patch literal 1205 zcmV;m1WNmfP)W*ujvB!cOZ3tM zh#;X#5mn2%QJr&@+E$uNXjHpy9LKeHhxgWAcf8)Qw`x8qn#s(2?|XkUvla-5nY4^I z@$7T9`0Taw(i9q`J=xB4=D* zjXC5@Ed0(+XFU=#aQ&}wCj*9|ci=gi&hZvA=`z*cEc*$u!3w3_H7JH&TWz?qUw>3Z z;tfMrj!F%!lSUJv3pztj9^07zE%s96uH&5kYd2yjKh`!wd`yHtHu!GW8F}|q2+^46 zlG{pAhs`A8l%c^$4xJHrpmZD?OO+6bBb%aKR~jYcEzdiV(6 z3Hm-Tbvu4_V?(pEv(B7r?WS9|KEPBLCZDvR@4TR#PEAb(UJrl@m!R}A8kS`_qncKC z?(PKzb90w%1XY-un?ooR!otFW6Lq0fLZMJ_=F7{=&fdz(3W7s!m=gBCbkfs7#CLah zkve}K|2%krKi1b#p^>XSe)=@l@7=?l+qZH2#0dn25XN0I4C_w|=2DP8SX^Ah&0Dwd zI~_S3JBHT7hn#nWsRW`}#81=HxO(|Af}$pyt4@P{pRO*EKhx^wlmBe|{P(z1U!mSc z%DvpUf1h5m7DmpVg{0AuqcV8$RjP{D-|RgZbP46=bK{>o$Bc`0 z-Fc8>rplSLpOj_dV0{B+wkt&48zeH~zAa?uU;5}g}THKIo3M#@mrUaQsm9guJ$ zpU)-wE%-@0?{QBW0Q{u`Uh^<#IW`wY8OIXXr0aZ$Q~4?acGMx4pgnS+Q6Q{44r@zF}g= ThuHI|00000NkvXXu0mjfM|MEp literal 0 HcmV?d00001 diff --git a/client/src/components/popups/ChatPopup.tsx b/client/src/components/popups/ChatPopup.tsx new file mode 100644 index 0000000..db4230d --- /dev/null +++ b/client/src/components/popups/ChatPopup.tsx @@ -0,0 +1,188 @@ +import { useRef, useState, useEffect } from "react"; +import SendIcon from "../icons/SendIcon"; +import Button from "../ui/Button"; +import { useMe } from "../../hooks/useAuth"; +import clsx from "clsx"; + +export default function ChatPopup() { + const [messages, setMessages] = useState([ + { + senderId: "1", + timestamp: "12:22", + content: + "У меня все сломалось, ничего не работает, картинки нет, все пошло по пизде, помогите мне кто-нибудь, пожалуйста", + }, + { + senderId: "2", + timestamp: "12:22", + content: "🤡🤡🤡", + }, + ]); + + function onMessageSend(message: string) { + setMessages([ + ...messages, + { + senderId: "1", + timestamp: "12:22", + content: message, + }, + ]); + } + + return ( +
+ + +
+ ); +} + +function MessageFeed({ messages }: { messages: MessageItemProps[] }) { + const messagesEndRef = useRef(null); + + // Скролл к концу при получении нового сообщения + useEffect(() => { + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + }, [messages]); + + return ( +
+ + {messages.length === 0 ? ( +
+ + + Здесь пока нет сообщений.
Можно начать беседу с приветствия +
+
+ ) : ( +
+ {messages.map((message, index) => ( + + ))} +
+
+ )} +
+ ); +} + +interface MessageItemProps { + senderId: string; + timestamp: string; + content: string; +} + +function MessageItem({ senderId, timestamp, content }: MessageItemProps) { + const { data: user } = useMe(); + const isFromMe = senderId === "1"; + + return ( +
+
+
+ {!isFromMe && ( +
+ {user?.fullName} +
+ )} +
{content}
+
+ {timestamp} +
+ +
+ user +
+
+ ); +} + +function MessageInput({ + onMessageSend, +}: { + onMessageSend: (message: string) => void; +}) { + const [message, setMessage] = useState(""); + const textareaRef = useRef(null); + + useEffect(() => { + const textarea = textareaRef.current; + if (!textarea) return; + textarea.style.height = "auto"; + + const computedStyle = window.getComputedStyle(textarea); + const lineHeight = parseInt(computedStyle.lineHeight); + const maxHeight = lineHeight * 4; + const newHeight = Math.min(textarea.scrollHeight, maxHeight); + + textarea.style.height = `${newHeight}px`; + textarea.style.overflowY = + textarea.scrollHeight > maxHeight ? "auto" : "hidden"; + }, [message]); + + function handleChange(e: React.ChangeEvent) { + setMessage(e.target.value); + } + + function sendMessage() { + setMessage(""); + onMessageSend(message); + } + + return ( +
textareaRef.current?.focus()} + className="flex w-full min-h-[4.444vw] p-[1.111vw] items-end justify-between absolute bottom-0 left-0 bg-white" + > +