on 1352bb6 help sign in
bridge/src/views/Point.js
269 lines 7.5 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 { ForwardButton, BootUrbitOSButton } from 'components/Buttons';
14import CopyButton from 'components/CopyButton';
15import Blinky, { matchBlinky } from 'components/Blinky';
16import BarGraph from 'components/BarGraph';
17import Chip from 'components/Chip';
18import InviteSigilList from 'components/InviteSigilList';
20import * as need from 'lib/need';
21import useInvites from 'lib/useInvites';
22import { useSyncOwnedPoints } from 'lib/useSyncPoints';
23import useCurrentPermissions from 'lib/useCurrentPermissions';
24import { useLocalRouter } from 'lib/LocalRouter';
25import useKeyfileGenerator from 'lib/useKeyfileGenerator';
27import Inviter from 'views/Invite/Inviter';
29export default function Point() {
30 const { pop, push, names } = useLocalRouter();
31 const { pointCursor } = usePointCursor();
33 const { wallet } = useWallet();
34 const point = need.point(pointCursor);
36 const { code, notice } = useKeyfileGenerator();
38 const {
39 isParent,
40 isActiveOwner,
41 canManage,
42 canSpawn,
43 canVote,
44 } = useCurrentPermissions();
46 // fetch the invites for the current cursor
47 const invites = useInvites(point);
48 const {
49 availableInvites,
50 sentInvites,
51 acceptedInvites,
52 pendingPoints,
53 acceptedPoints,
54 } = invites;
56 const showInvites = !(
57 acceptedInvites.getOrElse(0) === 0 && sentInvites.getOrElse(0) === 0
58 );
60 const hasInvites = showInvites || availableInvites.getOrElse(0) !== 0;
62 const _totalInvites =
63 sentInvites.getOrElse(0) + availableInvites.getOrElse(0);
64 const _pendingInvites = pendingPoints.getOrElse([]).length;
66 const loadedInvites = Just.hasInstance(availableInvites);
67 //
68 // availableInvites.getOrElse(0) === 0
70 const goAdmin = useCallback(() => push(names.ADMIN), [push, names]);
72 const goSenate = useCallback(() => push(names.SENATE), [push, names]);
74 const goSigil = useCallback(() => push(names.SIGIL_GENERATOR), [push, names]);
76 const goCohort = useCallback(() => push(names.INVITE_COHORT), [push, names]);
78 const goUrbitOS = useCallback(() => push(names.URBIT_OS), [push, names]);
80 const goPartiesSetPoolSize = useCallback(
81 () => push(names.PARTY_SET_POOL_SIZE),
82 [push, names]
83 );
85 const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
86 names.ISSUE_CHILD,
87 push,
88 ]);
90 const isPlanet = azimuth.getPointSize(point) === azimuth.PointSize.Planet;
92 const [showInviteForm, setShowInviteForm] = useState(false);
94 const inviteButton = (() => {
95 if (azimuth.getPointSize(point) === azimuth.PointSize.Star) {
96 return (
97 <>
98 <Grid.Item
99 full
100 as={ForwardButton}
101 disabled={!isActiveOwner}
102 onClick={goPartiesSetPoolSize}>
103 Manage Invite Pools
104 </Grid.Item>
105 <Grid.Divider />
106 </>
107 );
108 }
110 return null;
111 })();
113 const senateButton = (() => {
114 if (azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy) {
115 return null;
116 }
117 return (
118 <>
119 <Grid.Item
120 full
121 as={ForwardButton}
122 disabled={!canVote}
123 onClick={goSenate}>
124 Senate
125 </Grid.Item>
126 <Grid.Divider />
127 </>
128 );
129 })();
131 // sync the current cursor
132 useSyncOwnedPoints([point]);
134 const address = need.addressFromWallet(wallet);
136 return (
137 <View pop={pop} inset>
138 <Greeting point={point} />
139 <Passport
140 point={Just(point)}
141 address={Just(address)}
142 animationMode={'slide'}
143 />
144 <Grid gap={3}>
145 {isPlanet && hasInvites && (
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 {!loadedInvites && isPlanet && (
214 <Grid.Item className="mv2" full>
215 Invite Group <Blinky />
216 </Grid.Item>
217 )}
218 </Grid>
219 <Grid className="pt2">
220 {inviteButton}
221 <Grid.Item full as={ForwardButton} onClick={goSigil}>
222 Sigil
223 </Grid.Item>
224 <Grid.Divider />
225 <Grid.Item
226 full
227 as={ForwardButton}
228 disabled={!canManage}
229 onClick={goUrbitOS}>
230 Urbit OS
231 </Grid.Item>
232 <Grid.Item
233 full
234 as={ForwardButton}
235 disabled={!canManage}
236 onClick={goAdmin}>
237 Admin
238 </Grid.Item>
239 <Grid.Divider />
241 {isParent && (
242 <>
243 <Grid.Item
244 full
245 as={ForwardButton}
246 disabled={!canSpawn}
247 onClick={goIssuePoint}>
248 Issue Point
249 </Grid.Item>
250 <Grid.Divider />
251 </>
252 )}
253 {senateButton}
254 <Grid.Item full as={BootUrbitOSButton} />
255 <Grid.Divider />
256 <Grid.Item
257 full
258 as={ForwardButton}
259 accessory={code && <CopyButton text={code} />}
260 detail={code || notice}
261 disabled={!code}
262 detailClassName="mono">
263 Login Code
264 </Grid.Item>
265 <Grid.Divider />
266 </Grid>
267 </View>
268 );