on ee5bed0 help sign in
bridge/src/views/Point.js
306 lines 8.5 kB history raw
1import React, { useCallback, useState, useEffect } from 'react';
2import cn from 'classnames';
3import { Just } from 'folktale/maybe';
4import { Grid, Flex, Button } from 'indigo-react';
5import { azimuth } from 'azimuth-js';
7import { usePointCursor } from 'store/pointCursor';
8import { useWallet } from 'store/wallet';
10import View from 'components/View';
11import Greeting from 'components/Greeting';
12import Passport from 'components/Passport';
13import { ForwardButton } from 'components/Buttons';
14import Blinky, { matchBlinky } from 'components/Blinky';
15import BarGraph from 'components/BarGraph';
16import Chip from 'components/Chip';
17import InviteSigilList from 'components/InviteSigilList';
18import { ForwardButton, HostingButton } from 'components/Buttons';
19import CopyButton from 'components/CopyButton';
20import { matchBlinky } from 'components/Blinky';
21import DownloadSigilButton from 'components/DownloadSigilButton';
23import * as need from 'lib/need';
24import useInvites from 'lib/useInvites';
25import { useSyncOwnedPoints } from 'lib/useSyncPoints';
26import useCurrentPermissions from 'lib/useCurrentPermissions';
27import { useLocalRouter } from 'lib/LocalRouter';
28import { useResidents } from 'lib/useResidents';
30import Inviter from 'views/Invite/Inviter';
32export default function Point() {
33 const { pop, push, names } = useLocalRouter();
34 const { pointCursor } = usePointCursor();
36 const { wallet } = useWallet();
37 const point = need.point(pointCursor);
39 const { residentCount } = useResidents(point);
41 const {
42 isParent,
43 isActiveOwner,
44 canManage,
45 canSpawn,
46 canVote,
47 } = useCurrentPermissions();
49 // fetch the invites for the current cursor
50 const invites = useInvites(point);
51 const {
52 availableInvites,
53 sentInvites,
54 acceptedInvites,
55 pendingPoints,
56 acceptedPoints,
57 } = invites;
59 const showInvites = !(
60 acceptedInvites.getOrElse(0) === 0 && sentInvites.getOrElse(0) === 0
61 );
63 const hasInvites = showInvites || availableInvites.getOrElse(0) !== 0;
65 const _totalInvites =
66 sentInvites.getOrElse(0) + availableInvites.getOrElse(0);
67 const _pendingInvites = pendingPoints.getOrElse([]).length;
69 const loadedInvites = Just.hasInstance(availableInvites);
70 //
71 // availableInvites.getOrElse(0) === 0
73 const goAdmin = useCallback(() => push(names.ADMIN), [push, names]);
75 const goSenate = useCallback(() => push(names.SENATE), [push, names]);
77 const goSigil = useCallback(() => push(names.SIGIL_GENERATOR), [push, names]);
79 const goCohort = useCallback(() => push(names.INVITE_COHORT), [push, names]);
81 const goUrbitOS = useCallback(() => push(names.URBIT_OS), [push, names]);
83 const goUrbitID = useCallback(() => push(names.URBIT_ID), [push, names]);
85 const goResidents = useCallback(() => push(names.RESIDENTS), [push, names]);
87 const goPartiesSetPoolSize = useCallback(
88 () => push(names.PARTY_SET_POOL_SIZE),
89 [push, names]
90 );
92 const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
93 names.ISSUE_CHILD,
94 push,
95 ]);
97 const isPlanet = azimuth.getPointSize(point) === azimuth.PointSize.Planet;
99 const [showInviteForm, setShowInviteForm] = useState(false);
101 const goBoot = useCallback(() => push(names.BOOT), [push, names]);
102 const goHosting = useCallback(() => push(names.HOSTING), [push, names]);
104 const inviteButton = (() => {
105 if (azimuth.getPointSize(point) === azimuth.PointSize.Star) {
106 return (
107 <>
108 <Grid.Item
109 full
110 as={ForwardButton}
111 disabled={!isActiveOwner}
112 onClick={goPartiesSetPoolSize}>
113 Manage Invite Pools
114 </Grid.Item>
115 <Grid.Divider />
116 </>
117 );
118 }
120 return null;
121 })();
123 const senateButton = (() => {
124 if (azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy) {
125 return null;
126 }
127 return (
128 <>
129 <Grid.Item
130 full
131 as={ForwardButton}
132 disabled={!canVote}
133 onClick={goSenate}>
134 Senate
135 </Grid.Item>
136 <Grid.Divider />
137 </>
138 );
139 })();
141 // sync the current cursor
142 useSyncOwnedPoints([point]);
144 const address = need.addressFromWallet(wallet);
146 const InviteForm = useCallback(() => {
147 return (
148 <>
149 <Grid.Item cols={[1, 11]}>
150 Invite Group
151 <br />
152 </Grid.Item>
154 <Grid.Item
155 className={cn('t-right underline pointer-hover', {
156 gray4: sentInvites.getOrElse(0) === 0,
157 })}
158 onClick={goCohort}
159 cols={[11, 13]}>
160 View
161 </Grid.Item>
162 <Grid.Item full>
163 <Flex align="center">
164 <Flex.Item>
165 {acceptedInvites.getOrElse(0)} / {_totalInvites}
166 </Flex.Item>
167 {_pendingInvites > 0 && (
168 <Flex.Item as={Chip} className="bg-yellow1 yellow4">
169 {_pendingInvites} pending
170 </Flex.Item>
171 )}
172 </Flex>
173 </Grid.Item>
175 {showInvites && (
176 <>
177 <Grid.Item
178 full
179 as={BarGraph}
180 available={availableInvites}
181 sent={sentInvites}
182 accepted={acceptedInvites}
183 />
184 <Grid.Item
185 full
186 as={InviteSigilList}
187 pendingPoints={pendingPoints}
188 acceptedPoints={acceptedPoints}
189 />
190 </>
191 )}
192 {!showInvites && (
193 <>
194 <Grid.Item full className="b-gray4 b-dotted b1 self-center">
195 <div className="p4 pv8 t-center gray4">
196 Start your invite group by adding members
197 </div>
198 </Grid.Item>
199 </>
200 )}
201 {!showInviteForm && availableInvites.getOrElse(0) > 0 && (
202 <Grid.Item
203 full
204 solid
205 as={Button}
206 center
207 onClick={() => setShowInviteForm(true)}>
208 Add Members
209 </Grid.Item>
210 )}
211 {showInviteForm && <Inviter />}
212 <Grid.Item full className="mb2" />
213 </>
214 );
215 });
217 console.log(residentCount);
219 return (
220 <View pop={pop} inset>
221 <Greeting point={point} />
222 <Passport
223 point={Just(point)}
224 address={Just(address)}
225 animationMode={'slide'}
226 />
227 <Grid gap={3}>
228 {isParent && (
229 <Grid.Item full as={Flex} justify="between" onClick={goResidents}>
230 <Flex.Item>
231 Residents{' '}
232 <span className="gray3">{matchBlinky(residentCount)}</span>
233 </Flex.Item>
234 <Flex.Item>N/A</Flex.Item>
235 </Grid.Item>
236 )}
237 {isPlanet && hasInvites && <InviteForm />}
238 {!loadedInvites && isPlanet && (
239 <Grid.Item className="mv2" full>
240 Invite Group <Blinky />
241 </Grid.Item>
242 )}
243 </Grid>
244 <Grid className="pt2">
245 <Grid.Divider />
246 {inviteButton}
247 <Grid.Item
248 full
249 as={ForwardButton}
250 disabled={!canManage}
251 onClick={goUrbitID}
252 className="mt2"
253 detail="Identity and security settings">
254 ID
255 </Grid.Item>
256 <Grid.Divider />
257 <Grid.Item
258 full
259 as={ForwardButton}
260 disabled={!canManage}
261 className="mt2"
262 detail="Urbit OS Settings"
263 onClick={goUrbitOS}>
264 OS
265 </Grid.Item>
266 <Grid.Divider />
267 {isParent && (
268 <>
269 <Grid.Item
270 full
271 as={ForwardButton}
272 disabled={!canSpawn}
273 onClick={goIssuePoint}>
274 Issue Point
275 </Grid.Item>
276 <Grid.Divider />
277 </>
278 )}
279 {senateButton}
280 <Grid.Item
281 full
282 as={ForwardButton}
283 detail="Boot your computer"
284 onClick={goBoot}>
285 Boot Urbit OS
286 </Grid.Item>
288 <Grid.Item full as={HostingButton} onClick={goHosting} />
289 <Grid.Divider />
291 <Grid.Item
292 full
293 as={ForwardButton}
294 accessory={code && <CopyButton text={code} />}
295 detail={code || notice}
296 disabled={!code}
297 detailClassName="mono">
298 Login Code
299 </Grid.Item>
300 <Grid.Divider />
301 <Grid.Item full as={DownloadSigilButton} point={point} />
302 <Grid.Divider />
303 </Grid>
304 </View>
305 );