@@ -0,0 +1,143 @@
1+import React, { useCallback, useEffect, useMemo } from 'react';
2+import cn from 'classnames';
3+import { Grid, Flex } from 'indigo-react';
5+import * as need from 'lib/need';
6+import useEthereumTransaction from 'lib/useEthereumTransaction';
7+import pluralize from 'lib/pluralize';
9+import { useWallet } from 'store/wallet';
10+import { usePointCache } from 'store/pointCache';
11+import { useStarReleaseCache } from 'store/starRelease';
13+import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
15+import { NumberInput, AddressInput } from 'form/Inputs';
16+import BridgeForm from 'form/BridgeForm';
17+import FormError from 'form/FormError';
18+import { composeValidator, buildNumberValidator } from 'form/validators';
19+import { convertToNumber } from 'form/formatters';
21+function AddressIndicator({ isOwn, className }) {
23+ <div className={cn('green2', className)}>✓ Current Address</div>
25+ <div className={cn('red4', className)}>! Different address</div>
29+function useWithdrawStars() {
30+ const { syncControlledPoints } = usePointCache();
32+ const { syncStarReleaseDetails, withdraw } = useStarReleaseCache();
33+ return useEthereumTransaction(
34+ useCallback((to, amount) => withdraw(amount, to)),
36+ () => Promise.all([syncControlledPoints(), syncStarReleaseDetails()]),
37+ [syncStarReleaseDetails, syncControlledPoints]
42+export default function LockedView({ className }) {
43+ const { wallet } = useWallet();
44+ const address = need.addressFromWallet(wallet);
45+ const { bind, construct, unconstruct, inputsLocked } = useWithdrawStars();
47+ const { syncStarReleaseDetails, starReleaseDetails } = useStarReleaseCache();
50+ syncStarReleaseDetails();
51+ }, [syncStarReleaseDetails]);
53+ const onValues = useCallback(
54+ ({ valid, values }) => {
56+ construct(values.address, convertToNumber(values.numStars));
61+ [construct, unconstruct]
64+ const available = starReleaseDetails
65+ .map(b => b.available - b.withdrawn)
67+ const total = starReleaseDetails.map(b => b.total).getOrElse(0);
68+ const withdrawn = starReleaseDetails.map(b => b.withdrawn).getOrElse(0);
70+ const validate = useMemo(
73+ numStars: buildNumberValidator(0, available + 1),
78+ const initialValues = { address };
81+ <Grid gap={6} className={cn('mt4', className)} full>
83+ initialValues={initialValues}
86+ {({ values, reset }) => (
88+ <Grid.Item full className="f5">
92+ green2: available > 0,
93+ red4: available === 0,
97+ {pluralize(available, ' star ', ' stars ')}
98+ available to withdraw
100+ You have <span className="green2">{total - withdrawn}</span>
101+ {pluralize(available, ' star ', ' stars ')}
104+ <Grid.Item full className="f5" cols={[1, 10]} as={Flex} col>
109+ disabled={inputsLocked}
112+ as={AddressIndicator}
113+ isOwn={address === values.address}
120+ style={{ minWidth: '0' }}
124+ disabled={inputsLocked}
126+ <Grid.Item as={Flex} col cols={[5, 8]}>
127+ <Flex.Item className="f6 lh-tall"> </Flex.Item>
128+ <Flex.Item className="f3">/ {available}</Flex.Item>
130+ <Grid.Item full as={FormError} />
133+ as={InlineEthereumTransaction}
135+ onReturn={() => reset()}
136+ label="Withdraw Stars"