on eb070bb help sign in
245 lines 6.5 kB history raw
1import React, { useCallback, useState, useEffect } from 'react';
2import cn from 'classnames';
3import { Grid, Button, SelectInput, Flex } from 'indigo-react';
4import * as ob from 'urbit-ob';
5import { azimuth } from 'azimuth-js';
7import { usePointCursor } from 'store/pointCursor';
8import { usePointCache } from 'store/pointCache';
10import useCurrentPointName from 'lib/useCurrentPointName';
11import useKeyfileGenerator from 'lib/useKeyfileGenerator';
12import * as need from 'lib/need';
14import { OutButton, ForwardButton } from 'components/Buttons';
15import { CopyButtonWide } from 'components/CopyButton';
16import NetworkingKeys from 'components/NetworkingKeys';
17import ProgressButton from 'components/ProgressButton';
19import BridgeForm from 'form/BridgeForm';
20import { useLocalRouter } from 'lib/LocalRouter';
21import { useHosting } from 'store/hosting';
22import DownloadKeyfileButton from 'components/DownloadKeyfileButton';
23import useLifecycle from 'lib/useLifecycle';
25export default function UrbitOSHome({ manualNetworkSeed }) {
26 const { pointCursor } = usePointCursor();
27 const { getDetails } = usePointCache();
29 const { push, names } = useLocalRouter();
31 const point = need.point(pointCursor);
32 const details = need.details(getDetails(point));
34 const sponsor = ob.patp(details.sponsor);
36 const [showKeys, setShowKeys] = useState(false);
38 const showSponsor = azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy;
39 const toggleShowKeys = useCallback(() => setShowKeys(s => !s), [setShowKeys]);
41 const goNetworkingKeys = useCallback(() => push(names.NETWORKING_KEYS), [
42 names,
43 push,
44 ]);
46 const goChangeSponsor = useCallback(() => push(names.CHANGE_SPONSOR), [
47 push,
48 names,
49 ]);
50 return (
51 <>
52 <Hosting manualNetworkSeed={manualNetworkSeed} />
54 <Grid>
55 <Grid.Item full className="mv7 f5">
56 Network
57 </Grid.Item>
58 {showSponsor && (
59 <>
60 <Grid.Divider />
61 <Grid.Item
62 full
63 as={ForwardButton}
64 detail="A sponsor finds new peers in your network"
65 accessory={<u>Change</u>}
66 onClick={goChangeSponsor}>
67 <span className="mono">{sponsor}</span>
68 <span className="f7 bg-black white p1 ml2 r4">SPONSOR</span>
69 </Grid.Item>
70 </>
71 )}
73 <Grid.Divider />
74 <Grid.Item full as={ForwardButton} onClick={goNetworkingKeys}>
75 Reset Networking Keys
76 </Grid.Item>
77 <Grid.Divider />
78 <Grid.Item
79 full
80 as={ForwardButton}
81 accessory={showKeys ? '▼' : '▲'}
82 onClick={toggleShowKeys}>
83 View Networking Keys
84 </Grid.Item>
85 {showKeys && <Grid.Item full as={NetworkingKeys} point={point} />}
86 </Grid>
87 </>
88 );
91// eslint-disable-next-line
92function Hosting({ manualNetworkSeed }) {
93 const bind = useKeyfileGenerator(manualNetworkSeed);
94 const { keyfile, code } = bind;
95 const ship = useHosting();
97 const {
98 syncStatus,
99 url,
100 unknown,
101 bootProgress,
102 bootMessage,
103 disabled,
104 } = ship;
106 useLifecycle(() => {
107 syncStatus();
108 });
110 const createShip = useCallback(() => ship.create(keyfile), [keyfile, ship]);
112 const name = useCurrentPointName();
113 const options = [{ text: 'Tlon', value: 'tlon' }];
115 const renderMain = useCallback(() => {
116 if (ship.running) {
117 return (
118 <>
119 <Grid.Item cols={[1, 9]} as={OutButton} solid success href={url}>
120 Open OS
121 </Grid.Item>
122 {/* Unsupported for now */}
123 {/* <Grid.Item cols={[9, 13]} as={Button} className="b-black b1" center> */}
124 {/* Disconnect */}
125 {/* </Grid.Item> */}
126 </>
127 );
128 }
129 if (ship.missing) {
130 return (
131 <Grid.Item
132 full
133 as={ForwardButton}
134 solid
135 disabled={!keyfile}
136 onClick={createShip}>
137 Connect
138 </Grid.Item>
139 );
140 }
141 if (ship.pending) {
142 return (
143 <Grid.Item
144 full
145 as={ProgressButton}
146 success
147 disabled
148 progress={bootProgress}>
149 {bootMessage || 'Connecting'}
150 </Grid.Item>
151 );
152 }
153 }, [
154 ship.missing,
155 ship.running,
156 ship.pending,
157 bootProgress,
158 bootMessage,
159 keyfile,
160 createShip,
161 url,
162 ]);
164 const renderDetails = useCallback(() => {
165 if (ship.running) {
166 return (
167 <>
168 <Grid.Item cols={[1, 9]} className="gray4">
169 <span className="mono">{name}</span> is connected to Tlon
170 </Grid.Item>
171 </>
172 );
173 }
174 if (!keyfile && ship.missing) {
175 return (
176 <Grid.Item full className="gray4">
177 Please reset your networking keys in order to use hosting
178 </Grid.Item>
179 );
180 }
181 }, [name, ship, keyfile]);
183 return (
184 <>
185 {disabled && (
186 <Grid gap={4}>
187 <Grid.Item full className="f5">
188 Urbit OS
189 </Grid.Item>
190 <Grid.Divider />
191 </Grid>
192 )}
193 {!disabled && (
194 <Grid gap={4}>
195 <Grid.Item full className="f5" as={Flex}>
196 <Flex.Item>Urbit OS </Flex.Item>
197 <Flex.Item
198 className={cn(
199 { green3: ship.running, gray4: !ship.running },
200 'ml3'
201 )}>
202 {ship.running ? 'Connected' : 'Disconnected'}
203 </Flex.Item>
204 </Grid.Item>
205 <BridgeForm initialValues={{ provider: 'tlon' }}>
206 {() => (
207 <>
208 {renderDetails()}
209 {renderMain()}
210 <Grid.Item
211 full
212 as={SelectInput}
213 name="provider"
214 label="Host Provider"
215 options={options}
216 disabled
217 />
218 </>
219 )}
220 </BridgeForm>
221 </Grid>
222 )}
223 <Grid>
224 <Grid.Item
225 full
226 as={DownloadKeyfileButton}
227 {...bind}
228 className="mt2"
229 detail="A keyfile authenticates your Urbit ID to Urbit OS"
230 />
231 <Grid.Divider />
232 {code && (
233 <Grid.Item
234 full
235 className="mt2"
236 as={CopyButtonWide}
237 detail={code}
238 detailClassName="mono">
239 Login Code
240 </Grid.Item>
241 )}
242 </Grid>
243 </>
244 );