@@ -20,6 +20,15 @@ import {
2020 eqAddr
2121} from '../lib/wallet'
2222
23+const setFind = (set, pred) => {
24+ for (const e of set) {
25+ if (pred(e)) {
26+ return e
27+ }
28+ }
29+ return undefined
30+}
31+
2332class IssueChild extends React.Component {
2433 constructor(props) {
2534 super(props)
@@ -46,11 +55,12 @@ class IssueChild extends React.Component {
4655 desiredPoint: '',
4756 isAvailable: Nothing(), // use Nothing to allow attempt when offline
4857 suggestions: suggestions,
58+ validChildren: new Set(),
59+ autoComplete: ''
4960 }
5061
5162 this.handlePointInput = this.handlePointInput.bind(this)
5263 this.handleAddressInput = this.handleAddressInput.bind(this)
53− this.handleConfirmAvailability = this.handleConfirmAvailability.bind(this)
5464 this.createUnsignedTxn = this.createUnsignedTxn.bind(this)
5565 this.statelessRef = React.createRef();
5666 }
@@ -60,28 +70,11 @@ class IssueChild extends React.Component {
6070 this.statelessRef.current.clearTxn()
6171 }
6272
63− handlePointInput(desiredPoint) {
64− if (desiredPoint.length < 15) {
65− this.setState({
66− desiredPoint,
67− isAvailable: Nothing()
68− })
69− this.statelessRef.current.clearTxn()
70− }
71− }
73+ componentWillMount() {
7274
73− handleConfirmAvailability() {
74− this.confirmPointAvailability().then(r => {
75− this.setState({
76− isAvailable: r,
77− })
78− })
79−
80− }
81−
82− async confirmPointAvailability() {
8375 const { contracts } = this.props
84− const { desiredPoint } = this.state
76+ const { issuingPoint } = this.state
77+
8578
8679 const validContracts = contracts.matchWith({
8780 Just: cs => cs.value,
@@ -90,31 +83,28 @@ class IssueChild extends React.Component {
9083 }
9184 })
9285
93− if (canDecodePatp(desiredPoint) === false) {
94− return Just(false)
95− }
86+ azimuth.getUnspawnedChildren(validContracts, issuingPoint).then(ps => this.setState({ validChildren: new Set(ps.map(ob.patp)) }))
87+ }
9688
97− const point = ob.patp2dec(desiredPoint)
98− const pointSize = azimuth.getPointSize(point)
89+ handlePointInput(desiredPoint) {
90+ if (desiredPoint.length < 15) {
9991
100− const prefix = azimuth.getPrefix(point)
101− const prefixSize = azimuth.getPointSize(prefix)
92+ const suggestedPoint = setFind(this.state.validChildren, (e => e.startsWith(desiredPoint))) || ''
93+ const rendered = ' '.repeat(desiredPoint.length) + suggestedPoint.substring(desiredPoint.length)
10294
103− // NB (jtobin): this prevents galaxies from attempting to spawn planets
104− //
105− if (pointSize !== prefixSize + 1) {
106− return Just(false)
107− }
95+ const available = Just(this.state.validChildren.has(desiredPoint))
10896
109− const owner = await azimuth.getOwner(validContracts, point)
97+ this.setState({
98+ desiredPoint,
99+ isAvailable: available,
100+ autoComplete: rendered
101+ })
102+ this.statelessRef.current.clearTxn()
110103
111− if (eqAddr(owner, ETH_ZERO_ADDR)) {
112− return Just(true)
113104 }
114−
115− return Just(false)
116105 }
117106
107+
118108 createUnsignedTxn() {
119109 const { state, props } = this
120110
@@ -140,19 +130,6 @@ class IssueChild extends React.Component {
140130 return Just(txn)
141131 }
142132
143− buttonTriState() {
144− const a = this.state.isAvailable
145− if (Nothing.hasInstance(a)) return 'blue'
146− if (a.value === false) return 'yellow'
147− if (a.value === true) return 'green'
148− }
149−
150− buttonTriStateText() {
151− const a = this.state.isAvailable
152− if (Nothing.hasInstance(a)) return 'Confirm Availablility'
153− if (a.value === false) return 'Point is Not Available'
154− if (a.value === true) return 'Available'
155− }
156133
157134 validatePoint = patp => {
158135 const point = this.point
@@ -176,16 +153,13 @@ class IssueChild extends React.Component {
176153 const { props, state } = this
177154
178155 const validAddress = isValidAddress(state.receivingAddress)
179− const validPoint = canDecodePatp(state.desiredPoint)
180156
181157 const canGenerate = props.web3.matchWith({
182158 Nothing: () => {
183− return validAddress === true &&
184− validPoint === true
159+ return validAddress === true
185160 },
186161 Just: () => {
187162 return validAddress === true &&
188− validPoint === true &&
189163 state.isAvailable.value === true
190164 }
191165 })
@@ -250,6 +224,11 @@ class IssueChild extends React.Component {
250224 value={ state.desiredPoint }
251225 onChange={ this.handlePointInput }>
252226 <InnerLabel>{ 'Point to Issue' }</InnerLabel>
227+ <div
228+ style={{marginTop: '8.8rem', marginLeft: '4.6rem', fontSize: '5rem', color: '#757575', whiteSpace: 'pre-wrap'}}
229+ className='abs tl-0 mono'>
230+ { state.autoComplete }
231+ </div>
253232 <ValidatedSigil
254233 className={'tr-0 mt-05 mr-0 abs'}
255234 patp={state.desiredPoint}
@@ -279,21 +258,6 @@ class IssueChild extends React.Component {
279258 {'View on Etherscan ↗'}
280259 </Anchor>
281260
282− {
283− props.web3.matchWith({
284− Nothing: _ => <div />,
285− Just: _ =>
286− <Button
287− prop-size='lg wide'
288− prop-color={this.buttonTriState()}
289− className={'mt-8'}
290− disabled={!validPoint}
291− onClick={this.handleConfirmAvailability}>
292− {this.buttonTriStateText()}
293− </Button>
294− })
295− }
296−
297261 <StatelessTransaction
298262 // Upper scope
299263 web3={props.web3}