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