on eb070bb help sign in
bridge/src/views/Point.js
296 lines 7.9 kB history raw
1import React, { useCallback, useState } 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 } from 'components/Buttons';
19import * as need from 'lib/need';
20import useInvites from 'lib/useInvites';
21import { useSyncOwnedPoints } from 'lib/useSyncPoints';
22import useCurrentPermissions from 'lib/useCurrentPermissions';
23import { useLocalRouter } from 'lib/LocalRouter';
25import Inviter from 'views/Invite/Inviter';
26import { usePointCache } from 'store/pointCache';
28export default function Point() {
29 const { pop, push, names } = useLocalRouter();
30 const { pointCursor } = usePointCursor();
32 const { wallet } = useWallet();
33 const point = need.point(pointCursor);
35 const { getResidents } = usePointCache();
37 const { residentCount, requestCount } = getResidents(point);
39 const {
40 isParent,
41 isActiveOwner,
42 canManage,
43 canSpawn,
44 canVote,
45 isOwner,
46 } = useCurrentPermissions();
48 // fetch the invites for the current cursor
49 const invites = useInvites(point);
50 const {
51 availableInvites,
52 sentInvites,
53 acceptedInvites,
54 pendingPoints,
55 acceptedPoints,
56 } = invites;
58 const showInvites = !(
59 acceptedInvites.getOrElse(0) === 0 && sentInvites.getOrElse(0) === 0
60 );
62 const hasInvites = showInvites || availableInvites.getOrElse(0) !== 0;
64 const _totalInvites =
65 sentInvites.getOrElse(0) + availableInvites.getOrElse(0);
66 const _pendingInvites = pendingPoints.getOrElse([]).length;
68 const loadedInvites = Just.hasInstance(availableInvites);
69 //
70 // availableInvites.getOrElse(0) === 0
72 const goSenate = useCallback(() => push(names.SENATE), [push, names]);
74 const goCohort = useCallback(() => push(names.INVITE_COHORT), [push, names]);
76 const goUrbitOS = useCallback(() => push(names.URBIT_OS), [push, names]);
78 const goUrbitID = useCallback(() => push(names.URBIT_ID), [push, names]);
80 const goResidents = useCallback(() => push(names.RESIDENTS), [push, names]);
82 const goPartiesSetPoolSize = useCallback(
83 () => push(names.PARTY_SET_POOL_SIZE),
84 [push, names]
85 );
87 const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
88 names.ISSUE_CHILD,
89 push,
90 ]);
92 const isPlanet = azimuth.getPointSize(point) === azimuth.PointSize.Planet;
94 const [showInviteForm, setShowInviteForm] = useState(false);
96 const inviteButton = (() => {
97 if (azimuth.getPointSize(point) === azimuth.PointSize.Star) {
98 return (
99 <>
100 <Grid.Item
101 full
102 as={ForwardButton}
103 disabled={!isActiveOwner}
104 onClick={goPartiesSetPoolSize}>
105 Manage Invite Pools
106 </Grid.Item>
107 <Grid.Divider />
108 </>
109 );
110 }
112 return null;
113 })();
115 const senateButton = (() => {
116 if (azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy) {
117 return null;
118 }
119 return (
120 <>
121 <Grid.Item
122 full
123 as={ForwardButton}
124 disabled={!canVote}
125 onClick={goSenate}>
126 Senate
127 </Grid.Item>
128 <Grid.Divider />
129 </>
130 );
131 })();
133 // sync the current cursor
134 useSyncOwnedPoints([point]);
136 const address = need.addressFromWallet(wallet);
138 const InviteForm = useCallback(() => {
139 return (
140 <>
141 <Grid.Item cols={[1, 11]}>
142 Invite Group
143 <br />
144 </Grid.Item>
146 <Grid.Item
147 className={cn('t-right underline pointer-hover', {
148 gray4: sentInvites.getOrElse(0) === 0,
149 })}
150 onClick={goCohort}
151 cols={[11, 13]}>
152 View
153 </Grid.Item>
154 <Grid.Item full>
155 <Flex align="center">
156 <Flex.Item>
157 {acceptedInvites.getOrElse(0)} / {_totalInvites}
158 </Flex.Item>
159 {_pendingInvites > 0 && (
160 <Flex.Item as={Chip} className="bg-yellow1 yellow4">
161 {_pendingInvites} pending
162 </Flex.Item>
163 )}
164 </Flex>
165 </Grid.Item>
167 {showInvites && (
168 <>
169 <Grid.Item
170 full
171 as={BarGraph}
172 available={availableInvites}
173 sent={sentInvites}
174 accepted={acceptedInvites}
175 />
176 <Grid.Item
177 full
178 as={InviteSigilList}
179 pendingPoints={pendingPoints}
180 acceptedPoints={acceptedPoints}
181 />
182 </>
183 )}
184 {!showInvites && (
185 <>
186 <Grid.Item full className="b-gray4 b-dotted b1 self-center">
187 <div className="p4 pv8 t-center gray4">
188 Start your invite group by adding members
189 </div>
190 </Grid.Item>
191 </>
192 )}
193 {!showInviteForm && availableInvites.getOrElse(0) > 0 && (
194 <Grid.Item
195 full
196 solid
197 as={Button}
198 center
199 onClick={() => setShowInviteForm(true)}>
200 Add Members
201 </Grid.Item>
202 )}
203 {showInviteForm && <Inviter />}
204 <Grid.Item full className="mb2" />
205 </>
206 );
207 }, [
208 showInviteForm,
209 setShowInviteForm,
210 _pendingInvites,
211 _totalInvites,
212 acceptedInvites,
213 acceptedPoints,
214 availableInvites,
215 goCohort,
216 pendingPoints,
217 sentInvites,
218 showInvites,
219 ]);
221 const _requestCount = requestCount.getOrElse(0);
223 return (
224 <View pop={pop} inset>
225 <Greeting point={point} />
226 <Passport
227 point={Just(point)}
228 address={Just(address)}
229 animationMode={'slide'}
230 />
231 <Grid gap={3}>
232 {isParent && (
233 <Grid.Item
234 full
235 as={Flex}
236 justify="between"
237 onClick={goResidents}
238 className="mv1 pointer">
239 <Flex.Item>
240 Residents{' '}
241 <span className="gray3">{matchBlinky(residentCount)}</span>
242 </Flex.Item>
243 {_requestCount !== 0 && (
244 <Flex.Item className="f7 bg-gray2 h3 pv1 ph2 br-full r-full text-center">
245 {_requestCount} PENDING
246 </Flex.Item>
247 )}
248 </Grid.Item>
249 )}
250 {isPlanet && hasInvites && <InviteForm />}
251 {!loadedInvites && isPlanet && (
252 <Grid.Item className="mv2" full>
253 Invite Group <Blinky />
254 </Grid.Item>
255 )}
256 </Grid>
257 <Grid className="pt2">
258 <Grid.Divider />
259 {inviteButton}
260 <Grid.Item
261 full
262 as={ForwardButton}
263 disabled={!canManage}
264 onClick={goUrbitID}
265 className="mt1"
266 detail="Identity and security settings">
267 ID
268 </Grid.Item>
269 <Grid.Divider />
270 <Grid.Item
271 full
272 as={ForwardButton}
273 disabled={!canManage}
274 className="mt1"
275 detail="Urbit OS Settings"
276 onClick={goUrbitOS}>
277 OS
278 </Grid.Item>
279 <Grid.Divider />
280 {isParent && (
281 <>
282 <Grid.Item
283 full
284 as={ForwardButton}
285 disabled={!canSpawn}
286 onClick={goIssuePoint}>
287 Issue Point
288 </Grid.Item>
289 <Grid.Divider />
290 </>
291 )}
292 {senateButton}
293 </Grid>
294 </View>
295 );