33
44import { isDev } from "@/store/global" ;
55import { ImperativePanelGroupHandle , ImperativePanelHandle } from "react-resizable-panels" ;
6+ import * as jotai from "jotai" ;
7+ import { getTabMetaKeyAtom } from "@/app/store/global" ;
8+ import { RpcApi } from "@/app/store/wshclientapi" ;
9+ import { TabRpcClient } from "@/app/store/wshrpcutil" ;
10+ import * as WOS from "@/app/store/wos" ;
11+ import { globalStore } from "@/app/store/jotaiStore" ;
12+ import { atoms } from "@/store/global" ;
13+ import { debounce } from "lodash-es" ;
614
715const AIPANEL_DEFAULTWIDTH = 300 ;
816const AIPANEL_MINWIDTH = 250 ;
917const AIPANEL_MAXWIDTHRATIO = 0.5 ;
1018
1119class WorkspaceLayoutModel {
12- aiPanelVisible : boolean ;
1320 aiPanelRef : ImperativePanelHandle | null ;
1421 panelGroupRef : ImperativePanelGroupHandle | null ;
15- aiPanelWidth : number ;
1622 inResize : boolean ;
17-
23+ private aiPanelVisible : boolean ;
24+ private aiPanelWidth : number ;
25+ private debouncedPersistWidth : ( width : number ) => void ;
26+ private initialized : boolean = false ;
27+
1828 constructor ( ) {
19- this . aiPanelVisible = isDev ( ) ;
2029 this . aiPanelRef = null ;
2130 this . panelGroupRef = null ;
22- this . aiPanelWidth = AIPANEL_DEFAULTWIDTH ;
2331 this . inResize = false ;
32+ this . aiPanelVisible = isDev ( ) ;
33+ this . aiPanelWidth = AIPANEL_DEFAULTWIDTH ;
34+
35+ this . debouncedPersistWidth = debounce ( ( width : number ) => {
36+ try {
37+ RpcApi . SetMetaCommand ( TabRpcClient , {
38+ oref : WOS . makeORef ( "tab" , this . getTabId ( ) ) ,
39+ meta : { "waveai:panelwidth" : width } ,
40+ } ) ;
41+ } catch ( e ) {
42+ console . warn ( "Failed to persist panel width:" , e ) ;
43+ }
44+ } , 300 ) ;
45+ }
46+
47+ private initializeFromTabMeta ( ) : void {
48+ if ( this . initialized ) return ;
49+ this . initialized = true ;
50+
51+ try {
52+ const savedVisible = globalStore . get ( this . getPanelOpenAtom ( ) ) ;
53+ const savedWidth = globalStore . get ( this . getPanelWidthAtom ( ) ) ;
54+
55+ if ( savedVisible != null ) {
56+ this . aiPanelVisible = savedVisible ;
57+ }
58+ if ( savedWidth != null ) {
59+ this . aiPanelWidth = savedWidth ;
60+ }
61+ } catch ( e ) {
62+ console . warn ( "Failed to initialize from tab meta:" , e ) ;
63+ }
64+ }
65+
66+ private getTabId ( ) : string {
67+ return globalStore . get ( atoms . staticTabId ) ;
68+ }
69+
70+ private getPanelOpenAtom ( ) : jotai . Atom < boolean > {
71+ return getTabMetaKeyAtom ( this . getTabId ( ) , "waveai:panelopen" ) ;
72+ }
73+
74+ private getPanelWidthAtom ( ) : jotai . Atom < number > {
75+ return getTabMetaKeyAtom ( this . getTabId ( ) , "waveai:panelwidth" ) ;
2476 }
2577
2678 registerRefs ( aiPanelRef : ImperativePanelHandle , panelGroupRef : ImperativePanelGroupHandle ) : void {
@@ -38,7 +90,7 @@ class WorkspaceLayoutModel {
3890 const aiPanelPercentage = this . getAIPanelPercentage ( currentWindowWidth ) ;
3991 const mainContentPercentage = this . getMainContentPercentage ( currentWindowWidth ) ;
4092
41- if ( this . aiPanelVisible ) {
93+ if ( this . getAIPanelVisible ( ) ) {
4294 this . aiPanelRef . expand ( ) ;
4395 } else {
4496 this . aiPanelRef . collapse ( ) ;
@@ -63,6 +115,7 @@ class WorkspaceLayoutModel {
63115 }
64116
65117 getAIPanelVisible ( ) : boolean {
118+ this . initializeFromTabMeta ( ) ;
66119 return this . aiPanelVisible ;
67120 }
68121
@@ -71,15 +124,21 @@ class WorkspaceLayoutModel {
71124 return ;
72125 }
73126 this . aiPanelVisible = visible ;
127+ RpcApi . SetMetaCommand ( TabRpcClient , {
128+ oref : WOS . makeORef ( "tab" , this . getTabId ( ) ) ,
129+ meta : { "waveai:panelopen" : visible } ,
130+ } ) ;
74131 this . syncAIPanelRef ( ) ;
75132 }
76133
77134 getAIPanelWidth ( ) : number {
135+ this . initializeFromTabMeta ( ) ;
78136 return this . aiPanelWidth ;
79137 }
80138
81139 setAIPanelWidth ( width : number ) : void {
82140 this . aiPanelWidth = width ;
141+ this . debouncedPersistWidth ( width ) ;
83142 }
84143
85144 getAIPanelPercentage ( windowWidth : number ) : number {
@@ -102,7 +161,7 @@ class WorkspaceLayoutModel {
102161 if ( ! isDev ( ) ) {
103162 return ;
104163 }
105- if ( ! this . aiPanelVisible ) {
164+ if ( ! this . getAIPanelVisible ( ) ) {
106165 return ;
107166 }
108167 const clampedWidth = this . getClampedAIPanelWidth ( width , windowWidth ) ;
0 commit comments