11"use client" ;
22
3- import { useEffect , useRef , useState } from "react" ;
4- import styles from "./ChatingPanel .module.scss" ;
3+ import { useEffect , useRef , useState , useMemo } from "react" ;
4+ import styles from "./ChattingPanel .module.scss" ;
55import IconButton from "@/components/Button/IconButton/IconButton" ;
66import { X , SendHorizontal } from "lucide-react" ;
77import { useLive } from "../../LectureLiveProvider" ;
88import ChatBox from "@/components/ChatBox/ChatBox" ;
99import BasicInput from "@/components/Input/BasicInput/BasicInput" ;
1010import { useParams } from "next/navigation" ;
11- import { useLectureChat } from "@/hooks/useLectureChat" ;
11+ import { useLectureChat , type ChatMessage } from "@/hooks/useLectureChat" ;
12+ import { fetchChattingList } from "@/api/lectures/fetchChattingList" ;
1213
13- export default function ChatPanel ( ) {
14+ export default function ChattingPanel ( ) {
1415 const { togglePanel } = useLive ( ) ;
1516 const { lectureId } = useParams < { lectureId : string } > ( ) ;
1617
@@ -20,6 +21,9 @@ export default function ChatPanel() {
2021 const [ text , setText ] = useState ( "" ) ;
2122 const bodyRef = useRef < HTMLDivElement > ( null ) ;
2223
24+ const [ previousMessages , setPreviousMessages ] = useState < ChatMessage [ ] > ( [ ] ) ;
25+ const fetchedOnceRef = useRef ( false ) ;
26+
2327 const closeChat = ( ) => togglePanel ( "chat" ) ;
2428
2529 // 메시지 전송
@@ -36,13 +40,53 @@ export default function ChatPanel() {
3640 send ( ) ;
3741 } ;
3842
43+ // 연결 직후 과거 대화 불러오기
44+ useEffect ( ( ) => {
45+ if ( ! lectureId || ! connected || fetchedOnceRef . current ) return ;
46+
47+ let isMounted = true ;
48+ ( async ( ) => {
49+ try {
50+ const res = await fetchChattingList ( lectureId ) ;
51+ if ( ! isMounted ) return ;
52+
53+ if ( res . isSuccess && Array . isArray ( res . result ) ) {
54+ const mapped : ChatMessage [ ] = res . result . map ( ( m ) => ( {
55+ senderId : null ,
56+ senderName : null ,
57+ content : m . content ,
58+ role : m . role ,
59+ timestamp : m . timestamp ,
60+ } ) ) ;
61+ setPreviousMessages ( mapped ) ;
62+ } else {
63+ setPreviousMessages ( [ ] ) ;
64+ }
65+ } catch ( e ) {
66+ setPreviousMessages ( [ ] ) ;
67+ console . error ( "과거 채팅 불러오기 실패:" , e ) ;
68+ } finally {
69+ fetchedOnceRef . current = true ;
70+ }
71+ } ) ( ) ;
72+
73+ return ( ) => {
74+ isMounted = false ;
75+ } ;
76+ } , [ lectureId , connected ] ) ;
77+
78+ // 과거 + 실시간 합친 배열
79+ const combinedMessages = useMemo (
80+ ( ) => [ ...previousMessages , ...messages ] ,
81+ [ previousMessages , messages ]
82+ ) ;
83+
3984 // 새로운 메시지 오면 스크롤 맨 아래로 이동
4085 useEffect ( ( ) => {
4186 const el = bodyRef . current ;
4287 if ( ! el ) return ;
4388 el . scrollTop = el . scrollHeight ;
44- } , [ messages ] ) ;
45-
89+ } , [ combinedMessages ] ) ;
4690
4791 const fmt = ( ts : string ) => {
4892 const d = new Date ( ts ) ;
@@ -66,7 +110,7 @@ export default function ChatPanel() {
66110 </ div >
67111
68112 < div ref = { bodyRef } className = { styles . body } >
69- { messages . map ( ( m , i ) => (
113+ { combinedMessages . map ( ( m , i ) => (
70114 < div
71115 key = { i }
72116 className = { `${ styles . row } ${
0 commit comments