@@ -17,6 +17,8 @@ export type ImageImporterToolInput = {
1717  gif ?: boolean  |  undefined ; 
1818} ; 
1919
20+ // TODO: FIX GIFS 
21+ //  https://pyscript.com/@ckyiu /image-to-makecode-arcade/latest?files=main.py,index.html 
2022export  default  function  ImageImporterTool ( ) : React . ReactNode  { 
2123  const  [ inputBuf ,  setInputBuf ]  =  React . useState < ArrayBuffer  |  null > ( null ) ; 
2224
@@ -30,16 +32,65 @@ export default function ImageImporterTool(): React.ReactNode {
3032  const  [ outputCode ,  setOutputCode ]  =  React . useState < string  |  null > ( null ) ; 
3133  const  [ outputBuf ,  setOutputBuf ]  =  React . useState < ArrayBuffer  |  null > ( null ) ; 
3234
35+   const  [ iframeReady ,  setIframeReady ]  =  React . useState ( false ) ; 
36+ 
37+   const  handleMessage  =  React . useCallback ( ( e : MessageEvent )  =>  { 
38+     let  data  =  e . data ; 
39+     console . log ( "Received message from iframe" ) ; 
40+     if  ( e . origin  !==  "https://ckyiu.pyscriptapps.com" )  { 
41+       console . warn ( "Received message from unknown origin" ,  e . origin ) ; 
42+       return ; 
43+     } 
44+     if  ( data  ===  "ready" )  { 
45+       setIframeReady ( true ) ; 
46+       return ; 
47+     } 
48+     try  { 
49+       data  =  JSON . parse ( data ) ; 
50+       setOutputCode ( data . output_image_code ) ; 
51+       setOutputBuf ( Buffer . from ( data . output_preview_img ,  "base64" ) ) ; 
52+       setIframeReady ( true ) ; 
53+     }  catch  ( e )  { 
54+       console . warn ( e ) ; 
55+     } 
56+   } ,  [ ] ) ; 
57+ 
58+   React . useEffect ( ( )  =>  { 
59+     window . addEventListener ( "message" ,  handleMessage ) ; 
60+     return  ( )  =>  { 
61+       window . removeEventListener ( "message" ,  handleMessage ) ; 
62+     } ; 
63+   } ,  [ handleMessage ] ) ; 
64+ 
3365  return  ( 
3466    < div  style = { {  overflowX : "hidden"  } } > 
3567      < form 
3668        onSubmit = { ( e )  =>  { 
3769          e . preventDefault ( ) ; 
3870          console . log ( 
3971            // @ts -ignore 
40-             `Converting image of size ${ inputBuf ?. byteLength  /  1024 }   kb` , 
72+             `Converting image of size ${ Math . round ( inputBuf ?. byteLength  /  1024 ) }   kb` , 
4173          ) ; 
42-           console . log ( `Using options {${ JSON . stringify ( options ) }  }` ) ; 
74+           console . log ( `Using options ${ JSON . stringify ( options ) }  ` ) ; 
75+ 
76+           const  iframe  =  getElement ( "worker-iframe" )  as  HTMLIFrameElement ; 
77+           if  ( iframe . contentWindow )  { 
78+             setIframeReady ( false ) ; 
79+             setOutputCode ( null ) ; 
80+             setOutputBuf ( null ) ; 
81+             setTimeout ( ( )  =>  { 
82+               iframe . contentWindow ! . postMessage ( 
83+                 JSON . stringify ( { 
84+                   input_image : Buffer . from ( inputBuf ! ) . toString ( "base64" ) , 
85+                   input_options : JSON . stringify ( options ) , 
86+                 } ) , 
87+                 "*" , 
88+               ) ; 
89+               console . log ( "Posted message to iframe" ) ; 
90+             } ) ; 
91+           }  else  { 
92+             console . error ( "Failed to get worker iframe content window" ) ; 
93+           } 
4394        } } 
4495      > 
4596        < div > 
@@ -274,7 +325,9 @@ export default function ImageImporterTool(): React.ReactNode {
274325        < button 
275326          type = "submit" 
276327          className = "btn btn-primary" 
277-           disabled = { inputBuf  ==  null  ||  inputBuf . byteLength  ==  0 } 
328+           disabled = { 
329+             inputBuf  ==  null  ||  inputBuf . byteLength  ==  0  ||  ! iframeReady 
330+           } 
278331        > 
279332          Convert
280333        </ button > 
@@ -288,6 +341,7 @@ export default function ImageImporterTool(): React.ReactNode {
288341            < textarea 
289342              id = "output-code" 
290343              className = "form-control" 
344+               style = { {  fontFamily : "monospace"  } } 
291345              placeholder = "No image code generated yet." 
292346              rows = { 10 } 
293347              readOnly 
@@ -340,6 +394,33 @@ export default function ImageImporterTool(): React.ReactNode {
340394        </ div > 
341395        < br  /> 
342396      </ div > 
397+       < div > 
398+         < iframe 
399+           src = "https://ckyiu.pyscriptapps.com/image-to-makecode-arcade/latest/" 
400+           sandbox = "allow-scripts allow-same-origin" 
401+           referrerPolicy = "no-referrer" 
402+           style = { {  width : "50vw" ,  height : "50vh"  } } 
403+           id = "worker-iframe" 
404+         /> 
405+         < br  /> 
406+         < button 
407+           type = "button" 
408+           className = "btn btn-danger" 
409+           onClick = { ( )  =>  { 
410+             const  iframe  =  getElement ( "worker-iframe" )  as  HTMLIFrameElement ; 
411+             const  url  =  iframe . src ; 
412+             iframe . src  =  "" ; 
413+             setTimeout ( ( )  =>  { 
414+               iframe . src  =  url ; 
415+             } ,  100 ) ; 
416+           } } 
417+         > 
418+           reload iframe
419+         </ button > 
420+         < p > 
421+           iframeReady: < code > { iframeReady . toString ( ) } </ code > 
422+         </ p > 
423+       </ div > 
343424    </ div > 
344425  ) ; 
345426} 
0 commit comments