Skip to content

Commit a59007b

Browse files
authored
Merge pull request #5 from ipfs-shipyard/feat/drag-and-derp
feat: drag and derp
2 parents e53aa66 + 0d99194 commit a59007b

File tree

6 files changed

+109
-31
lines changed

6 files changed

+109
-31
lines changed

src/App.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Controls from './Controls'
55
import Dag from './Dag'
66
import { Buffer } from 'ipfs'
77
import { ipfsAdd } from './lib/ipfs'
8+
import DropTarget from './DropTarget'
89

910
export default function App () {
1011
const [files, setFiles] = useState([])
@@ -27,25 +28,36 @@ export default function App () {
2728
fileReader.readAsArrayBuffer(file)
2829
}
2930

31+
const onReset = () => {
32+
setFiles([])
33+
setChunker('size-512')
34+
setStrategy('balanced')
35+
setMaxChildren(11)
36+
setLayerRepeat(4)
37+
setRootCid(null)
38+
}
39+
3040
return (
3141
<div className='avenir flex flex-column h-100'>
3242
<div className='flex-none'>
3343
<Header />
3444
</div>
3545
<div className='flex-none'>
3646
<Controls
37-
onFileChange={onFileChange}
3847
chunker={chunker}
3948
onChunkerChange={setChunker}
4049
strategy={strategy}
4150
onStrategyChange={setStrategy}
4251
maxChildren={maxChildren}
4352
onMaxChildrenChange={setMaxChildren}
4453
layerRepeat={layerRepeat}
45-
onLayerRepeatChange={setLayerRepeat} />
54+
onLayerRepeatChange={setLayerRepeat}
55+
onReset={onReset} />
4656
</div>
4757
<div className='flex-auto'>
48-
<Dag rootCid={rootCid} />
58+
<DropTarget onFileDrop={onFileChange} className='h-100'>
59+
{files.length ? <Dag rootCid={rootCid} /> : null}
60+
</DropTarget>
4961
</div>
5062
</div>
5163
)

src/Controls.js

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,72 @@
11
import React from 'react'
22

33
export default function Controls ({
4-
onFileChange,
54
chunker,
65
onChunkerChange,
76
strategy,
87
onStrategyChange,
98
maxChildren,
109
onMaxChildrenChange,
1110
layerRepeat,
12-
onLayerRepeatChange
11+
onLayerRepeatChange,
12+
onReset
1313
}) {
1414
return (
15-
<div className='pa3 bg-white'>
16-
<input type='file' className='input avenir' onChange={e => onFileChange(e.target.files[0])} />
17-
<select value={chunker} onChange={e => onChunkerChange(e.target.value)}>
18-
<option value='size-32'>32 byte chunks</option>
19-
<option value='size-512'>512 byte chunks</option>
20-
<option value='size-1024'>1,024 byte chunks</option>
21-
<option value='size-16384'>16,384 byte chunks</option>
22-
<option value='size-262144'>26,2144 byte chunks</option>
23-
</select>
24-
<select value={strategy} onChange={e => onStrategyChange(e.target.value)}>
25-
<option value='balanced'>Balanced DAG</option>
26-
<option value='trickle'>Trickle DAG</option>
27-
<option value='flat'>Flat DAG</option>
28-
</select>
29-
{['balanced', 'trickle'].includes(strategy) ? (
30-
<select value={maxChildren} onChange={e => onMaxChildrenChange(parseInt(e.target.value))}>
31-
<option value='11'>11 children max</option>
32-
<option value='44'>44 children max</option>
33-
<option value='174'>174 children max</option>
15+
<div className='flex flex-row items-center pa3 bg-white'>
16+
<div className='mr3'>
17+
<select
18+
value={chunker}
19+
onChange={e => onChunkerChange(e.target.value)}
20+
className='charcoal ba b--black-20 br1 pv1 ph2 db center focus-outline'>
21+
<option value='size-32'>32 byte chunks</option>
22+
<option value='size-512'>512 byte chunks</option>
23+
<option value='size-1024'>1,024 byte chunks</option>
24+
<option value='size-16384'>16,384 byte chunks</option>
25+
<option value='size-262144'>26,2144 byte chunks</option>
26+
</select>
27+
</div>
28+
<div className='mr3'>
29+
<select
30+
value={strategy}
31+
onChange={e => onStrategyChange(e.target.value)}
32+
className='charcoal ba b--black-20 br1 pv1 ph2 db center focus-outline'>
33+
<option value='balanced'>Balanced DAG</option>
34+
<option value='trickle'>Trickle DAG</option>
35+
<option value='flat'>Flat DAG</option>
3436
</select>
37+
</div>
38+
{['balanced', 'trickle'].includes(strategy) ? (
39+
<div className='mr3'>
40+
<select
41+
value={maxChildren}
42+
onChange={e => onMaxChildrenChange(parseInt(e.target.value))}
43+
className='charcoal ba b--black-20 br1 pv1 ph2 db center focus-outline'>
44+
<option value='11'>11 children max</option>
45+
<option value='44'>44 children max</option>
46+
<option value='174'>174 children max</option>
47+
</select>
48+
</div>
3549
) : null}
3650
{strategy === 'trickle' ? (
37-
<select value={layerRepeat} onChange={e => onLayerRepeatChange(parseInt(e.target.value))}>
38-
<option value='1'>1 layer repeat</option>
39-
<option value='4'>4 layer repeats</option>
40-
<option value='16'>16 layer repeats</option>
41-
</select>
51+
<div className='mr3'>
52+
<select
53+
value={layerRepeat}
54+
onChange={e => onLayerRepeatChange(parseInt(e.target.value))}
55+
className='charcoal ba b--black-20 br1 pv1 ph2 db center focus-outline'>
56+
<option value='1'>1 layer repeat</option>
57+
<option value='4'>4 layer repeats</option>
58+
<option value='16'>16 layer repeats</option>
59+
</select>
60+
</div>
4261
) : null}
62+
<div className='flex-auto' />
63+
<button
64+
type='button'
65+
onClick={e => onReset()}
66+
className='transition-all sans-serif dib v-mid fw5 nowrap lh-copy bn br1 ph4 pv1 pointer focus-outline bg-gray hover-bg-red white'
67+
title='Clear file(s) and reset controls to defaults'>
68+
Reset
69+
</button>
4370
</div>
4471
)
4572
}

src/Dag.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,6 @@ export default class Dag extends Component {
7676
}
7777

7878
render () {
79-
return <div ref={this._graphRoot} style={{ background: 'pink' }} className='h-100' />
79+
return <div ref={this._graphRoot} className='bg-snow-muted h-100' />
8080
}
8181
}

src/DropTarget.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from 'react'
2+
3+
function kill (e) {
4+
e.stopPropagation()
5+
e.preventDefault()
6+
return false
7+
}
8+
9+
export default function DropTarget ({ onFileDrop, children, ...props }) {
10+
const onDrop = e => {
11+
e.stopPropagation()
12+
e.preventDefault()
13+
onFileDrop(e.dataTransfer.files[0])
14+
}
15+
16+
return (
17+
<div onDrop={onDrop} onDragEnter={kill} onDragOver={kill} {...props}>
18+
{children || (
19+
<div className='h-100 ph3 pb3'>
20+
<label className='flex items-center justify-center h-100 br4 bw2 b--gray-muted b--dashed bg-snow-muted relative'>
21+
<div>
22+
<input
23+
type='file'
24+
className='absolute top-0 o-0'
25+
onChange={e => onFileDrop(e.target.files[0])} />
26+
<span
27+
className='f3 transition-all sans-serif dib v-mid lh-copy bn br1 ph4 pv2 pointer focus-outline bg-aqua o-90 glow white mr3'>
28+
Pick a file
29+
</span>
30+
<span className='f2 gray v-mid'>or drop it here</span>
31+
</div>
32+
</label>
33+
</div>
34+
)}
35+
</div>
36+
)
37+
}

src/Header.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import React from 'react'
2+
import Logo from './ipfs-logo.svg'
23

34
export default function Header () {
45
return (
56
<header className='flex items-center pa3 bg-navy'>
67
<a href='https://ipfs.io' title='home' className='w-50'>
7-
<img src='https://ipfs.io/images/ipfs-logo.svg' style={{ height: 50 }} />
8+
<img src={Logo} style={{ height: 50 }} />
89
</a>
910
<h1 className='w-50 ma0 tr f3 fw2 montserrat aqua'>DAG builder</h1>
1011
</header>

src/ipfs-logo.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)