on 8d566ea help sign in
249 lines 6.4 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 CopyButton 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';
24export default function UrbitOSHome() {
25 const { pointCursor } = usePointCursor();
26 const { getDetails } = usePointCache();
28 const { push, names } = useLocalRouter();
30 const point = need.point(pointCursor);
31 const details = need.details(getDetails(point));
33 const sponsor = ob.patp(details.sponsor);
35 const [showKeys, setShowKeys] = useState(false);
37 const showSponsor = azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy;
38 const toggleShowKeys = useCallback(() => setShowKeys(!showKeys), [
39 setShowKeys,
40 showKeys,
41 ]);
43 const goNetworkingKeys = useCallback(() => push(names.NETWORKING_KEYS), [
44 names,
45 push,
46 ]);
48 const goChangeSponsor = useCallback(() => push(names.CHANGE_SPONSOR), [
49 push,
50 names,
51 ]);
52 return (
53 <>
54 <Hosting />
56 <Grid>
57 <Grid.Item full className="mv7 f5">
58 Network
59 </Grid.Item>
60 {showSponsor && (
61 <>
62 <Grid.Divider />
63 <Grid.Item
64 full
65 as={ForwardButton}
66 detail="A sponsor finds new peers in your network"
67 accessory={<u>Change</u>}
68 onClick={goChangeSponsor}>
69 <span className="mono">{sponsor}</span>
70 <span className="f7 bg-black white p1 ml2 r4">SPONSOR</span>
71 </Grid.Item>
72 </>
73 )}
75 <Grid.Divider />
76 <Grid.Item full as={ForwardButton} onClick={goNetworkingKeys}>
77 Reset Networking Keys
78 </Grid.Item>
79 <Grid.Divider />
80 <Grid.Item
81 full
82 as={ForwardButton}
83 accessory={showKeys ? '▲' : '▼'}
84 onClick={toggleShowKeys}>
85 View Networking Keys
86 </Grid.Item>
87 {showKeys && <Grid.Item full as={NetworkingKeys} point={point} />}
88 </Grid>
89 </>
90 );
93// eslint-disable-next-line
94function Hosting() {
95 const bind = useKeyfileGenerator();
96 const { keyfile, code, notice } = bind;
97 const ship = useHosting();
99 const {
100 syncStatus,
101 url,
102 unknown,
103 running,
104 sysEvents,
105 runEvents,
106 newEvents,
107 bootProgress,
108 bootMessage,
109 } = ship;
111 const [synced, setSynced] = useState(false);
112 useEffect(() => {
113 if (unknown && !synced) {
114 syncStatus();
115 setSynced(true);
116 }
117 }, [syncStatus, unknown, setSynced, synced]);
119 const createShip = useCallback(() => ship.create(keyfile), [keyfile, ship]);
121 const name = useCurrentPointName();
122 const options = [{ text: 'Tlon', value: 'tlon' }];
124 const props = { name, options, ship };
126 const renderMain = useCallback(() => {
127 if (ship.running) {
128 return (
129 <>
130 <Grid.Item cols={[1, 9]} as={OutButton} solid success href={url}>
131 Open OS
132 </Grid.Item>
133 <Grid.Item cols={[9, 13]} as={Button} className="b-black b1" center>
134 Disconnect
135 </Grid.Item>
136 </>
137 );
138 }
139 if (ship.missing) {
140 return (
141 <Grid.Item
142 full
143 as={ForwardButton}
144 solid
145 disabled={!keyfile}
146 onClick={createShip}>
147 Connect
148 </Grid.Item>
149 );
150 }
151 if (ship.pending) {
152 return (
153 <Grid.Item
154 full
155 as={ProgressButton}
156 success
157 disabled
158 progress={bootProgress}>
159 {bootMessage || 'Connecting'}
160 </Grid.Item>
161 );
162 }
163 }, [
164 ship.missing,
165 ship.running,
166 ship.pending,
167 bootProgress,
168 bootMessage,
169 keyfile,
170 createShip,
171 url,
172 ]);
174 const renderDetails = useCallback(() => {
175 if (ship.running) {
176 return (
177 <>
178 <Grid.Item cols={[1, 9]} className="gray4">
179 <span className="mono">{name}</span> is connected to Tlon
180 </Grid.Item>
181 </>
182 );
183 }
184 if (ship.missing) {
185 return (
186 <>
187 <Grid.Item full className="gray4">
188 <span className="gray3">Status:</span> Disconnected
189 <br />
190 <span className="f6">Last connected: 4m ago</span>
191 </Grid.Item>
192 </>
193 );
194 }
195 }, [name, ship]);
197 return (
198 <>
199 <Grid gap={4}>
200 <Grid.Item full className="f5" as={Flex}>
201 <Flex.Item>Urbit OS </Flex.Item>
202 <Flex.Item
203 className={cn(
204 { green3: ship.running, grey4: !ship.running },
205 'ml3'
206 )}>
207 {ship.running ? 'Connected' : 'Disconnected'}
208 </Flex.Item>
209 </Grid.Item>
210 <BridgeForm initialValues={{ provider: 'tlon' }}>
211 {() => (
212 <>
213 {renderDetails()}
214 {renderMain()}
215 <Grid.Item
216 full
217 as={SelectInput}
218 name="provider"
219 label="Host Provider"
220 options={options}
221 disabled
222 />
223 </>
224 )}
225 </BridgeForm>
226 </Grid>
227 <Grid>
228 <Grid.Item
229 full
230 as={DownloadKeyfileButton}
231 {...bind}
232 className="mt2"
233 detail="A keyfile authenticates your Urbit ID to Urbit OS"
234 />
235 <Grid.Divider />
236 <Grid.Item
237 full
238 className="mt2"
239 as={ForwardButton}
240 accessory={code && <CopyButton text={code} />}
241 detail={code || notice}
242 disabled={!code}
243 detailClassName="mono">
244 Login Code
245 </Grid.Item>
246 </Grid>
247 </>
248 );