@@ -21,6 +21,7 @@ import PortDetectionModal from "@/components/ui/PortDetectionModal";
2121import PortDetectionButton from "@/components/ui/PortDetectionButton" ;
2222import QrCodeModal from "@/components/recording/QrCodeModal" ;
2323import { useApi } from "@/contexts/ApiContext" ;
24+ import { useAutoSave } from "@/hooks/useAutoSave" ;
2425interface RecordingModalProps {
2526 open : boolean ;
2627 onOpenChange : ( open : boolean ) => void ;
@@ -66,16 +67,54 @@ const RecordingModal: React.FC<RecordingModalProps> = ({
6667 onStart,
6768} ) => {
6869 const { baseUrl, fetchWithHeaders } = useApi ( ) ;
70+ const { debouncedSavePort, debouncedSaveConfig } = useAutoSave ( ) ;
6971 const [ showPortDetection , setShowPortDetection ] = useState ( false ) ;
7072 const [ detectionRobotType , setDetectionRobotType ] = useState <
7173 "leader" | "follower"
7274 > ( "leader" ) ;
7375 const [ showQrCodeModal , setShowQrCodeModal ] = useState ( false ) ;
7476 const [ sessionId , setSessionId ] = useState ( "" ) ;
7577
76- // Load saved ports on component mount
78+ const handlePortDetection = ( robotType : "leader" | "follower" ) => {
79+ setDetectionRobotType ( robotType ) ;
80+ setShowPortDetection ( true ) ;
81+ } ;
82+ const handlePortDetected = ( port : string ) => {
83+ if ( detectionRobotType === "leader" ) {
84+ setLeaderPort ( port ) ;
85+ } else {
86+ setFollowerPort ( port ) ;
87+ }
88+ } ;
89+
90+ // Enhanced port change handlers that save automatically
91+ const handleLeaderPortChange = ( value : string ) => {
92+ setLeaderPort ( value ) ;
93+ // Auto-save with debouncing to avoid excessive API calls
94+ debouncedSavePort ( "leader" , value ) ;
95+ } ;
96+
97+ const handleFollowerPortChange = ( value : string ) => {
98+ setFollowerPort ( value ) ;
99+ // Auto-save with debouncing to avoid excessive API calls
100+ debouncedSavePort ( "follower" , value ) ;
101+ } ;
102+
103+ // Enhanced config change handlers that save automatically
104+ const handleLeaderConfigChange = ( value : string ) => {
105+ setLeaderConfig ( value ) ;
106+ // Auto-save with debouncing to avoid excessive API calls
107+ debouncedSaveConfig ( "leader" , value ) ;
108+ } ;
109+
110+ const handleFollowerConfigChange = ( value : string ) => {
111+ setFollowerConfig ( value ) ;
112+ // Auto-save with debouncing to avoid excessive API calls
113+ debouncedSaveConfig ( "follower" , value ) ;
114+ } ;
115+ // Load saved ports and configurations on component mount
77116 useEffect ( ( ) => {
78- const loadSavedPorts = async ( ) => {
117+ const loadSavedData = async ( ) => {
79118 try {
80119 // Load leader port
81120 const leaderResponse = await fetchWithHeaders (
@@ -94,25 +133,34 @@ const RecordingModal: React.FC<RecordingModalProps> = ({
94133 if ( followerData . status === "success" && followerData . default_port ) {
95134 setFollowerPort ( followerData . default_port ) ;
96135 }
136+
137+ // Load leader configuration
138+ const leaderConfigResponse = await fetchWithHeaders (
139+ `${ baseUrl } /robot-config/leader?available_configs=${ leaderConfigs . join ( ',' ) } `
140+ ) ;
141+ const leaderConfigData = await leaderConfigResponse . json ( ) ;
142+ if ( leaderConfigData . status === "success" && leaderConfigData . default_config ) {
143+ setLeaderConfig ( leaderConfigData . default_config ) ;
144+ }
145+
146+ // Load follower configuration
147+ const followerConfigResponse = await fetchWithHeaders (
148+ `${ baseUrl } /robot-config/follower?available_configs=${ followerConfigs . join ( ',' ) } `
149+ ) ;
150+ const followerConfigData = await followerConfigResponse . json ( ) ;
151+ if ( followerConfigData . status === "success" && followerConfigData . default_config ) {
152+ setFollowerConfig ( followerConfigData . default_config ) ;
153+ }
97154 } catch ( error ) {
98- console . error ( "Error loading saved ports :" , error ) ;
155+ console . error ( "Error loading saved data :" , error ) ;
99156 }
100157 } ;
101- if ( open ) {
102- loadSavedPorts ( ) ;
103- }
104- } , [ open , setLeaderPort , setFollowerPort ] ) ;
105- const handlePortDetection = ( robotType : "leader" | "follower" ) => {
106- setDetectionRobotType ( robotType ) ;
107- setShowPortDetection ( true ) ;
108- } ;
109- const handlePortDetected = ( port : string ) => {
110- if ( detectionRobotType === "leader" ) {
111- setLeaderPort ( port ) ;
112- } else {
113- setFollowerPort ( port ) ;
158+
159+ if ( open && leaderConfigs . length > 0 && followerConfigs . length > 0 ) {
160+ loadSavedData ( ) ;
114161 }
115- } ;
162+ } , [ open , setLeaderPort , setFollowerPort , setLeaderConfig , setFollowerConfig , leaderConfigs , followerConfigs , baseUrl , fetchWithHeaders ] ) ;
163+
116164 const handleQrCodeClick = ( ) => {
117165 // Generate a session ID for this recording session
118166 const newSessionId = `recording_${ Date . now ( ) } _${ Math . random ( )
@@ -175,7 +223,7 @@ const RecordingModal: React.FC<RecordingModalProps> = ({
175223 < Input
176224 id = "recordLeaderPort"
177225 value = { leaderPort }
178- onChange = { ( e ) => setLeaderPort ( e . target . value ) }
226+ onChange = { ( e ) => handleLeaderPortChange ( e . target . value ) }
179227 placeholder = "/dev/tty.usbmodem5A460816421"
180228 className = "bg-gray-800 border-gray-700 text-white flex-1"
181229 />
@@ -194,7 +242,7 @@ const RecordingModal: React.FC<RecordingModalProps> = ({
194242 </ Label >
195243 < Select
196244 value = { leaderConfig }
197- onValueChange = { setLeaderConfig }
245+ onValueChange = { handleLeaderConfigChange }
198246 >
199247 < SelectTrigger className = "bg-gray-800 border-gray-700 text-white" >
200248 < SelectValue
@@ -229,7 +277,7 @@ const RecordingModal: React.FC<RecordingModalProps> = ({
229277 < Input
230278 id = "recordFollowerPort"
231279 value = { followerPort }
232- onChange = { ( e ) => setFollowerPort ( e . target . value ) }
280+ onChange = { ( e ) => handleFollowerPortChange ( e . target . value ) }
233281 placeholder = "/dev/tty.usbmodem5A460816621"
234282 className = "bg-gray-800 border-gray-700 text-white flex-1"
235283 />
@@ -248,7 +296,7 @@ const RecordingModal: React.FC<RecordingModalProps> = ({
248296 </ Label >
249297 < Select
250298 value = { followerConfig }
251- onValueChange = { setFollowerConfig }
299+ onValueChange = { handleFollowerConfigChange }
252300 >
253301 < SelectTrigger className = "bg-gray-800 border-gray-700 text-white" >
254302 < SelectValue
0 commit comments