import React, { useCallback } from 'react'; import { Just, Nothing } from 'folktale/maybe'; import { Grid, H5, H1, HelpText, LinkButton, Flex } from 'indigo-react'; import { get } from 'lodash'; import { useHistory } from 'store/history'; import { useWallet } from 'store/wallet'; import { usePointCache } from 'store/pointCache'; import { usePointCursor } from 'store/pointCursor'; import * as need from 'lib/need'; import { isZeroAddress, abbreviateAddress } from 'lib/wallet'; import useIsEclipticOwner from 'lib/useIsEclipticOwner'; import { useSyncKnownPoints } from 'lib/useSyncPoints'; import View from 'components/View'; import Blinky from 'components/Blinky'; import Passport from 'components/Passport'; import useRejectedIncomingPointTransfers from 'lib/useRejectedIncomingPointTransfers'; import pluralize from 'lib/pluralize'; import Footer from 'components/Footer'; import { ForwardButton } from 'components/Buttons'; const maybeGetResult = (obj, key, defaultValue) => obj.matchWith({ Nothing: () => defaultValue, Just: p => p.value.matchWith({ Ok: r => get(r.value, key, defaultValue), Error: e => defaultValue, }), }); const hasTransferProxy = details => !isZeroAddress(details.transferProxy); const PointList = function({ points, className, actions, ...rest }) { const { setPointCursor } = usePointCursor(); const { push, names } = useHistory(); return ( {points.map((point, i) => ( { setPointCursor(Just(point)); push(names.POINT); }} {...rest} /> {actions && ( {actions(point, i)} )} ))} ); }; function ActionButtons({ actions = [] }) { return ( {actions.map(action => ( {action.text} ))} ); } export default function Points() { const { wallet } = useWallet(); const { pop, push, names } = useHistory(); const { setPointCursor } = usePointCursor(); const { controlledPoints, getDetails } = usePointCache(); const isEclipticOwner = useIsEclipticOwner(); const [ rejectedPoints, addRejectedPoint, ] = useRejectedIncomingPointTransfers(); const address = need.addressFromWallet(wallet); const loading = Nothing.hasInstance(controlledPoints); const ownedPoints = maybeGetResult(controlledPoints, 'ownedPoints', []); const incomingPoints = maybeGetResult( controlledPoints, 'incomingPoints', [] ).filter(point => !rejectedPoints.includes(point)); const managingPoints = maybeGetResult(controlledPoints, 'managingPoints', []); const votingPoints = maybeGetResult(controlledPoints, 'votingPoints', []); const spawningPoints = maybeGetResult(controlledPoints, 'spawningPoints', []); const outgoingPoints = ownedPoints.filter(point => getDetails(point).matchWith({ Nothing: () => false, Just: p => hasTransferProxy(p.value), }) ); const multipassPoints = [ ...ownedPoints.filter(p => !outgoingPoints.includes(p)), ...managingPoints, ...votingPoints, ...spawningPoints, ]; const displayEmptyState = !loading && incomingPoints.length === 0 && multipassPoints.length === 0; // sync display details for known points useSyncKnownPoints([ ...ownedPoints, ...incomingPoints, ...managingPoints, ...votingPoints, ...spawningPoints, ]); const goCreateGalaxy = useCallback(() => push(names.CREATE_GALAXY), [ names.CREATE_GALAXY, push, ]); const goViewPoint = useCallback(() => push(names.VIEW_POINT), [ names.VIEW_POINT, push, ]); return ( {abbreviateAddress(address)} {loading && ( Loading... )} {displayEmptyState && ( No points to display. This wallet is not the owner or proxy for any points. )} {incomingPoints.length > 0 && ( {pluralize( incomingPoints.length, 'Incoming Transfer', 'Incoming Transfers' )} ( { setPointCursor(Just(point)); push(names.ACCEPT_TRANSFER); }, }, { text: 'Reject', onClick: () => { addRejectedPoint(point); }, }, ]} /> )} inverted /> )} {outgoingPoints.length > 0 && ( {pluralize( outgoingPoints.length, 'Outgoing Transfer', 'Outgoing Transfers' )} ( { setPointCursor(Just(point)); // TODO: deep linking to fix this duplicate route push(names.CANCEL_TRANSFER); }, }, ]} /> )} inverted /> )} {multipassPoints.length > 0 && ( {pluralize(multipassPoints.length, 'Multipass', 'Multipasses')} )} ); }