diff --git a/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/_hooks/useChatListHandler.ts b/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/_hooks/useChatListHandler.ts index 4e0988ec..f2d0389e 100644 --- a/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/_hooks/useChatListHandler.ts +++ b/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/_hooks/useChatListHandler.ts @@ -87,6 +87,25 @@ const useChatListHandler = (chatId: number) => { [chatId, connectionStatus], ); // chatId와 connectionStatus가 변경될 경우에만 함수를 재생성 + const sendImageMessage = useCallback( + (imageUrls: string[]) => { + if (imageUrls.length === 0) return false; + + if (clientRef.current?.active && connectionStatus === ConnectionStatus.Connected) { + clientRef.current.publish({ + destination: `/publish/chat/${chatId}/image`, + body: JSON.stringify({ imageUrls }), + }); + + return true; + } + + console.error("WebSocket is not connected. Image message could not be sent."); + return false; + }, + [chatId, connectionStatus], + ); + // Track created object URLs for cleanup const objectUrlsRef = useRef([]); @@ -172,6 +191,7 @@ const useChatListHandler = (chatId: number) => { // Handlers sendTextMessage, + sendImageMessage, addImageMessagePreview, addFileMessagePreview, }; diff --git a/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx b/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx index d13a57df..8fb606ad 100644 --- a/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx +++ b/apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx @@ -3,9 +3,11 @@ import clsx from "clsx"; import Link from "next/link"; import { useGetPartnerInfo } from "@/apis/chat"; +import { useUploadProfileImage } from "@/apis/image-upload"; import ProfileWithBadge from "@/components/ui/ProfileWithBadge"; import useAuthStore from "@/lib/zustand/useAuthStore"; +import { toast } from "@/lib/zustand/useToastStore"; import { ConnectionStatus } from "@/types/chat"; import { UserRole } from "@/types/mentor"; import { tokenParse } from "@/utils/jwtUtils"; @@ -43,9 +45,12 @@ const ChatContent = ({ chatId }: ChatContentProps) => { // Handlers sendTextMessage, + sendImageMessage, addImageMessagePreview, } = useChatListHandler(chatId); + const uploadProfileImageMutation = useUploadProfileImage(); + const { data: partnerInfo } = useGetPartnerInfo(chatId); const { partnerId, nickname, profileUrl, university } = partnerInfo ?? {}; @@ -170,8 +175,21 @@ const ChatContent = ({ chatId }: ChatContentProps) => { onSendMessage={(data) => { sendTextMessage(data.message, userId); }} - onSendImages={(data) => { - addImageMessagePreview(data.images, userId); + onSendImages={async (data) => { + try { + const uploadedImages = await Promise.all( + data.images.map((image) => uploadProfileImageMutation.mutateAsync(image)), + ); + + const imageUrls = uploadedImages.map((image) => image.fileUrl); + const isSent = sendImageMessage(imageUrls); + + if (!isSent) { + toast.error("채팅 연결이 원활하지 않아 이미지를 전송하지 못했어요."); + } + } catch { + toast.error("이미지 전송에 실패했어요. 다시 시도해주세요."); + } }} onSendFiles={(data) => { addImageMessagePreview(data.files, userId);