Skip to content

Commit 54012ac

Browse files
committed
Make bottom pane resizable
1 parent 0cf344b commit 54012ac

File tree

2 files changed

+65
-9
lines changed

2 files changed

+65
-9
lines changed

client/src/App.tsx

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
CompatibilityCallToolResult,
2323
ClientNotification,
2424
} from "@modelcontextprotocol/sdk/types.js";
25-
import { useEffect, useRef, useState } from "react";
25+
import { useCallback, useEffect, useRef, useState } from "react";
2626
// Add dark mode class based on system preference
2727
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
2828
document.documentElement.classList.add("dark");
@@ -127,6 +127,49 @@ const App = () => {
127127
>();
128128
const [nextToolCursor, setNextToolCursor] = useState<string | undefined>();
129129
const progressTokenRef = useRef(0);
130+
const [historyPaneHeight, setHistoryPaneHeight] = useState<number>(300);
131+
const [isDragging, setIsDragging] = useState(false);
132+
const dragStartY = useRef<number>(0);
133+
const dragStartHeight = useRef<number>(0);
134+
135+
const handleDragStart = useCallback(
136+
(e: React.MouseEvent) => {
137+
setIsDragging(true);
138+
dragStartY.current = e.clientY;
139+
dragStartHeight.current = historyPaneHeight;
140+
document.body.style.userSelect = "none";
141+
},
142+
[historyPaneHeight],
143+
);
144+
145+
const handleDragMove = useCallback(
146+
(e: MouseEvent) => {
147+
if (!isDragging) return;
148+
const deltaY = dragStartY.current - e.clientY;
149+
const newHeight = Math.max(
150+
100,
151+
Math.min(800, dragStartHeight.current + deltaY),
152+
);
153+
setHistoryPaneHeight(newHeight);
154+
},
155+
[isDragging],
156+
);
157+
158+
const handleDragEnd = useCallback(() => {
159+
setIsDragging(false);
160+
document.body.style.userSelect = "";
161+
}, []);
162+
163+
useEffect(() => {
164+
if (isDragging) {
165+
window.addEventListener("mousemove", handleDragMove);
166+
window.addEventListener("mouseup", handleDragEnd);
167+
return () => {
168+
window.removeEventListener("mousemove", handleDragMove);
169+
window.removeEventListener("mouseup", handleDragEnd);
170+
};
171+
}
172+
}, [isDragging, handleDragMove, handleDragEnd]);
130173

131174
useEffect(() => {
132175
localStorage.setItem("lastCommand", command);
@@ -467,11 +510,24 @@ const App = () => {
467510
</div>
468511
)}
469512
</div>
470-
<div className="h-1/3 min-h-[200px] border-t border-border">
471-
<HistoryAndNotifications
472-
requestHistory={requestHistory}
473-
serverNotifications={notifications}
474-
/>
513+
<div
514+
className="relative border-t border-border"
515+
style={{
516+
height: `${historyPaneHeight}px`,
517+
}}
518+
>
519+
<div
520+
className="absolute w-full h-4 -top-2 cursor-row-resize flex items-center justify-center hover:bg-accent/50"
521+
onMouseDown={handleDragStart}
522+
>
523+
<div className="w-8 h-1 rounded-full bg-border" />
524+
</div>
525+
<div className="h-full overflow-auto">
526+
<HistoryAndNotifications
527+
requestHistory={requestHistory}
528+
serverNotifications={notifications}
529+
/>
530+
</div>
475531
</div>
476532
</div>
477533
</div>

client/src/components/History.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ const HistoryAndNotifications = ({
2929
};
3030

3131
return (
32-
<div className="bg-card p-4 overflow-hidden flex h-full">
33-
<div className="flex-1 overflow-y-auto px-4 border-r">
32+
<div className="bg-card overflow-hidden flex h-full">
33+
<div className="flex-1 overflow-y-auto p-4 border-r">
3434
<h2 className="text-lg font-semibold mb-4">History</h2>
3535
{requestHistory.length === 0 ? (
3636
<p className="text-sm text-gray-500 italic">No history yet</p>
@@ -107,7 +107,7 @@ const HistoryAndNotifications = ({
107107
</ul>
108108
)}
109109
</div>
110-
<div className="flex-1 overflow-y-auto px-4">
110+
<div className="flex-1 overflow-y-auto p-4">
111111
<h2 className="text-lg font-semibold mb-4">Server Notifications</h2>
112112
{serverNotifications.length === 0 ? (
113113
<p className="text-sm text-gray-500 italic">No notifications yet</p>

0 commit comments

Comments
 (0)