on bab2fa8 help sign in
bridge/src/views/Point.js
360 lines 9.8 kB history raw
1import React, { useCallback, useEffect, useState } from 'react';
2import cn from 'classnames';
3import { Just } from 'folktale/maybe';
4import { Grid, Flex, Button } from 'indigo-react';
5import { azimuth } from 'azimuth-js';
6import * as ob from 'urbit-ob';
7import * as wg from 'lib/walletgen';
9import { usePointCursor } from 'store/pointCursor';
10import { useWallet } from 'store/wallet';
12import View from 'components/View';
13import Greeting from 'components/Greeting';
14import Passport from 'components/Passport';
15import Blinky, { matchBlinky } from 'components/Blinky';
16import BarGraph from 'components/BarGraph';
17import Chip from 'components/Chip';
18import InviteSigilList from 'components/InviteSigilList';
19import { ForwardButton } from 'components/Buttons';
21import * as need from 'lib/need';
22import useInvites from 'lib/useInvites';
23import { useSyncExtras } from 'lib/useSyncPoints';
24import useCurrentPermissions from 'lib/useCurrentPermissions';
25import { useLocalRouter } from 'lib/LocalRouter';
27import Inviter from 'views/Invite/Inviter';
28import { usePointCache } from 'store/pointCache';
29import Card from 'components/L2/Card';
30import { Icon, Row } from '@tlon/indigo-react';
31import L2PointHeader from 'components/L2/Headers/L2PointHeader';
32import useRoller from 'lib/useRoller';
33import { useRollerStore } from 'store/roller';
34import LayerIndicator from 'components/L2/LayerIndicator';
35import { convertToInt } from 'lib/convertToInt';
37import './Point.scss';
39function InviteForm({
40 showInviteForm,
41 setShowInviteForm,
42 acceptedInvites,
43 acceptedPoints,
44 availableInvites,
45 goCohort,
46 pendingPoints,
47 sentInvites,
48 showInvites,
49}) {
50 const _totalInvites =
51 sentInvites.getOrElse(0) + availableInvites.getOrElse(0);
52 const _pendingInvites = pendingPoints.getOrElse([]).length;
54 return (
55 <>
56 <Grid.Item cols={[1, 11]}>
57 Invite Group
58 <br />
59 </Grid.Item>
61 <Grid.Item
62 className={cn('t-right underline pointer-hover', {
63 gray4: sentInvites.getOrElse(0) === 0,
64 })}
65 onClick={goCohort}
66 cols={[11, 13]}>
67 View
68 </Grid.Item>
69 <Grid.Item full>
70 <Flex align="center">
71 <Flex.Item>
72 {acceptedInvites.getOrElse(0)} / {_totalInvites}
73 </Flex.Item>
74 {_pendingInvites > 0 && (
75 <Flex.Item as={Chip} className="bg-yellow1 yellow4">
76 {_pendingInvites} pending
77 </Flex.Item>
78 )}
79 </Flex>
80 </Grid.Item>
82 {showInvites && (
83 <>
84 <Grid.Item
85 full
86 as={BarGraph}
87 available={availableInvites}
88 sent={sentInvites}
89 accepted={acceptedInvites}
90 />
91 <Grid.Item
92 full
93 as={InviteSigilList}
94 pendingPoints={pendingPoints}
95 acceptedPoints={acceptedPoints}
96 />
97 </>
98 )}
99 {!showInvites && (
100 <>
101 <Grid.Item full className="b-gray4 b-dotted b1 self-center">
102 <div className="p4 pv8 t-center gray4">
103 Start your invite group by adding members
104 </div>
105 </Grid.Item>
106 </>
107 )}
108 {!showInviteForm && availableInvites.getOrElse(0) > 0 && (
109 <Grid.Item
110 full
111 solid
112 as={Button}
113 center
114 onClick={() => setShowInviteForm(true)}>
115 Add Members
116 </Grid.Item>
117 )}
118 {showInviteForm && <Inviter />}
119 <Grid.Item full className="mb2" />
120 </>
121 );
124export default function Point() {
125 const { pop, push, names } = useLocalRouter();
126 const { wallet, authToken } = useWallet();
127 const { pointCursor } = usePointCursor();
128 const point = need.point(pointCursor);
130 const { getResidents } = usePointCache();
131 const { api, getInvites } = useRoller();
132 const {
133 pendingTransactions,
134 nextRoll,
135 setCurrentPoint,
136 currentL2,
137 invites,
138 recentlyCompleted,
139 } = useRollerStore();
141 useEffect(() => {
142 const loadL2Info = async () => {
143 console.log('POINT', point);
144 const getTransactions = async () => {
145 const pointInfo = await api.getPoint(Number(point));
146 setCurrentPoint(pointInfo);
147 console.log('POINT', pointInfo);
149 if (pointInfo.dominion !== 'l1') {
150 getInvites();
151 }
152 };
154 getTransactions();
155 };
157 loadL2Info();
158 }, [api, point, authToken]); // eslint-disable-line
160 const { residentCount, requestCount } = getResidents(point);
162 const {
163 isParent,
164 isActiveOwner,
165 canManage,
166 canSpawn,
167 canVote,
168 } = useCurrentPermissions();
170 // L1 invites
171 const l1Invites = useInvites(point);
172 const {
173 availableInvites,
174 sentInvites,
175 acceptedInvites,
176 pendingPoints,
177 acceptedPoints,
178 } = l1Invites;
180 const showInvites = !(
181 acceptedInvites.getOrElse(0) === 0 && sentInvites.getOrElse(0) === 0
182 );
184 const hasInvites = showInvites || availableInvites.getOrElse(0) !== 0;
186 const loadedInvites = Just.hasInstance(availableInvites);
187 //
188 // availableInvites.getOrElse(0) === 0
190 const goSenate = useCallback(() => push(names.SENATE), [push, names]);
192 const goCohort = useCallback(() => push(names.INVITE_COHORT), [push, names]);
194 const goUrbitOS = useCallback(() => push(names.URBIT_OS), [push, names]);
196 const goUrbitID = useCallback(() => push(names.URBIT_ID), [push, names]);
198 const goResidents = useCallback(() => push(names.RESIDENTS), [push, names]);
200 const goPartiesSetPoolSize = useCallback(
201 () => push(names.PARTY_SET_POOL_SIZE),
202 [push, names]
203 );
205 const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
206 names.ISSUE_CHILD,
207 push,
208 ]);
210 const isPlanet = azimuth.getPointSize(point) === azimuth.PointSize.Planet;
212 const [showInviteForm, setShowInviteForm] = useState(false);
214 const inviteButton = (() => {
215 if (azimuth.getPointSize(point) === azimuth.PointSize.Star) {
216 return (
217 <>
218 <Grid.Item
219 full
220 as={ForwardButton}
221 disabled={!isActiveOwner}
222 onClick={goPartiesSetPoolSize}>
223 Manage Invite Pools
224 </Grid.Item>
225 <Grid.Divider />
226 </>
227 );
228 }
230 return null;
231 })();
233 const senateButton = (() => {
234 if (azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy) {
235 return null;
236 }
237 return (
238 <>
239 <Grid.Item
240 full
241 as={ForwardButton}
242 disabled={!canVote}
243 onClick={goSenate}>
244 Senate
245 </Grid.Item>
246 <Grid.Divider />
247 </>
248 );
249 })();
251 // sync the current cursor
252 useSyncExtras([point]);
254 const address = need.addressFromWallet(wallet);
256 const _requestCount = requestCount.getOrElse(0);
257 const numPending = pendingTransactions.length;
258 const numInvites = currentL2 ? invites.length : sentInvites.length;
260 return (
261 <View
262 pop={pop}
263 inset
264 className="point"
265 header={
266 <L2PointHeader hideTimer={!!numPending} numInvites={numInvites} />
267 }>
268 <Greeting point={point} />
269 {!!numPending && (
270 <div className="transaction">
271 <Row className="title-row">
272 <div className="title">
273 {numPending} Planet{numPending > 1 ? 's' : ''} Spawned
274 </div>
275 <div className="rollup-timer">{nextRoll}</div>
276 </Row>
277 <Row className="info-row">
278 <LayerIndicator layer={2} size="sm" />
279 <div className="date"></div>
280 </Row>
281 </div>
282 )}
283 <Passport
284 point={Just(point)}
285 address={Just(address)}
286 animationMode={'slide'}
287 />
288 <Grid gap={4}>
289 {isParent && (
290 <Grid.Item full as={Flex} justify="between">
291 <Card
292 title="Residency"
293 subtitle="Manage peers that you service"
294 onClick={goResidents}
295 />
296 </Grid.Item>
297 )}
298 {isPlanet && hasInvites && (
299 <InviteForm
300 showInviteForm={showInviteForm}
301 setShowInviteForm={setShowInviteForm}
302 acceptedInvites={acceptedInvites}
303 acceptedPoints={acceptedPoints}
304 availableInvites={availableInvites}
305 goCohort={goCohort}
306 pendingPoints={pendingPoints}
307 sentInvites={sentInvites}
308 showInvites={showInvites}
309 />
310 )}
311 {!loadedInvites && isPlanet && (
312 <Grid.Item className="mv2" full>
313 Invite Group <Blinky />
314 </Grid.Item>
315 )}
316 {/* {inviteButton} */}
317 <Grid.Item full as={Flex} justify="between">
318 <Card
319 title="ID"
320 subtitle="Identity and security settings"
321 icon={<Icon icon="User" />}
322 onClick={goUrbitID}
323 disabled={!canManage}
324 />
325 </Grid.Item>
326 <Grid.Item full as={Flex} justify="between">
327 <Card
328 title="OS"
329 subtitle="Urbit OS Settings"
330 icon={<Icon icon="Server" />}
331 onClick={goUrbitOS}
332 disabled={!canManage}
333 />
334 </Grid.Item>
335 {/* <Grid.Item
336 full
337 as={ForwardButton}
338 disabled={!canBitcoin}
339 className="mt1"
340 detail="Bitcoin management"
341 onClick={goBitcoin}>
342 Bitcoin
343 </Grid.Item> */}
344 {/* {isParent && (
345 <>
346 <Grid.Item
347 full
348 as={ForwardButton}
349 disabled={!canSpawn}
350 onClick={goIssuePoint}>
351 Issue Point
352 </Grid.Item>
353 <Grid.Divider />
354 </>
355 )} */}
356 {senateButton}
357 </Grid>
358 </View>
359 );