1import React, { useCallback, useEffect, useState } from 'react';
2import cn from 'classnames';
3import { azimuth } from 'azimuth-js';
4import { Just } from 'folktale/maybe';
5import { Grid, Flex } from 'indigo-react';
6import { Box, Icon, Row, Button } from '@tlon/indigo-react';
8import { usePointCursor } from 'store/pointCursor';
9import { useWallet } from 'store/wallet';
10import { useRollerStore } from 'store/roller';
12import View from 'components/View';
13import Greeting from 'components/Greeting';
14import Passport from 'components/Passport';
15import Blinky from 'components/Blinky';
16import BarGraph from 'components/BarGraph';
17import Chip from 'components/Chip';
18import InviteSigilList from 'components/InviteSigilList';
19import { ForwardButton } from 'components/Buttons';
20import L2PointHeader from 'components/L2/Headers/L2PointHeader';
21import LayerIndicator from 'components/L2/LayerIndicator';
22import Card from 'components/L2/Card';
24import * as need from 'lib/need';
25import useInvites from 'lib/useInvites';
26import { useSyncExtras } from 'lib/useSyncPoints';
27import useCurrentPermissions from 'lib/useCurrentPermissions';
28import { useLocalRouter } from 'lib/LocalRouter';
29import Inviter from 'views/Invite/Inviter';
30import useRoller from 'lib/useRoller';
33import { isL2 } from 'lib/utils/roller';
34import { isDevelopment } from 'lib/flags';
35import { convertToInt } from 'lib/convertToInt';
36import { usePointCache } from 'store/pointCache';
37import Modal from 'components/L2/Modal';
38import { isPlanet } from 'lib/utils/point';
52 sentInvites.getOrElse(0) + availableInvites.getOrElse(0);
53 const _pendingInvites = pendingPoints.getOrElse([]).length;
57 <Grid.Item cols={[1, 11]}>
63 className={cn('t-right underline pointer-hover', {
64 gray4: sentInvites.getOrElse(0) === 0,
73 {acceptedInvites.getOrElse(0)} / {_totalInvites}
75 {_pendingInvites > 0 && (
76 <Flex.Item as={Chip} className="bg-yellow1 yellow4">
77 {_pendingInvites} pending
88 available={availableInvites}
90 accepted={acceptedInvites}
95 pendingPoints={pendingPoints}
96 acceptedPoints={acceptedPoints}
102 <Grid.Item full className="b-gray4 b-dotted b1 self-center">
103 <div className="p4 pv8 t-center gray4">
104 Start your invite group by adding members
109 {!showInviteForm && availableInvites.getOrElse(0) > 0 && (
115 onClick={() => setShowInviteForm(true)}>
119 {showInviteForm && <Inviter />}
120 <Grid.Item full className="mb2" />
125export default function Point() {
126 const { pop, push, names } = useLocalRouter();
127 const { wallet, authToken } = useWallet();
128 const { pointCursor } = usePointCursor();
129 const point = need.point(pointCursor);
130 const { getDetails } = usePointCache();
131 // sync the current cursor
132 useSyncExtras([point]);
134 const { api, getInvites } = useRoller();
140 setPendingTransactions,
145 } = useRollerStore();
147 // const pointSize = azimuth.getPointSize(point);
148 // const details = need.details(getDetails(point));
149 // const details = getDetails(point);
150 // console.log(details);
151 // const isStarOrGalaxy = pointSize !== azimuth.PointSize.Planet;
152 // const networkRevision =
153 // Just.hasInstance(details) &&
154 // convertToInt(need.details(details).keyRevisionNumber, 10);
155 // console.log(networkRevision);
156 const networkKeysNotSet = false;
157 // networkRevision && !currentL2 && isStarOrGalaxy && networkRevision === 0;
159 const [showModal, setShowModal] = useState(networkKeysNotSet);
162 // if (networkKeysNotSet) {
163 // setShowModal(true);
165 // }, [networkKeysNotSet]);
169 const loadL2Info = async () => {
170 const getTransactions = async () => {
171 const pointInfo = await api.getPoint(Number(point));
172 const pendingTxs = await api.getPendingByShip(Number(point));
174 console.log('POINT INFO', pointInfo);
176 setNonces(point, pointInfo.ownership);
178 for (let index = 0; index < pendingTxs.length; index++) {
179 const proxy = pendingTxs[index].rawTx?.from?.proxy;
180 console.log(pointInfo.ownership, proxy);
181 increaseNonce(point, proxy);
183 setCurrentPoint(pointInfo);
184 getInvites(isL2(pointInfo.dominion));
193 // TODO: adding this causes the effect to be called constantly...
197 // setPendingTransactions,
206 const { isParent, canManage, canSpawn, canVote } = useCurrentPermissions();
209 const l1Invites = useInvites(point);
218 const showInvites = !(
219 acceptedInvites.getOrElse(0) === 0 && sentInvites.getOrElse(0) === 0
222 const hasInvites = showInvites || availableInvites.getOrElse(0) !== 0;
224 const loadedInvites = Just.hasInstance(availableInvites);
226 // availableInvites.getOrElse(0) === 0
228 const goSenate = useCallback(() => push(names.SENATE), [push, names]);
230 const goCohort = useCallback(() => push(names.INVITE_COHORT), [push, names]);
232 const goUrbitOS = useCallback(() => push(names.URBIT_OS), [push, names]);
234 const goUrbitID = useCallback(() => push(names.URBIT_ID), [push, names]);
236 const goResidents = useCallback(() => push(names.RESIDENTS), [push, names]);
238 const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
243 const planet = isPlanet(point);
245 const [showInviteForm, setShowInviteForm] = useState(false);
247 const senateButton = (() => {
248 if (azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy) {
265 // sync the current cursor
266 useSyncExtras([point]);
268 const address = need.addressFromWallet(wallet);
269 const numPending = pendingTransactions.filter(
270 ({ rawTx }) => rawTx?.tx?.type === 'spawn'
281 hideTimer={!!numPending}
282 numInvites={invites.length}
283 hideInvites={networkKeysNotSet}
286 <Greeting point={point} />
288 <div className="transaction">
289 <Row className="title-row">
290 <div className="title">
292 {numPending > 1 ? 's' : ''} Spawned
294 <div className="rollup-timer">
295 <Icon icon="Clock" />
299 <Row className="info-row">
300 <LayerIndicator layer={2} size="sm" />
301 <div className="date"></div>
307 address={Just(address)}
308 animationMode={'slide'}
312 <Grid.Item full as={Flex} justify="between">
315 subtitle="Manage peers that you service"
316 onClick={goResidents}
320 {planet && hasInvites && (
322 showInviteForm={showInviteForm}
323 setShowInviteForm={setShowInviteForm}
324 acceptedInvites={acceptedInvites}
325 acceptedPoints={acceptedPoints}
326 availableInvites={availableInvites}
328 pendingPoints={pendingPoints}
329 sentInvites={sentInvites}
330 showInvites={showInvites}
333 {!loadedInvites && planet && (
334 <Grid.Item className="mv2" full>
335 Invite Group <Blinky />
338 {/* {inviteButton} */}
339 <Grid.Item full as={Flex} justify="between">
342 subtitle="Identity and security settings"
343 icon={<Icon icon="User" />}
345 disabled={!canManage}
348 <Grid.Item full as={Flex} justify="between">
351 subtitle="Urbit OS Settings"
352 icon={<Icon icon="Server" />}
354 disabled={!canManage}
363 onClick={goIssuePoint}>
371 <Modal show={showModal} hide={() => setShowModal(false)}>
372 <Box className="network-keys-modal">
373 <Box className="close" onClick={() => setShowModal(false)}>
376 <Box className="title">Network Keys Not Set</Box>
377 <Box className="message">
378 This point's network keys are not set. The network keys must be set
379 to spawn points or migrate to Layer 2. Please set them in Urbit OS
382 <Row className="buttons">
383 <Button className="cancel" onClick={() => setShowModal(false)}>
386 <Button className="migrate" onClick={goUrbitOS}>
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list