@@ -8,6 +8,47 @@ import { ChatView } from "./chat-panel";
88
99import { useShell } from "~/contexts/shell" ;
1010
11+ const FLOATING_CHAT_PADDING_PX = 32 ;
12+ const FLOATING_CHAT_MIN_WIDTH_PX = 320 ;
13+ const FLOATING_CHAT_MIN_HEIGHT_PX = 400 ;
14+ const DEFAULT_FLOATING_CHAT_WIDTH_PX = 400 ;
15+ const DEFAULT_FLOATING_CHAT_HEIGHT_RATIO = 0.7 ;
16+
17+ function getFloatingViewportSize ( ) {
18+ return {
19+ width : Math . max ( window . innerWidth - FLOATING_CHAT_PADDING_PX , 1 ) ,
20+ height : Math . max ( window . innerHeight - FLOATING_CHAT_PADDING_PX , 1 ) ,
21+ } ;
22+ }
23+
24+ function clampFloatingSize ( size : { width : number ; height : number } ) {
25+ const viewport = getFloatingViewportSize ( ) ;
26+
27+ return {
28+ width : Math . min (
29+ Math . max (
30+ size . width ,
31+ Math . min ( FLOATING_CHAT_MIN_WIDTH_PX , viewport . width ) ,
32+ ) ,
33+ viewport . width ,
34+ ) ,
35+ height : Math . min (
36+ Math . max (
37+ size . height ,
38+ Math . min ( FLOATING_CHAT_MIN_HEIGHT_PX , viewport . height ) ,
39+ ) ,
40+ viewport . height ,
41+ ) ,
42+ } ;
43+ }
44+
45+ function getDefaultFloatingSize ( ) {
46+ return clampFloatingSize ( {
47+ width : DEFAULT_FLOATING_CHAT_WIDTH_PX ,
48+ height : window . innerHeight * DEFAULT_FLOATING_CHAT_HEIGHT_RATIO ,
49+ } ) ;
50+ }
51+
1152export function PersistentChatPanel ( {
1253 panelContainerRef,
1354} : {
@@ -20,10 +61,7 @@ export function PersistentChatPanel({
2061 const isVisible = isFloating || isPanel ;
2162
2263 const [ hasBeenOpened , setHasBeenOpened ] = useState ( false ) ;
23- const [ floatingSize , setFloatingSize ] = useState ( {
24- width : 400 ,
25- height : window . innerHeight * 0.7 ,
26- } ) ;
64+ const [ floatingSize , setFloatingSize ] = useState ( getDefaultFloatingSize ) ;
2765 const [ panelRect , setPanelRect ] = useState < DOMRect | null > ( null ) ;
2866 const observerRef = useRef < ResizeObserver | null > ( null ) ;
2967
@@ -33,20 +71,6 @@ export function PersistentChatPanel({
3371 }
3472 } , [ isVisible , hasBeenOpened ] ) ;
3573
36- useEffect ( ( ) => {
37- if ( ! isFloating ) return ;
38-
39- const handleResize = ( ) => {
40- setFloatingSize ( ( prev ) => ( {
41- ...prev ,
42- height : window . innerHeight * 0.7 ,
43- } ) ) ;
44- } ;
45-
46- window . addEventListener ( "resize" , handleResize ) ;
47- return ( ) => window . removeEventListener ( "resize" , handleResize ) ;
48- } , [ isFloating ] ) ;
49-
5074 useHotkeys (
5175 "esc" ,
5276 ( ) => chat . sendEvent ( { type : "CLOSE" } ) ,
@@ -133,10 +157,12 @@ export function PersistentChatPanel({
133157 onResizeStop = {
134158 isFloating
135159 ? ( _ , __ , ___ , d ) => {
136- setFloatingSize ( ( prev ) => ( {
137- width : prev . width + d . width ,
138- height : prev . height + d . height ,
139- } ) ) ;
160+ setFloatingSize ( ( prev ) =>
161+ clampFloatingSize ( {
162+ width : prev . width + d . width ,
163+ height : prev . height + d . height ,
164+ } ) ,
165+ ) ;
140166 }
141167 : undefined
142168 }
@@ -154,11 +180,10 @@ export function PersistentChatPanel({
154180 }
155181 : false
156182 }
157- minWidth = { isFloating ? 320 : undefined }
158- minHeight = { isFloating ? 400 : undefined }
159- maxWidth = { isFloating ? window . innerWidth - 32 : undefined }
160- maxHeight = { isFloating ? window . innerHeight - 32 : undefined }
183+ minWidth = { isFloating ? FLOATING_CHAT_MIN_WIDTH_PX : undefined }
184+ minHeight = { isFloating ? FLOATING_CHAT_MIN_HEIGHT_PX : undefined }
161185 bounds = { isFloating ? "window" : undefined }
186+ boundsByDirection = { isFloating }
162187 className = { cn ( [
163188 "pointer-events-auto flex min-h-0 min-w-0 flex-col overflow-hidden" ,
164189 isFloating && [
0 commit comments