mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-04 19:32:12 +00:00
fix: enforce minimum chat width so the git panel can't squish it (#1526)
The git panel can now be dragged toward full window width, but its max was reserved against window.innerWidth (ignoring the sidebar), letting the panel squeeze the chat below a usable width. Clamp the panel against the actual container width and give the chat column a matching min-width floor. Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
parent
acae8b9419
commit
dfa3fc13b9
2 changed files with 26 additions and 14 deletions
|
|
@ -78,16 +78,18 @@ const COLLAPSED_STATE_FALSE = "0"
|
||||||
const PANEL_DEFAULT_WIDTH = 420
|
const PANEL_DEFAULT_WIDTH = 420
|
||||||
const PANEL_MIN_WIDTH = 320
|
const PANEL_MIN_WIDTH = 320
|
||||||
// Keep at least this much room for the chat so the panel can grow to nearly the
|
// Keep at least this much room for the chat so the panel can grow to nearly the
|
||||||
// full window (e.g. ~50/50 on ultrawide screens) without hiding the chat.
|
// full window (e.g. ~50/50 on ultrawide screens) without squishing the chat.
|
||||||
const PANEL_MIN_CHAT_WIDTH = 360
|
// Exported so the chat column can enforce the same floor via min-width.
|
||||||
|
export const PANEL_MIN_CHAT_WIDTH = 360
|
||||||
|
|
||||||
function getPanelMaxWidth(): number {
|
function getPanelMaxWidth(availableWidth?: number): number {
|
||||||
if (typeof window === "undefined") return PANEL_DEFAULT_WIDTH
|
if (typeof window === "undefined") return PANEL_DEFAULT_WIDTH
|
||||||
return Math.max(PANEL_MIN_WIDTH, window.innerWidth - PANEL_MIN_CHAT_WIDTH)
|
const available = availableWidth ?? window.innerWidth
|
||||||
|
return Math.max(PANEL_MIN_WIDTH, available - PANEL_MIN_CHAT_WIDTH)
|
||||||
}
|
}
|
||||||
|
|
||||||
function clampPanelWidth(width: number): number {
|
function clampPanelWidth(width: number, availableWidth?: number): number {
|
||||||
return Math.min(getPanelMaxWidth(), Math.max(PANEL_MIN_WIDTH, width))
|
return Math.min(getPanelMaxWidth(availableWidth), Math.max(PANEL_MIN_WIDTH, width))
|
||||||
}
|
}
|
||||||
|
|
||||||
function readStoredPanelWidth(): number {
|
function readStoredPanelWidth(): number {
|
||||||
|
|
@ -190,6 +192,7 @@ export function AgentGitPanel({ thread, messages }: AgentGitPanelProps) {
|
||||||
)
|
)
|
||||||
const [width, setWidthState] = useState(() => readStoredPanelWidth())
|
const [width, setWidthState] = useState(() => readStoredPanelWidth())
|
||||||
const [fullScreen, setFullScreen] = useState(false)
|
const [fullScreen, setFullScreen] = useState(false)
|
||||||
|
const panelRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
const setCollapsed = (next: boolean) => {
|
const setCollapsed = (next: boolean) => {
|
||||||
setCollapsedState(next)
|
setCollapsedState(next)
|
||||||
|
|
@ -202,18 +205,20 @@ export function AgentGitPanel({ thread, messages }: AgentGitPanelProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const setWidth = useCallback((next: number) => {
|
const setWidth = useCallback((next: number) => {
|
||||||
const clamped = clampPanelWidth(next)
|
const available = panelRef.current?.parentElement?.clientWidth
|
||||||
|
const clamped = clampPanelWidth(next, available)
|
||||||
setWidthState(clamped)
|
setWidthState(clamped)
|
||||||
window.localStorage.setItem(PANEL_STORAGE_WIDTH, String(clamped))
|
window.localStorage.setItem(PANEL_STORAGE_WIDTH, String(clamped))
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// Re-clamp the stored width when the window shrinks so the panel never
|
// Re-clamp against the real container width on mount and whenever the window
|
||||||
// exceeds the available space (which would squeeze out the chat).
|
// resizes, so the panel can never squeeze the chat below its minimum width.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof window === "undefined") return
|
if (typeof window === "undefined") return
|
||||||
const onResize = () => setWidth(width)
|
const reclamp = () => setWidth(width)
|
||||||
window.addEventListener("resize", onResize)
|
reclamp()
|
||||||
return () => window.removeEventListener("resize", onResize)
|
window.addEventListener("resize", reclamp)
|
||||||
|
return () => window.removeEventListener("resize", reclamp)
|
||||||
}, [setWidth, width])
|
}, [setWidth, width])
|
||||||
const [selectedTreePath, setSelectedTreePath] = useState<string | null>(null)
|
const [selectedTreePath, setSelectedTreePath] = useState<string | null>(null)
|
||||||
const sectionRefs = useRef<Record<string, HTMLDivElement | null>>({})
|
const sectionRefs = useRef<Record<string, HTMLDivElement | null>>({})
|
||||||
|
|
@ -305,6 +310,7 @@ export function AgentGitPanel({ thread, messages }: AgentGitPanelProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside
|
<aside
|
||||||
|
ref={panelRef}
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative flex shrink-0 flex-col bg-[var(--ui-bg)]",
|
"relative flex shrink-0 flex-col bg-[var(--ui-bg)]",
|
||||||
fullScreen ? "fixed inset-0 !w-full" : "h-full"
|
fullScreen ? "fixed inset-0 !w-full" : "h-full"
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@ import { useStreamContext as useAgentThreadStream } from "@langchain/react"
|
||||||
|
|
||||||
import type { AgentThread, Message } from "@/lib/agents/types"
|
import type { AgentThread, Message } from "@/lib/agents/types"
|
||||||
import type { ModelSelection } from "@/lib/agents/provider/useModelOptions"
|
import type { ModelSelection } from "@/lib/agents/provider/useModelOptions"
|
||||||
import { AgentGitPanel } from "@/components/agents/AgentGitPanel"
|
import {
|
||||||
|
AgentGitPanel,
|
||||||
|
PANEL_MIN_CHAT_WIDTH,
|
||||||
|
} from "@/components/agents/AgentGitPanel"
|
||||||
import { AgentPromptBar } from "@/components/agents/AgentPromptBar"
|
import { AgentPromptBar } from "@/components/agents/AgentPromptBar"
|
||||||
import { Messages } from "@/components/agents/messages"
|
import { Messages } from "@/components/agents/messages"
|
||||||
import { streamMessagesToUi } from "@/lib/agents/streamMessagesToUi"
|
import { streamMessagesToUi } from "@/lib/agents/streamMessagesToUi"
|
||||||
|
|
@ -58,7 +61,10 @@ export function AgentThreadView({ thread }: AgentThreadViewProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-w-0 flex-1">
|
<div className="flex min-w-0 flex-1">
|
||||||
<div className="flex min-w-0 flex-1 flex-col">
|
<div
|
||||||
|
className="flex flex-1 flex-col"
|
||||||
|
style={{ minWidth: PANEL_MIN_CHAT_WIDTH }}
|
||||||
|
>
|
||||||
{hasMessages ? (
|
{hasMessages ? (
|
||||||
<div className="relative flex min-h-0 flex-1 flex-col overflow-hidden">
|
<div className="relative flex min-h-0 flex-1 flex-col overflow-hidden">
|
||||||
<Messages
|
<Messages
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue