1import { useCallback, useEffect, useState, useRef } from 'react';
2import { Just } from 'folktale/maybe';
3import { Grid, Flex } from 'indigo-react';
4import { Box, Icon, Row, Button, Checkbox } from '@tlon/indigo-react';
6import { usePointCache } from 'store/pointCache';
7import { useWallet } from 'store/wallet';
8import { useRollerStore } from 'store/rollerStore';
9import { useTimerStore } from 'store/timerStore';
11import View from 'components/View';
12import Greeting from 'components/Greeting';
13import Passport from 'components/Passport';
14import L2PointHeader from 'components/L2/Headers/L2PointHeader';
15import Card from 'components/L2/Card';
17import * as need from 'lib/need';
18import { useLocalRouter } from 'lib/LocalRouter';
19import useRoller from 'lib/useRoller';
20import useSeenMissingKeys from 'lib/useSeenMissingKeys';
21import { useHasNetworkKeysSet } from 'lib/useHasNetworkKeysSet';
23import LoadingOverlay from 'components/L2/LoadingOverlay';
24import PendingTransaction from 'components/L2/PendingTransaction';
25import Modal from 'components/L2/Modal';
27import { TransactionRow } from 'views/Transactions/TransactionRow';
28import { useInvites } from 'views/Invite/useInvites';
30export default function Point() {
31 const { pop, push, names }: any = useLocalRouter();
32 const { wallet }: any = useWallet();
33 const { syncExtras }: any = usePointCache();
34 const { getPendingTransactions } = useRoller();
35 const { getInvites } = useInvites();
36 const { pendingTransactions, point, pendingL1ByPoint } = useRollerStore();
37 const { nextRoll } = useTimerStore();
38 const networkKeysSet = useHasNetworkKeysSet();
39 const [seenMissingKeys, setSeenMissingKeys] = useSeenMissingKeys();
40 const [showModal, setShowModal] = useState(false);
41 const [hideMessage, setHideMessage] = useState(false);
42 const [loading, setLoading] = useState(false);
44 const pointRef = useRef<number | null>(null);
46 const pendingL1Transactions = pendingL1ByPoint[point.value] || [];
48 const hideModal = useCallback(() => {
50 setSeenMissingKeys(true);
54 }, [hideMessage, setShowModal, setSeenMissingKeys]);
57 if (!pointRef.current || pointRef.current !== point.value) {
58 pointRef.current = point.value;
59 setShowModal(!point.networkKeysSet && !seenMissingKeys);
61 }, [seenMissingKeys, point]);
63 const loadL1Info = useCallback(async () => {
64 await syncExtras(point.value);
65 }, [point, syncExtras]);
67 const loadL2Info = useCallback(async () => {
68 const getTransactions = async () => {
70 getPendingTransactions();
71 if (point.isStar && (point.canSpawn || point.canManage)) {
74 setTimeout(() => setLoading(false), 100);
77 await getTransactions();
78 }, [getInvites, getPendingTransactions, setLoading]); // eslint-disable-line react-hooks/exhaustive-deps
83 }, [point]); // eslint-disable-line react-hooks/exhaustive-deps
85 const { isParent, canManage, isSpawnProxy } = point;
87 const goUrbitOS = useCallback(() => {
88 if (hideMessage) setSeenMissingKeys(hideMessage);
91 }, [push, names, hideMessage, setSeenMissingKeys]);
93 const goUrbitID = useCallback(() => push(names.URBIT_ID), [push, names]);
95 const goOps = useCallback(() => push(names.OPS), [push, names]);
97 const address = need.addressFromWallet(wallet);
98 const spawnedPending = pendingTransactions.filter(
99 ({ rawTx }) => rawTx?.tx?.type === 'spawn'
101 const otherPending = pendingTransactions.filter(
102 ({ rawTx }) => rawTx?.tx?.type !== 'spawn'
111 header={<L2PointHeader hideInvites={!networkKeysSet} />}>
112 <Greeting point={point.value} />
113 {!!spawnedPending && (
117 title={`${spawnedPending} Planet${
118 spawnedPending > 1 ? 's' : ''
122 {!!otherPending.length &&
123 otherPending.map(pendingTx => (
125 className="point-view"
128 type={pendingTx.rawTx?.tx?.type}
130 time={pendingTx.time}
133 {!!pendingL1Transactions.length &&
134 pendingL1Transactions.map((pendingTx, ind) => (
136 className="point-view"
139 type={pendingTx.type as string}
141 time={pendingTx.time}
142 hash={pendingTx.hash}
147 point={Just(point.value)}
148 address={Just(address)}
149 animationMode={'slide'}
153 <Grid.Item full as={Flex} justify="between">
155 icon={(<Icon icon="ShipActivated" />) as any}
156 title={`${point.isStar ? 'Star' : 'Galaxy'} Ops`}
159 ? 'Residents, Requests, Spawn Planets'
160 : 'Residents, Requests, Spawn Stars, Vote'
166 {(canManage || isSpawnProxy) && (
167 <Grid.Item full as={Flex} justify="between">
170 subtitle="Master Key, Passport, Proxy Addresses, etc"
171 icon={(<Icon icon="User" />) as any}
173 disabled={!(canManage || isSpawnProxy)}
178 <Grid.Item full as={Flex} justify="between">
181 subtitle="Sponsor, Network Keys, Access Key"
182 icon={(<Icon icon="Server" />) as any}
184 disabled={!canManage}
189 <Modal show={showModal} hide={hideModal}>
190 <Box className="network-keys-modal">
191 <Box className="title">No Network Keys Found</Box>
192 <Box className="message">
193 Network Keys are required to generate a Keyfile and use Landscape.
195 <Row className="hide-row">
198 selected={hideMessage}
199 onClick={() => setHideMessage(!hideMessage)}
201 <Box className="dont-show">Do not warn me again</Box>
203 <Row className="buttons">
204 <Button className="cancel" onClick={hideModal}>
207 <Button className="migrate" onClick={goUrbitOS}>
213 <LoadingOverlay loading={loading} />
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