on 6ecd461 help sign in
bridge/src/views/CreateGalaxy.js
179 lines 4.4 kB history raw
1import React, { useCallback, useEffect, useState } from 'react';
2import { Nothing, Just } from 'folktale/maybe';
3import cn from 'classnames';
4import { Grid, Text, Input } from 'indigo-react';
5import * as azimuth from 'azimuth-js';
7import { useNetwork } from 'store/network';
8import { useHistory } from 'store/history';
9import { usePointCache } from 'store/pointCache';
11import * as need from 'lib/need';
12import { useAddressInput, useGalaxyInput } from 'lib/useInputs';
13import useEthereumTransaction from 'lib/useEthereumTransaction';
14import { GAS_LIMITS } from 'lib/constants';
15import patp2dec from 'lib/patp2dec';
17import ViewHeader from 'components/ViewHeader';
18import MiniBackButton from 'components/MiniBackButton';
19import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
20import View from 'components/View';
21import { isZeroAddress } from 'lib/wallet';
23function useCreateGalaxy() {
24 const { contracts } = useNetwork();
25 const { syncKnownPoint } = usePointCache();
27 const _contracts = need.contracts(contracts);
29 const [galaxy, setGalaxy] = useState();
31 const {
32 construct: _construct,
33 unconstruct,
34 confirmed,
35 inputsLocked,
36 bind,
37 } = useEthereumTransaction(GAS_LIMITS.DEFAULT);
39 const construct = useCallback(
40 (galaxy, owner) => {
41 setGalaxy(galaxy);
42 _construct(azimuth.ecliptic.createGalaxy(_contracts, galaxy, owner));
43 },
44 [_construct, _contracts]
45 );
47 useEffect(() => {
48 if (confirmed) {
49 syncKnownPoint(galaxy);
50 }
51 }, [confirmed, galaxy, syncKnownPoint]);
53 return {
54 construct,
55 unconstruct,
56 confirmed,
57 inputsLocked,
58 bind,
59 };
62export default function CreateGalaxy() {
63 const { pop } = useHistory();
64 const { contracts } = useNetwork();
65 const _contracts = need.contracts(contracts);
67 const [error, setError] = useState();
68 const [isAvailable, setIsAvailable] = useState(Nothing());
70 const {
71 construct,
72 unconstruct,
73 confirmed,
74 inputsLocked,
75 bind,
76 } = useCreateGalaxy();
78 const [
79 galaxyNameInput,
80 { pass: validGalaxyName, syncPass: syncValidGalaxyName, value: galaxyName },
81 // ^ we use value: here so our effect runs onChange
82 ] = useGalaxyInput({
83 disabled: inputsLocked,
84 autoFocus: true,
85 error:
86 error ||
87 isAvailable.matchWith({
88 Nothing: () => 'Loading availabiliy...', // TODO: make async loading?
89 Just: p => (p.value ? undefined : 'This galaxy is already owned.'),
90 }),
91 });
93 const [ownerInput, { pass: validOwner, data: owner }] = useAddressInput({
94 name: 'owner',
95 label: `Ethereum Address`,
96 disabled: inputsLocked,
97 });
99 useEffect(() => {
100 if (validGalaxyName && validOwner) {
101 construct(patp2dec(galaxyName), owner);
102 } else {
103 unconstruct();
104 }
105 }, [owner, construct, unconstruct, validGalaxyName, validOwner, galaxyName]);
107 useEffect(() => {
108 if (!syncValidGalaxyName || inputsLocked) {
109 return;
110 }
112 setError();
113 setIsAvailable(Nothing());
115 let cancelled = false;
117 (async () => {
118 try {
119 const currentOwner = await azimuth.azimuth.getOwner(
120 _contracts,
121 patp2dec(galaxyName)
122 );
124 const isAvailable = isZeroAddress(currentOwner);
126 if (cancelled) {
127 return;
128 }
130 setIsAvailable(Just(isAvailable));
131 } catch (error) {
132 console.error(error);
133 setError(error.message);
134 setIsAvailable(Just(false));
135 }
136 })();
138 return () => (cancelled = true);
139 }, [
140 _contracts,
141 galaxyName,
142 inputsLocked,
143 setIsAvailable,
144 syncValidGalaxyName,
145 ]);
147 return (
148 <View inset>
149 <Grid>
150 <Grid.Item full as={MiniBackButton} onClick={() => pop()} />
152 <Grid.Item full as={ViewHeader}>
153 Create a Galaxy
154 </Grid.Item>
156 {confirmed && (
157 <Grid.Item
158 full
159 as={Text}
160 className={cn('f5', {
161 green3: confirmed,
162 })}>
163 {galaxyName} has been created and is owned by {owner}.
164 </Grid.Item>
165 )}
167 <Grid.Item full as={Input} {...galaxyNameInput} className="mt4" />
168 <Grid.Item full as={Input} {...ownerInput} className="mb4" />
170 <Grid.Item
171 full
172 as={InlineEthereumTransaction}
173 {...bind}
174 onReturn={() => pop()}
175 />
176 </Grid>
177 </View>
178 );