on 8d566ea help sign in
bridge/src/views/Point.js
290 lines 8.0 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 Blinky, { matchBlinky } from 'components/Blinky';
14import BarGraph from 'components/BarGraph';
15import Chip from 'components/Chip';
16import InviteSigilList from 'components/InviteSigilList';
17import { ForwardButton, HostingButton } from 'components/Buttons';
18import CopyButton from 'components/CopyButton';
19import DownloadSigilButton from 'components/DownloadSigilButton';
21import * as need from 'lib/need';
22import useInvites from 'lib/useInvites';
23import { useSyncOwnedPoints } from 'lib/useSyncPoints';
24import useCurrentPermissions from 'lib/useCurrentPermissions';
25import { useLocalRouter } from 'lib/LocalRouter';
27import Inviter from 'views/Invite/Inviter';
28import { usePointCache } from 'store/pointCache';
30export default function Point() {
31 const { pop, push, names } = useLocalRouter();
32 const { pointCursor } = usePointCursor();
34 const { wallet } = useWallet();
35 const point = need.point(pointCursor);
37 const { getResidents } = usePointCache();
39 const { residentCount, requestCount } = getResidents(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 goSenate = useCallback(() => push(names.SENATE), [push, names]);
75 const goSigil = useCallback(() => push(names.SIGIL_GENERATOR), [push, names]);
77 const goCohort = useCallback(() => push(names.INVITE_COHORT), [push, names]);
79 const goUrbitOS = useCallback(() => push(names.URBIT_OS), [push, names]);
81 const goUrbitID = useCallback(() => push(names.URBIT_ID), [push, names]);
83 const goResidents = useCallback(() => push(names.RESIDENTS), [push, names]);
85 const goPartiesSetPoolSize = useCallback(
86 () => push(names.PARTY_SET_POOL_SIZE),
87 [push, names]
88 );
90 const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
91 names.ISSUE_CHILD,
92 push,
93 ]);
95 const isPlanet = azimuth.getPointSize(point) === azimuth.PointSize.Planet;
97 const [showInviteForm, setShowInviteForm] = useState(false);
99 const goBoot = useCallback(() => push(names.BOOT), [push, names]);
100 const goHosting = useCallback(() => push(names.HOSTING), [push, names]);
102 const inviteButton = (() => {
103 if (azimuth.getPointSize(point) === azimuth.PointSize.Star) {
104 return (
105 <>
106 <Grid.Item
107 full
108 as={ForwardButton}
109 disabled={!isActiveOwner}
110 onClick={goPartiesSetPoolSize}>
111 Manage Invite Pools
112 </Grid.Item>
113 <Grid.Divider />
114 </>
115 );
116 }
118 return null;
119 })();
121 const senateButton = (() => {
122 if (azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy) {
123 return null;
124 }
125 return (
126 <>
127 <Grid.Item
128 full
129 as={ForwardButton}
130 disabled={!canVote}
131 onClick={goSenate}>
132 Senate
133 </Grid.Item>
134 <Grid.Divider />
135 </>
136 );
137 })();
139 // sync the current cursor
140 useSyncOwnedPoints([point]);
142 const address = need.addressFromWallet(wallet);
144 const InviteForm = useCallback(() => {
145 return (
146 <>
147 <Grid.Item cols={[1, 11]}>
148 Invite Group
149 <br />
150 </Grid.Item>
152 <Grid.Item
153 className={cn('t-right underline pointer-hover', {
154 gray4: sentInvites.getOrElse(0) === 0,
155 })}
156 onClick={goCohort}
157 cols={[11, 13]}>
158 View
159 </Grid.Item>
160 <Grid.Item full>
161 <Flex align="center">
162 <Flex.Item>
163 {acceptedInvites.getOrElse(0)} / {_totalInvites}
164 </Flex.Item>
165 {_pendingInvites > 0 && (
166 <Flex.Item as={Chip} className="bg-yellow1 yellow4">
167 {_pendingInvites} pending
168 </Flex.Item>
169 )}
170 </Flex>
171 </Grid.Item>
173 {showInvites && (
174 <>
175 <Grid.Item
176 full
177 as={BarGraph}
178 available={availableInvites}
179 sent={sentInvites}
180 accepted={acceptedInvites}
181 />
182 <Grid.Item
183 full
184 as={InviteSigilList}
185 pendingPoints={pendingPoints}
186 acceptedPoints={acceptedPoints}
187 />
188 </>
189 )}
190 {!showInvites && (
191 <>
192 <Grid.Item full className="b-gray4 b-dotted b1 self-center">
193 <div className="p4 pv8 t-center gray4">
194 Start your invite group by adding members
195 </div>
196 </Grid.Item>
197 </>
198 )}
199 {!showInviteForm && availableInvites.getOrElse(0) > 0 && (
200 <Grid.Item
201 full
202 solid
203 as={Button}
204 center
205 onClick={() => setShowInviteForm(true)}>
206 Add Members
207 </Grid.Item>
208 )}
209 {showInviteForm && <Inviter />}
210 <Grid.Item full className="mb2" />
211 </>
212 );
213 });
215 const _requestCount = requestCount.getOrElse(0);
217 return (
218 <View pop={pop} inset>
219 <Greeting point={point} />
220 <Passport
221 point={Just(point)}
222 address={Just(address)}
223 animationMode={'slide'}
224 />
225 <Grid gap={3}>
226 {isParent && (
227 <Grid.Item
228 full
229 as={Flex}
230 justify="between"
231 onClick={goResidents}
232 className="mv1">
233 <Flex.Item>
234 Residents{' '}
235 <span className="gray3">{matchBlinky(residentCount)}</span>
236 </Flex.Item>
237 {_requestCount !== 0 && (
238 <Flex.Item className="f7 bg-gray2 h3 pv1 ph2 br-full r-full text-center">
239 {_requestCount} PENDING
240 </Flex.Item>
241 )}
242 </Grid.Item>
243 )}
244 {isPlanet && hasInvites && <InviteForm />}
245 {!loadedInvites && isPlanet && (
246 <Grid.Item className="mv2" full>
247 Invite Group <Blinky />
248 </Grid.Item>
249 )}
250 </Grid>
251 <Grid className="pt2">
252 <Grid.Divider />
253 {inviteButton}
254 <Grid.Item
255 full
256 as={ForwardButton}
257 disabled={!canManage}
258 onClick={goUrbitID}
259 className="mt2"
260 detail="Identity and security settings">
261 ID
262 </Grid.Item>
263 <Grid.Divider />
264 <Grid.Item
265 full
266 as={ForwardButton}
267 disabled={!canManage}
268 className="mt2"
269 detail="Urbit OS Settings"
270 onClick={goUrbitOS}>
271 OS
272 </Grid.Item>
273 <Grid.Divider />
274 {isParent && (
275 <>
276 <Grid.Item
277 full
278 as={ForwardButton}
279 disabled={!canSpawn}
280 onClick={goIssuePoint}>
281 Issue Point
282 </Grid.Item>
283 <Grid.Divider />
284 </>
285 )}
286 {senateButton}
287 </Grid>
288 </View>
289 );