@@ -20,16 +20,114 @@ const ScratchIntegrationHOC = function (WrappedComponent) {
2020 "handleUpload" ,
2121 "handleRemix" ,
2222 "handleSave" ,
23+ "handleBlocksChanged" ,
2324 ] ) ;
2425 }
2526 componentDidMount ( ) {
2627 window . addEventListener ( "message" , this . handleMessage ) ;
2728 this . props . setStageSize ( ) ;
29+ if ( this . props . vm ) {
30+ console . log ( "Setting up VM listeners in componentDidMount..." ) ;
31+ this . setupVMListeners ( ) ;
32+ } else {
33+ console . log ( "VM not available yet in componentDidMount." ) ;
34+ }
35+ }
36+
37+ componentDidUpdate ( prevProps ) {
38+ // Set up listeners when VM becomes available
39+ if ( ! prevProps . vm && this . props . vm ) {
40+ console . log ( "Setting up VM listeners in componentDidUpdate..." ) ;
41+ this . setupVMListeners ( ) ;
42+ }
2843 }
44+
2945 componentWillUnmount ( ) {
3046 window . removeEventListener ( "message" , this . handleMessage ) ;
47+ this . removeVMListeners ( ) ;
48+ }
49+
50+ setupVMListeners ( ) {
51+ const vm = this . props . vm ;
52+ if ( ! vm ) return ;
53+
54+ console . log ( "=== Looking for Blockly workspace ===" ) ;
55+
56+ // Method 1: Check for global Blockly
57+ if ( window . Blockly ) {
58+ console . log ( "Found global Blockly:" , window . Blockly ) ;
59+ const workspace = window . Blockly . getMainWorkspace ?. ( ) ;
60+ console . log ( "Blockly main workspace:" , workspace ) ;
61+
62+ if ( workspace ) {
63+ workspace . addChangeListener ( ( event ) => {
64+ console . log ( "Blockly workspace change event:" , event ) ;
65+ console . log ( "Event type:" , event . type ) ;
66+ if ( event . type === "endDrag" ) {
67+ this . handleBlocksChanged ( ) ;
68+ }
69+ } ) ;
70+ console . log ( "✓ Added Blockly workspace change listener" ) ;
71+ return ; // Success!
72+ }
73+ }
74+ // const vm = this.props.vm;
75+ // if (!vm) return;
76+
77+ // // if (vm.runtime.getEditingTarget()) {
78+ // // const workspace = vm.runtime.getEditingTarget().blocks;
79+ // console.log(vm);
80+ // console.log(vm.runtime);
81+ // console.log(vm.runtime.constructor.PROJECT_CHANGED);
82+ // vm.runtime.on('BLOCK_DRAG_UPDATE', this.handleBlocksChanged);
83+ // // workspace.on('BLOCK_CREATE', this.handleBlocksChanged);
84+ // // workspace.on('BLOCK_DELETE', this.handleBlocksChanged);
85+ // // }
86+ // console.log("Blocks changed listener set up...")
87+ // // this.startPolling();
88+ }
89+
90+ removeVMListeners ( ) {
91+ // Clean up any listeners set up in setupVMListeners
92+ const vm = this . props . vm ;
93+ if ( ! vm ) return ;
94+
95+ // const workspace = vm.runtime.getEditingTarget()?.blocks;
96+ vm . runtime . removeListener ( 'BLOCK_DRAG_UPDATE' , this . handleBlocksChanged ) ;
3197 }
98+ handleBlocksChanged ( ) {
99+ console . log ( "Blocks have changed" ) ;
100+
101+ // Debounce to avoid saving on every tiny change
102+ if ( this . saveTimeout ) {
103+ clearTimeout ( this . saveTimeout ) ;
104+ }
105+
106+ this . saveTimeout = setTimeout ( ( ) => {
107+ if ( this . props . saveProjectSb3 ) {
108+ this . props . saveProjectSb3 ( ) . then ( ( sb3Content ) => {
109+ console . log ( "Autosaving project..." , sb3Content ) ;
110+
111+ // Convert Blob/ArrayBuffer to base64 for localStorage
112+ const reader = new FileReader ( ) ;
113+ reader . onloadend = ( ) => {
114+ const base64String = reader . result . split ( ',' ) [ 1 ] ; // Remove data:application/octet-stream;base64, prefix
115+ localStorage . setItem ( "autosavedProject" , base64String ) ;
116+ console . log ( "Project saved to localStorage (base64)" ) ;
117+ } ;
118+ reader . readAsDataURL ( sb3Content ) ;
119+
120+ // This sb3Content is what you'd send to your save API
121+ // It's the complete .sb3 file content
122+ } ) ;
123+ }
124+ } , 2000 ) ; // Wait 2 seconds after last change
125+ } ;
126+
32127 handleMessage ( event ) {
128+ // These are events sent from the page telling Scratch GUI to do certain things.
129+ // Here we are telling Scratch GUI how to do those things.
130+ // We want this the other way around in some of these cases.
33131 if ( event . origin !== window . location . origin ) return ;
34132
35133 switch ( event . data . type ) {
@@ -103,13 +201,17 @@ const ScratchIntegrationHOC = function (WrappedComponent) {
103201 saveProjectSb3 : null ,
104202 loadProject : null ,
105203 vmReady : false ,
204+ vm : null ,
106205 } ;
206+ } else {
207+ console . log ( "Scratch VM is initialized" ) ;
107208 }
108209
109210 return {
110211 saveProjectSb3 : vm . saveProjectSb3 ?. bind ( vm ) ,
111212 loadProject : vm . loadProject ?. bind ( vm ) ,
112213 vmReady : true ,
214+ vm : vm ,
113215 } ;
114216 } ;
115217
0 commit comments