Skip to content

Commit fac1c7c

Browse files
committed
feat: 채팅 크기 조절 로직 구현
1 parent 2bf006e commit fac1c7c

1 file changed

Lines changed: 98 additions & 9 deletions

File tree

  • apps/www/src/components/bookmarks/graph/chat-bot

apps/www/src/components/bookmarks/graph/chat-bot/index.tsx

Lines changed: 98 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ export default function ChatBot() {
1515
const [isNewChat, setIsNewChat] = useState(true);
1616
const [chatListWidth, setChatListWidth] = useState(160); // w-40 = 160px
1717
const [isDragging, setIsDragging] = useState(false);
18-
const dragRef = useRef<HTMLDivElement>(null);
18+
const [isResizingWidth, setIsResizingWidth] = useState(false);
19+
const [isResizingHeight, setIsResizingHeight] = useState(false);
20+
const [chatBoxWidth, setChatBoxWidth] = useState(() => Math.max(window.innerWidth * 0.5, 480));
21+
const [chatBoxHeight, setChatBoxHeight] = useState(384);
22+
const chatBoxRef = useRef<HTMLDivElement>(null);
1923

2024
const { data: chatSessions, isLoading: isChatSessionsLoading } = useGetAllChatSessions();
2125

@@ -29,13 +33,13 @@ export default function ChatBot() {
2933

3034
const onMouseMove = useCallback(
3135
(e: MouseEvent) => {
32-
if (!isDragging || !dragRef.current) return;
36+
if (!isDragging || !chatBoxRef.current) return;
3337

34-
const containerRect = dragRef.current.getBoundingClientRect();
38+
const containerRect = chatBoxRef.current.getBoundingClientRect();
3539
const newWidth = e.clientX - containerRect.left;
3640

3741
// 최소 128px (w-32), 최대 160px (w-40)
38-
const clampedWidth = Math.max(128, Math.min(160, newWidth));
42+
const clampedWidth = Math.max(128, Math.min(containerRect.width / 3, newWidth));
3943
setChatListWidth(clampedWidth);
4044
},
4145
[isDragging]
@@ -47,6 +51,54 @@ export default function ChatBot() {
4751
document.body.style.userSelect = "";
4852
}, []);
4953

54+
// Width resize handlers
55+
const onResizeWidthMouseDown = (e: React.MouseEvent) => {
56+
e.preventDefault();
57+
setIsResizingWidth(true);
58+
document.body.style.cursor = "ew-resize";
59+
document.body.style.userSelect = "none";
60+
};
61+
const onResizeWidthMouseMove = useCallback(
62+
(e: MouseEvent) => {
63+
if (!isResizingWidth || !chatBoxRef.current) return;
64+
const box = chatBoxRef.current.getBoundingClientRect();
65+
const newWidth = box.right - e.clientX;
66+
const minWidth = 480; // 30rem
67+
const maxWidth = window.innerWidth * 0.5;
68+
setChatBoxWidth(Math.max(minWidth, Math.min(maxWidth, newWidth)));
69+
},
70+
[isResizingWidth]
71+
);
72+
const onResizeWidthMouseUp = useCallback(() => {
73+
setIsResizingWidth(false);
74+
document.body.style.cursor = "";
75+
document.body.style.userSelect = "";
76+
}, []);
77+
78+
// Height resize handlers
79+
const onResizeHeightMouseDown = (e: React.MouseEvent) => {
80+
e.preventDefault();
81+
setIsResizingHeight(true);
82+
document.body.style.cursor = "ns-resize";
83+
document.body.style.userSelect = "none";
84+
};
85+
const onResizeHeightMouseMove = useCallback(
86+
(e: MouseEvent) => {
87+
if (!isResizingHeight || !chatBoxRef.current) return;
88+
const box = chatBoxRef.current.getBoundingClientRect();
89+
const newHeight = box.bottom - e.clientY;
90+
const minHeight = 384; // 24rem
91+
const maxHeight = window.innerHeight - 40;
92+
setChatBoxHeight(Math.max(minHeight, Math.min(maxHeight, newHeight)));
93+
},
94+
[isResizingHeight]
95+
);
96+
const onResizeHeightMouseUp = useCallback(() => {
97+
setIsResizingHeight(false);
98+
document.body.style.cursor = "";
99+
document.body.style.userSelect = "";
100+
}, []);
101+
50102
// 마우스 이벤트 리스너 등록
51103
useEffect(() => {
52104
if (isDragging) {
@@ -58,7 +110,23 @@ export default function ChatBot() {
58110
document.removeEventListener("mouseup", onMouseUp);
59111
};
60112
}
61-
}, [isDragging, onMouseMove, onMouseUp]);
113+
if (isResizingWidth) {
114+
document.addEventListener("mousemove", onResizeWidthMouseMove);
115+
document.addEventListener("mouseup", onResizeWidthMouseUp);
116+
return () => {
117+
document.removeEventListener("mousemove", onResizeWidthMouseMove);
118+
document.removeEventListener("mouseup", onResizeWidthMouseUp);
119+
};
120+
}
121+
if (isResizingHeight) {
122+
document.addEventListener("mousemove", onResizeHeightMouseMove);
123+
document.addEventListener("mouseup", onResizeHeightMouseUp);
124+
return () => {
125+
document.removeEventListener("mousemove", onResizeHeightMouseMove);
126+
document.removeEventListener("mouseup", onResizeHeightMouseUp);
127+
};
128+
}
129+
}, [isDragging, isResizingWidth, isResizingHeight]);
62130

63131
// 컴포넌트 언마운트 시 cleanup
64132
useEffect(() => {
@@ -75,12 +143,33 @@ export default function ChatBot() {
75143
</button>
76144
{isOpen && (
77145
<div
78-
ref={dragRef}
79-
className="absolute bottom-0 right-full mr-2 flex h-96 w-[42rem] gap-0 rounded-lg border border-blue-400 bg-white p-2 text-black"
146+
ref={chatBoxRef}
147+
className="absolute bottom-0 right-full mr-2 flex gap-0 rounded-lg border border-blue-400 bg-white p-2 text-black"
148+
style={{
149+
minWidth: "30rem",
150+
maxWidth: "50vw",
151+
minHeight: "24rem",
152+
maxHeight: "calc(100vh - 2.5rem)",
153+
width: chatBoxWidth,
154+
height: chatBoxHeight,
155+
overflow: "auto",
156+
}}
80157
>
158+
{/* Left edge resize handle */}
159+
<div
160+
className="absolute left-0 top-0 z-20 h-full w-2 cursor-ew-resize"
161+
style={{ userSelect: "none" }}
162+
onMouseDown={onResizeWidthMouseDown}
163+
/>
164+
{/* Top edge resize handle */}
165+
<div
166+
className="absolute left-0 top-0 z-20 h-2 w-full cursor-ns-resize"
167+
style={{ userSelect: "none" }}
168+
onMouseDown={onResizeHeightMouseDown}
169+
/>
81170
<ul
82171
className="relative flex flex-col gap-2 overflow-y-auto"
83-
style={{ width: `${chatListWidth}px` }}
172+
style={{ width: `${chatListWidth}px`, minWidth: "10rem", maxWidth: "16rem" }}
84173
>
85174
{isChatSessionsLoading ? (
86175
<div className="mx-auto flex h-full items-center justify-center">
@@ -123,7 +212,7 @@ export default function ChatBot() {
123212
<div className="absolute left-1/2 top-1/2 h-12 w-1 -translate-x-1/2 -translate-y-1/2 rounded-full bg-gray-400 transition-colors hover:bg-blue-500" />
124213
</div>
125214

126-
<div className="min-w-0 flex-1">
215+
<div className="h-full min-w-0 flex-1">
127216
<Chat
128217
sessionId={currentSession}
129218
onSessionCreated={setCurrentSession}

0 commit comments

Comments
 (0)