@@ -5,7 +5,7 @@ import BlocklyConfigs from '@components/blockly/xrp_blockly_configs';
55import * as Blockly from 'blockly/core' ;
66import { setBlocklyLocale } from '@/utils/blockly-locales' ;
77import AppMgr , { EventType , Themes } from '@/managers/appmgr' ;
8- import { useEffect , useState } from 'react' ;
8+ import { useCallback , useEffect , useRef , useState } from 'react' ;
99import { useHotkeys } from 'react-hotkeys-hook' ;
1010import { StorageKeys } from '@/utils/localstorage' ;
1111import EditorMgr , { EditorSession } from '@/managers/editormgr' ;
@@ -122,17 +122,36 @@ const blocklyMpdernTheme = Blockly.Theme.defineTheme('modern', {
122122} ) ;
123123
124124interface BlocklyEditorProps {
125- name : string ;
125+ tabname : string ;
126126}
127127
128+ /**
129+ * blocklyToPython
130+ * @param ws
131+ * @returns
132+ */
133+ function blocklyToPython ( ws : Workspace ) {
134+ const pythonCode = pythonGenerator
135+ . workspaceToCode ( ws )
136+ . replace ( 'from numbers import Number\n' , 'Number = int\n' ) ;
137+ const blocklyCode = JSON . stringify ( Blockly . serialization . workspaces . save ( ws ) ) ;
138+ const date = moment ( ) ;
139+ const formatedDate = date . format ( 'YYYY-MM-DD HH:MM:SS' ) ;
140+ const code = pythonCode + '\n\n\n## ' + formatedDate + '\n##XRPBLOCKS ' + blocklyCode ;
141+ return code ;
142+ }
143+
144+
128145/**
129146 * BlocklyEditor component
130147 * @returns
131148 */
132- function BlocklyEditor ( { name } : BlocklyEditorProps ) {
149+ function BlocklyEditor ( { tabname } : BlocklyEditorProps ) {
133150 const [ toolboxKey , setToolboxKey ] = useState ( 0 ) ; // Force re-render when toolbox updates
134151 const [ isLoading , setIsLoading ] = useState < boolean > ( true ) ;
135152 const [ isListenerSet , setIsListenerSet ] = useState ( false ) ;
153+ const [ name , setName ] = useState < string > ( tabname ) ;
154+ const nameRef = useRef ( name ) ;
136155
137156 /**
138157 * handleOnInject
@@ -144,54 +163,46 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
144163 editorSession . workspace = ws ;
145164 }
146165 }
147-
148- /**
149- * blocklyToPython
150- * @param ws
151- * @returns
152- */
153- function blocklyToPython ( ws : Workspace ) {
154- const pythonCode = pythonGenerator
155- . workspaceToCode ( ws )
156- . replace ( 'from numbers import Number\n' , 'Number = int\n' ) ;
157- const blocklyCode = JSON . stringify ( Blockly . serialization . workspaces . save ( ws ) ) ;
158- const date = moment ( ) ;
159- const formatedDate = date . format ( 'YYYY-MM-DD HH:MM:SS' ) ;
160- const code = pythonCode + '\n\n\n## ' + formatedDate + '\n##XRPBLOCKS ' + blocklyCode ;
161- return code ;
162- }
163166
164167 /**
165168 * saveEditor
166169 */
167- async function saveEditor ( ) {
168- const ws = EditorMgr . getInstance ( ) . getEditorSession ( name ) ?. workspace ;
170+ const saveEditor = useCallback ( async ( ) => {
171+ const currentName = nameRef . current ;
172+ const ws = EditorMgr . getInstance ( ) . getEditorSession ( currentName ) ?. workspace ;
169173 if ( ws ) {
170174 const activeTab = localStorage . getItem ( StorageKeys . ACTIVETAB ) ?. replace ( / ^ " | " $ / g, '' ) ;
171- if ( activeTab === name ) {
175+ if ( activeTab === currentName ) {
172176 const code = blocklyToPython ( ws ) ;
173177 console . log ( 'Saving blockly' , activeTab , code ) ;
174- await EditorMgr . getInstance ( ) . saveEditor ( name , code ) ;
178+ await EditorMgr . getInstance ( ) . saveEditor ( currentName , code ) ;
175179 EditorMgr . getInstance ( ) . SaveToLocalStorage (
176- EditorMgr . getInstance ( ) . getEditorSession ( name ) as EditorSession ,
180+ EditorMgr . getInstance ( ) . getEditorSession ( currentName ) as EditorSession ,
177181 code
178182 ) ;
179183 }
180184 }
181- }
185+ } , [ ] ) ;
182186
183187 useHotkeys ( 'ctrl+s, meta+s' , ( event ) => {
184188 event . preventDefault ( ) ;
185189 saveEditor ( ) ;
186190 } ) ;
187191
192+ /**
193+ * useEffect - setup a reference to the editor name
194+ */
195+ useEffect ( ( ) => {
196+ nameRef . current = name ;
197+ } , [ name ] ) ;
198+
188199 useEffect ( ( ) => {
189200 if (
190- EditorMgr . getInstance ( ) . hasEditorSession ( name ) &&
191- ! EditorMgr . getInstance ( ) . hasSubscription ( name )
201+ EditorMgr . getInstance ( ) . hasEditorSession ( nameRef . current ) &&
202+ ! EditorMgr . getInstance ( ) . hasSubscription ( nameRef . current )
192203 ) {
193204 AppMgr . getInstance ( ) . on ( EventType . EVENT_THEME , ( theme ) => {
194- const ws = EditorMgr . getInstance ( ) . getEditorSession ( name ) ?. workspace ;
205+ const ws = EditorMgr . getInstance ( ) . getEditorSession ( nameRef . current ) ?. workspace ;
195206
196207 if ( ws ) {
197208 // Not sure why the compiler complain but it works at runtime
@@ -203,9 +214,9 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
203214
204215 AppMgr . getInstance ( ) . on ( EventType . EVENT_EDITOR_LOAD , ( content ) => {
205216 const loadContent = JSON . parse ( content ) ;
206- if ( loadContent . name !== name ) return ;
217+ if ( loadContent . name !== nameRef . current ) return ;
207218
208- const ws = EditorMgr . getInstance ( ) . getEditorSession ( name ) ?. workspace ;
219+ const ws = EditorMgr . getInstance ( ) . getEditorSession ( nameRef . current ) ?. workspace ;
209220 if ( ws ) {
210221 Blockly . serialization . workspaces . load ( JSON . parse ( loadContent . content ) , ws ) ;
211222 // @ts -expect-error - it is a valid function
@@ -222,7 +233,7 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
222233
223234 AppMgr . getInstance ( ) . on ( EventType . EVENT_EDITOR , ( type ) => {
224235 if ( type === EditorType . BLOCKLY ) {
225- const ws = EditorMgr . getInstance ( ) . getEditorSession ( name ) ?. workspace ;
236+ const ws = EditorMgr . getInstance ( ) . getEditorSession ( nameRef . current ) ?. workspace ;
226237 if ( ws ) {
227238 console . log ( 'rescrolling to center!' )
228239 // @ts -expect-error - it is a valid function
@@ -237,7 +248,7 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
237248
238249 AppMgr . getInstance ( ) . on ( EventType . EVENT_BLOCKLY_TOOLBOX_UPDATED , ( ) => {
239250 // Force a re-render of the Blockly workspace to show new blocks
240- const ws = EditorMgr . getInstance ( ) . getEditorSession ( name ) ?. workspace ;
251+ const ws = EditorMgr . getInstance ( ) . getEditorSession ( nameRef . current ) ?. workspace ;
241252 if ( ws ) {
242253 // Save current workspace content
243254 const content = Blockly . serialization . workspaces . save ( ws ) ;
@@ -260,7 +271,7 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
260271 } ) ;
261272
262273 AppMgr . getInstance ( ) . on ( EventType . EVENT_GENPYTHON , ( activeTab ) => {
263- if ( name === activeTab ) {
274+ if ( nameRef . current === activeTab ) {
264275 const session : EditorSession | undefined =
265276 EditorMgr . getInstance ( ) . getEditorSession ( activeTab ) ;
266277 if ( session ) {
@@ -277,10 +288,14 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
277288 saveEditor ( ) ;
278289 } ) ;
279290
280- EditorMgr . getInstance ( ) . setSubscription ( name ) ;
291+ AppMgr . getInstance ( ) . on ( EventType . EVENT_EDITOR_NAME_CHANGED , ( newName ) => {
292+ setName ( newName ) ;
293+ } ) ;
294+
295+ EditorMgr . getInstance ( ) . setSubscription ( nameRef . current ) ;
281296
282297 } else {
283- const editorSession = EditorMgr . getInstance ( ) . getEditorSession ( name ) ;
298+ const editorSession = EditorMgr . getInstance ( ) . getEditorSession ( nameRef . current ) ;
284299 if ( editorSession && editorSession . content ) {
285300 // There appears to be some timing issues in loading the content into the workspace
286301 // Set 100 ms delay to accommendate the timing issue
@@ -290,11 +305,11 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
290305 const loadContent = { name : name , content : blockContent } ;
291306 AppMgr . getInstance ( ) . emit ( EventType . EVENT_EDITOR_LOAD , JSON . stringify ( loadContent ) ) ;
292307 } ;
293- setTimeout ( loadEditor , 100 , name , editorSession . content ) ;
308+ setTimeout ( loadEditor , 100 , nameRef . current , editorSession . content ) ;
294309 }
295310 }
296311
297- // Set up language based on stored preference
312+ // Set up language based on stored preference
298313 const setupLanguage = ( ) => {
299314 const storedLanguage = localStorage . getItem ( StorageKeys . LANGUAGE ) || 'en' ;
300315 setBlocklyLocale ( storedLanguage ) ;
@@ -320,10 +335,10 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
320335 ) { return ; }
321336 if ( event . type === Blockly . Events . VIEWPORT_CHANGE || event . isUiEvent ) { return ; }
322337 try {
323- console . log ( 'Workspace changed, saving session:' , name ) ;
324- EditorMgr . getInstance ( ) . updateEditorSessionChange ( name , true ) ;
338+ console . log ( 'Workspace changed, saving session:' , nameRef . current ) ;
339+ EditorMgr . getInstance ( ) . updateEditorSessionChange ( nameRef . current , true ) ;
325340 const code = blocklyToPython ( ws ) ;
326- EditorMgr . getInstance ( ) . SaveToLocalStorage ( EditorMgr . getInstance ( ) . getEditorSession ( name ) as EditorSession , code ) ;
341+ EditorMgr . getInstance ( ) . SaveToLocalStorage ( EditorMgr . getInstance ( ) . getEditorSession ( nameRef . current ) as EditorSession , code ) ;
327342 } catch ( e ) {
328343 console . warn ( 'Failed to serialize Blockly workspace:' , e ) ;
329344 }
@@ -351,7 +366,7 @@ function BlocklyEditor({ name }: BlocklyEditorProps) {
351366 ws . removeChangeListener ( listener ) ;
352367 }
353368 }
354- } ) ;
369+ } , [ isListenerSet , isLoading , saveEditor ] ) ;
355370
356371 return (
357372 < BlocklyWorkspace
0 commit comments