[RAPID-fix] 스크롤 ResizeObserver 추가: 이미지 로드 후 높이 변화 감지해 자동 하단 스크롤
This commit is contained in:
@@ -37,23 +37,40 @@ export function ChatPanel({ room }: ChatPanelProps) {
|
||||
const lastMessageId = messages?.[messages.length - 1]?.id;
|
||||
|
||||
// Scroll to bottom: sentinel scrollIntoView before paint (no visible jump)
|
||||
// Scroll to bottom on room open / new message
|
||||
useLayoutEffect(() => {
|
||||
if (isOpen) bottomRef.current?.scrollIntoView();
|
||||
}, [selectedRoomId, lastMessageId, isOpen]);
|
||||
|
||||
// Second pass for async image loads
|
||||
// ResizeObserver: re-scroll whenever content height changes (images loading, etc.)
|
||||
const shouldAutoScrollRef = useRef(true);
|
||||
useEffect(() => {
|
||||
if (!isOpen) return;
|
||||
const t = setTimeout(() => { bottomRef.current?.scrollIntoView(); }, 600);
|
||||
return () => clearTimeout(t);
|
||||
}, [lastMessageId, selectedRoomId, isOpen]);
|
||||
const el = scrollRef.current;
|
||||
if (!el) return;
|
||||
const inner = el.firstElementChild as HTMLElement | null;
|
||||
if (!inner) return;
|
||||
const ro = new ResizeObserver(() => {
|
||||
if (shouldAutoScrollRef.current) {
|
||||
bottomRef.current?.scrollIntoView();
|
||||
}
|
||||
});
|
||||
ro.observe(inner);
|
||||
return () => ro.disconnect();
|
||||
}, [selectedRoomId]);
|
||||
|
||||
// Track whether user has scrolled up (disable auto-scroll while reading old messages)
|
||||
useEffect(() => {
|
||||
shouldAutoScrollRef.current = true;
|
||||
}, [selectedRoomId, lastMessageId]);
|
||||
|
||||
// Re-attach scroll listener whenever room changes (scrollRef mounts after room is set)
|
||||
useEffect(() => {
|
||||
const el = scrollRef.current;
|
||||
if (!el) return;
|
||||
const onScroll = () => {
|
||||
setIsAtBottom(el.scrollHeight - el.scrollTop - el.clientHeight < 60);
|
||||
const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 60;
|
||||
setIsAtBottom(atBottom);
|
||||
shouldAutoScrollRef.current = atBottom;
|
||||
};
|
||||
el.addEventListener("scroll", onScroll);
|
||||
return () => el.removeEventListener("scroll", onScroll);
|
||||
|
||||
Reference in New Issue
Block a user