5 Button as IndigoButton,
8} from '@tlon/indigo-react';
9import { Button } from 'indigo-react';
10import Modal from './Modal';
11import { useCallback, useEffect, useState } from 'react';
12import { ReactComponent as InviteIcon } from 'assets/invite.svg';
13import Point from 'lib/types/Point';
14import useRoller from 'lib/useRoller';
15import BodyPane from './Window/BodyPane';
17 InviteGeneratingStatus,
20} from 'views/Invite/useInvites';
21import { usePointCache } from 'store/pointCache';
22import { CreatingInvitesModal } from './CreatingInvitesModal';
23import { useWallet } from 'store/wallet';
24import { WALLET_TYPES } from 'lib/constants';
33interface InviteConverterProps {
37function selectText(selected: string[], children: Point[]) {
41 children.map(p => p.patp)
44 return 'Deselect All';
50function allChildrenSelected(selected: string[], childrenPatps: string[]) {
51 const filtered = childrenPatps.filter(p => selected.includes(p));
52 return filtered.length === childrenPatps.length;
55export const InviteConverter = ({ points }: InviteConverterProps) => {
56 const { syncControlledPoints }: any = usePointCache();
57 const { walletType }: any = useWallet();
59 walletType === WALLET_TYPES.TICKET || walletType === WALLET_TYPES.SHARDS;
60 const { api, getPendingTransactions, getAndUpdatePoint } = useRoller();
61 const { inviteJobs } = useInviteStore();
62 const { generateInviteCodes } = useInvites();
63 const [show, setShow] = useState(false);
64 const [selected, setSelected] = useState<string[]>([]);
65 const [starMap, setStarMap] = useState<StarMap>({});
66 const [generatingStatus, setGeneratingStatus] = useState<
67 InviteGeneratingStatus
69 const [error, setError] = useState('');
70 const [created, setCreated] = useState(0);
71 const [currentPoint, setCurrentPoint] = useState<Point>();
72 const currentJob = inviteJobs[currentPoint?.value || 0];
73 const signatureCount = selected.length * 3;
80 async function collect() {
81 const pointMap: StarMap = {};
82 const stars = points.filter(point => point.isStar && point.isL2Spawn);
84 for (const star of stars) {
85 const spawns = await api.getSpawned(star.value);
86 const filteredPoints = points.filter(
87 p => spawns.includes(p.value) && p.isL2Spawn
90 if (filteredPoints.length !== 0) {
91 pointMap[star.patp] = {
93 children: filteredPoints,
104 const selectChildren = useCallback(
105 (children: Point[]) => {
106 setSelected(state => {
107 const childrenPatps = children.map(p => p.patp);
108 const withoutChildren = state.filter(p => !childrenPatps.includes(p));
110 if (allChildrenSelected(state, childrenPatps)) {
111 return withoutChildren;
113 return withoutChildren.concat(childrenPatps);
120 const togglePoint = useCallback(
122 setSelected(state => {
123 if (state.includes(point.patp)) {
124 return state.filter(p => p !== point.patp);
126 return state.concat([point.patp]);
133 const convert = useCallback(async () => {
134 if (generatingStatus !== 'initial') {
138 setGeneratingStatus('generating');
141 for (const { point, children } of Object.values(starMap)) {
142 const filtered = children
143 .filter(p => selected.includes(p.patp))
146 if (filtered.length <= 0) {
150 setCurrentPoint(point);
151 await generateInviteCodes(point, filtered, false);
152 await getAndUpdatePoint(point.value);
153 setCreated(children.length);
156 setGeneratingStatus('finished');
158 if (typeof error === 'object' && (error as Error)?.message) {
159 setError((error as Error).message);
160 } else if (typeof error === 'string') {
163 setError('Creating invites failed');
165 setGeneratingStatus('errored');
176 Object.entries(starMap).reduce((sum, [, star]) => {
177 return (sum += star.children.length);
180 if (generatingStatus !== 'initial') {
182 <CreatingInvitesModal
183 status={generatingStatus}
184 current={created + currentJob?.generatingNum}
185 total={selected.length}
188 setGeneratingStatus('initial');
192 getPendingTransactions();
193 syncControlledPoints();
203 <Button className="create-invites" center onClick={() => setShow(true)}>
206 <Modal small show={show} hide={() => setShow(false)}>
209 <Row alignItems="center" mb={3}>
212 Updates invites for planets
216 Select L2 planets you own to convert them back into invite links
217 under each star.{' '}
218 <Text color="red" lineHeight="24px">
219 Note: this will re-ticket the planets and render their existing
224 <Text bold className={!!signatureCount ? '' : 'hidden'}>
225 {signatureCount} manual signatures will be required.
235 alignItems={hasPlanets ? '' : 'center'}
236 justifyContent={hasPlanets ? '' : 'center'}>
237 {Object.entries(starMap).map(([patp, { children }]) => (
244 backgroundColor="transparent"
246 onClick={() => selectChildren(children)}>
247 {selectText(selected, children)}
250 {children.map((point, index) => (
253 justifyContent="space-between"
256 index === children.length - 1 ? '0px' : '1px'
258 borderBottomStyle="solid"
259 borderBottomColor="washedGray">
260 <Text>{point.patp}</Text>
262 selected={selected.includes(point.patp)}
263 onClick={() => togglePoint(point)}
269 {!hasPlanets && <Text>No planets to update</Text>}
271 <Row mt={3} justifyContent="end">
273 className="secondary"
274 onClick={() => setShow(false)}>
280 className={selected.length === 0 ? '' : 'primary'}
283 disabled={selected.length === 0}>
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