@@ -1,11 +1,13 @@
1−import React, { useState } from 'react';
1+import React, { useState, useCallback } from 'react';
2−import { Just } from 'folktale/maybe';
4−import View from 'components/View';
3+import { Grid, H4, Text, ErrorText } from 'indigo-react';
5−import { ForwardButton } from 'components/Buttons';
4+import { RestartButton } from 'components/Buttons';
6−import { Warning } from 'components/old/Base';
5+import WarningBox from 'components/WarningBox';
6+import LoadingBar from 'components/LoadingBar';
7+import Highlighted from 'components/Highlighted';
8−import { TRANSACTION_STATES, claimPointFromInvite } from 'lib/invite';
9+import { claimPointFromInvite } from 'lib/invite';
10+import { fromWei } from 'lib/txn';
10import * as need from 'lib/need';
12import * as need from 'lib/need';
11import { useNetwork } from 'store/network';
13import { useNetwork } from 'store/network';
@@ -13,15 +15,18 @@ import { useWallet } from 'store/wallet';
13import { usePointCursor } from 'store/pointCursor';
15import { usePointCursor } from 'store/pointCursor';
14import useLifecycle from 'lib/useLifecycle';
16import useLifecycle from 'lib/useLifecycle';
18+//TODO maybe we want to drop in PassportTransfer here?
16export default function DoReticket({ newWallet, completed }) {
19export default function DoReticket({ newWallet, completed }) {
17 const { web3, contracts } = useNetwork();
20 const { web3, contracts } = useNetwork();
18 const { wallet, setUrbitWallet } = useWallet();
21 const { wallet, setUrbitWallet } = useWallet();
19 const { pointCursor } = usePointCursor();
22 const { pointCursor } = usePointCursor();
21− const [transactionProgress, setTransactionProgress] = useState(
24+ const [generalError, setGeneralError] = useState();
22− TRANSACTION_STATES.GENERATING
25+ const [{ label, progress }, setState] = useState({
26+ label: 'Starting...',
24− const [errors, setErrors] = useState([]);
29+ const [needFunds, setNeedFunds] = useState();
26 // start reticketing transactions on mount
31 // start reticketing transactions on mount
27 useLifecycle(() => {
32 useLifecycle(() => {
@@ -31,70 +36,94 @@ export default function DoReticket({ newWallet, completed }) {
31 point: need.point(pointCursor),
36 point: need.point(pointCursor),
32 web3: need.web3(web3),
37 web3: need.web3(web3),
33 contracts: need.contracts(contracts),
38 contracts: need.contracts(contracts),
34− onUpdate: updateProgress,
39+ onUpdate: handleUpdate,
35− }).then(() => {
41+ .then(() => {
36− setUrbitWallet(newWallet.value.wallet);
42+ setUrbitWallet(newWallet.value.wallet);
43+ next(); //TODO don't auto-redirect
46+ setGeneralError(err);
40− const updateProgress = notification => {
50+ const handleUpdate = useCallback(
51+ ({ type, state, value }) => {
41− if (notification.type === 'progress') {
53+ case 'progress':
42− setTransactionProgress(notification.value);
54+ return setState(state);
43− } else if (notification.type === 'notify') {
55+ case 'askFunding':
44− setErrors([notification.value]);
56+ return setNeedFunds(value);
45− }
57+ case 'gotFunding':
58+ return setNeedFunds(false);
60+ console.error(`Unknown update: ${type}`);
63+ [setState, setNeedFunds]
48 const next = () => {
66 const next = () => {
49 completed();
67 completed();
52− const getErrors = () => {
70+ const renderAdditionalInfo = () => {
53− if (errors.length === 0) return null;
71+ if (generalError) {
74+ <Grid.Item full className="mt8">
75+ <ErrorText>{generalError.message.toString()}</ErrorText>
81+ //TODO onClick={goToRestart}
55− let errorElems = errors.map(e => <span>{e}</span>);
87+ if (needFunds) {
89+ <Grid.Item full className="mt8">
91+ The address {needFunds.address} needs at least{' '}
92+ {fromWei(needFunds.minBalance)} ETH and currently has{' '}
93+ {fromWei(needFunds.balance)} ETH. Waiting until the account has
100+ if (progress < 100) {
57− return (
101+ return (
58− <Warning>
102+ <Grid.Item full as={WarningBox} className="mt8">
59− <h3 className={'mb-2'}>{'Warning'}</h3>
103+ Never give your Master Ticket to anyone
60− {errorElems}
104+ </Grid.Item>
65− const errorDisplay = getErrors();
108+ return null;
68− <View>
112+ <Grid className={'auto-rows-min'}>
69− {errorDisplay}
113+ <Grid.Item full as={H4}>
70− {transactionProgress.label === TRANSACTION_STATES.DONE.label ? (
114+ {label}
71− <div>
115+ </Grid.Item>
72− <h1 className="fs-6 lh-8 mb-3">
116+ <Grid.Item full as={Grid} className="mt3" gap={3}>
73− <span>Success</span>
117+ <Grid.Item full as={LoadingBar} progress={progress} />
74− <span className="ml-4 green">✓</span>
118+ <Grid.Item full>
76− <ForwardButton onClick={next}>Done!</ForwardButton>
80− <h1 className="fs-6 lh-8 mb-3">Submitting</h1>
81− <p className="mt-4 mb-4">
119+ <Text className="f5 green4">
82− This step can take up to five minutes. Please do not leave this page
120+ This process can take up to 5 minutes to complete. Don't leave this
83− until the transactions are complete.
121+ page until the process is complete.
85− <div className="passport-progress mb-2">
123+ </Grid.Item>
86− <div
124+ </Grid.Item>
87− className="passport-progress-filled"
125+
88− style={{ width: transactionProgress.pct }}
126+ {renderAdditionalInfo()}
91− <div className="flex justify-between">
92− <div className="text-mono text-sm lh-6 green-dark">
93− {transactionProgress.label}