1
+ import React , { useState , useEffect } from 'react' ;
2
+ import classnames from 'classnames' ;
3
+
4
+ import ProcessingIcon from '../images/logo-processing.svg' ;
5
+
6
+ import * as css from './OpenWithButton.module.css' ;
7
+
8
+ const OpenWithButton = ( { pdes, dataFiles } ) => {
9
+ const main = pdes [ 0 ]
10
+ const [ sketchURL , setSketchURL ] = useState ( `processing://open?sketch=${ stringToBase64 ( main . code ) } ` )
11
+
12
+ useEffect ( ( ) => {
13
+ let sketchURL = `pde://sketch/base64/${ stringToBase64 ( main . code ) } ?pde=`
14
+ for ( let pde of pdes ) {
15
+ if ( pde === main ) continue
16
+ sketchURL += `${ pde . name } :${ stringToBase64 ( pde . code ) } ,`
17
+ }
18
+ if ( dataFiles . length > 0 ) {
19
+ let data = '&data=' + dataFiles . map ( file => file . relativePath . split ( '/' ) . pop ( ) + ":" + window . location . protocol + "//" + window . location . host + file . publicURL ) . join ( ',' )
20
+ sketchURL += data
21
+ }
22
+ setSketchURL ( sketchURL )
23
+ } , [ ] )
24
+ const [ showInstructions , setShowInstructions ] = useState ( false )
25
+
26
+ useEffect ( ( ) => {
27
+ const handleClickOutside = ( event ) => {
28
+ if ( showInstructions && ! event . target . closest ( `.${ css . root } ` ) ) {
29
+ setShowInstructions ( false ) ;
30
+ }
31
+ } ;
32
+
33
+ document . addEventListener ( 'click' , handleClickOutside ) ;
34
+ return ( ) => document . removeEventListener ( 'click' , handleClickOutside ) ;
35
+ } , [ showInstructions ] ) ;
36
+
37
+ return (
38
+ < a
39
+ href = { sketchURL }
40
+ type = "button"
41
+ className = { classnames ( css . root ) }
42
+ onClick = { ( ) => setShowInstructions ( true ) }
43
+ >
44
+ < ProcessingIcon /> { 'Open In Processing' }
45
+ { showInstructions && (
46
+ < div className = { classnames ( css . instructions ) } >
47
+ < h1 > Opening Processing< span className = { css . ellipsis } > </ span > </ h1 >
48
+ < p > If nothing happens, < a href = "https://www.processing.org/download/" target = "_black" > Download Processing</ a > version 4.4.1 or later and try again.</ p >
49
+ < p className = { classnames ( css . tooltipFootnote ) } > Make sure Processing is installed and was opened at least once.</ p >
50
+ </ div >
51
+ ) }
52
+ </ a >
53
+ )
54
+ }
55
+
56
+ export default OpenWithButton ;
57
+
58
+ function stringToBase64 ( str ) {
59
+ if ( typeof Buffer !== 'undefined' ) {
60
+ return Buffer . from ( str ) . toString ( 'base64' ) ;
61
+ }
62
+ return btoa ( str )
63
+ }
0 commit comments