Skip to content

Commit

Permalink
Closes #69
Browse files Browse the repository at this point in the history
Merge branch 'app/feature/69-transfer-progress-bar' into design
  • Loading branch information
jack0son committed Apr 10, 2020
2 parents aeae9ae + 4068db3 commit 074876a
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 8 deletions.
1 change: 1 addition & 0 deletions @woke/app/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react';
// TODO unecessary import for build - bloat
import DesignRoot from './containers/design/root'

//const Root = LogicRoot;
const Root = DesignRoot;
//const Root = (process.env.REACT_APP_DEV_MODE == 'design') ? DesignRoot : LogicRoot;

Expand Down
65 changes: 65 additions & 0 deletions @woke/app/src/components/progress/linear-continuous.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React, { useState, useEffect } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import LinearProgress from '@material-ui/core/LinearProgress';
import { setSyncTimeout } from '../../lib/utils';

import BodyLarge from '../text/body-large';
import BodyStandard from '../text/body-standard';

const useStyles = makeStyles({
wrapper: styles => ({
width: '100%',
maxHeight: '2vh',
flexGrow: 1,
...styles,
}),

bar: {
height: '0.5vh',
width: '100%',
},
});

function randSign() {
return Math.random() > 0.5 ? 1 : -1;
}

// TODO add weights to stageList
export default function ContinuousProgress({value, endValue, ...props}) {
const defaults = { step: 1 };
const { step, styles, organic } = { ...defaults, ...props};
const [completed, setCompleted] = useState(0);
const classes = useStyles(styles);

//const increment = Math.ceil(endValue * (step / 100));

useEffect(() => {
async function progress() {
let diff = (value == endValue) ? 100 : (value / endValue) * 100;
// @brokenwindow this does not take into acount the timing of the input
// value
if(organic) {
const rand = 5 * Math.random();
diff += randSign() * rand;
await setSyncTimeout(rand * 500);
}
setCompleted(prev => {
if (prev === 100) {
return 0;
}
return Math.min(diff, 100);
});
}

progress()

}, [value]);

return (
<>
<div className={classes.wrapper}>
<LinearProgress className={classes.bar} variant="determinate" value={completed} />
</div>
</>
);
}
1 change: 0 additions & 1 deletion @woke/app/src/containers/views/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ export default function WalletView (props) {
);

const makePendingTransfers = () => {
console.log(sendTransfers.currentTransfer);
return [{
type: 'send',
counterParty: sendTransfers.currentTransfer.recipient,
Expand Down
14 changes: 12 additions & 2 deletions @woke/app/src/hooks/mocks/sendtransfer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React, { useState, useEffect, useReducer } from 'react'
import useTxTimer from '../woke-contracts/tx-timer';

export default function useSendTransfer (users) {
const [recipient, setRecipient] = useState(null);
const [recipient, setRecipient] = useState(users[1]);
const [txHash, setTxHash] = useState(null);
const [currentTransfer, setCurrentTransfer] = useState({
recipient: null, amount: null, txHash: null,
});
Expand All @@ -13,6 +15,8 @@ export default function useSendTransfer (users) {
amount: 1,
});

const txTimer = useTxTimer(15000, {steps: 8});

// Transfer input
const handleChangeInput = name => value => {
value && setInput({ ...input, [name]: value });
Expand All @@ -24,6 +28,7 @@ export default function useSendTransfer (users) {
newRecipient ? resolve(newRecipient) : resolve(false);
});


const handleSelectRecipient = () => {
setError(null);
console.log('handleSelectRecipient() ', input.screen_name);
Expand All @@ -42,15 +47,18 @@ export default function useSendTransfer (users) {

const handleSubmitTransfer = () => {
//setRecipient(null);
txTimer.start();
setPending(true);
setTxHash('0xRANDOM');
setCurrentTransfer({
recipient,
amount: input.amount,
txHash: null,
});
setTimeout(() => {
setPending(false);
}, 5000);
txTimer.stop();
}, 20000);
}

const handleClearRecipient = () => {
Expand All @@ -67,6 +75,8 @@ export default function useSendTransfer (users) {
recipient,
currentTransfer: currentTransfer,
amount: input.amount,
timer: txTimer,
txHash: txHash,
error,
};
}
13 changes: 12 additions & 1 deletion @woke/app/src/hooks/woke-contracts/sendtransfer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState, useEffect, useReducer, useRef } from 'react'
import { useWeb3Context } from '../web3context';
import { safePriceEstimate } from '../../lib/web3/web3-utils'
import useTxTimer from './tx-timer';


// User friendly send transfer with user ID checking
Expand Down Expand Up @@ -79,7 +80,8 @@ export default function useSendTransferInput({
txHash: sendTransfers.txHash,
currentTransfer: sendTransfers.currentTransfer,
pending: sendTransfers.pending,
error
timer: sendTransfers.timer,
error,
};
}

Expand Down Expand Up @@ -109,6 +111,9 @@ export function useSendTransfers (recipient, handleClearRecipient) {
recipient ? recipient.id : ''
);

// @TODO get time estimate from config
const txTimer = useTxTimer(18000);

// Update gas estimate when recipient prop changes
const prevRecipient = useRef({id: '', ...recipient});
useEffect(() => {
Expand Down Expand Up @@ -163,6 +168,7 @@ export function useSendTransfers (recipient, handleClearRecipient) {
if(!transferMethod.send('useOpts', transferArgs.userId, transferArgs.amount, safeTxOpts)) {
console.error('... Failed to send transfer');
} else {
txTimer.start();
setCurrentTransfer({
recipient,
amount: transferArgs.amount,
Expand All @@ -186,6 +192,10 @@ export function useSendTransfers (recipient, handleClearRecipient) {

// Update pending transfers
useEffect(() => {
if(!pending) {
txTimer.stop();
}

setCurrentTransfer(t => ({...t, txHash, pending }));
}, [txHash, pending])

Expand All @@ -195,6 +205,7 @@ export function useSendTransfers (recipient, handleClearRecipient) {
txHash,
pending,
currentTransfer,
timer: txTimer,
};
}

Expand Down
35 changes: 35 additions & 0 deletions @woke/app/src/hooks/woke-contracts/tx-timer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { useState, useEffect } from 'react'

const averageBlockTime = 15000;
export default function useTxTimer(time = averageBlockTime, opts) {
const defaults = { steps: 8 };
const { steps } = {...defaults, ...opts};
const [timer, setTimer] = React.useState(null);
const [timerVal, setTimerVal] = React.useState(0);

// TODO allow providing a callback on timer completion. e.g. indicating a tx
// is taking too long.

const start = () => {
console.log('Start tx timer');
setTimerVal(0);
const inc = time / steps;
setTimer(() => setInterval(
() => setTimerVal(t => {
if(t >= time) {
setTimer(timer => clearInterval(timer));
return time;
}
return t + inc;
}), inc));
}

const stop = () => setTimer(timer => clearInterval(timer));

return {
start,
stop,
value: timerVal,
transferTime: time,
}
}
24 changes: 20 additions & 4 deletions @woke/app/src/layouts/list-transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Icon from '@material-ui/core/Icon';
import FlexRow from './flex-row';
import Avatar from './avatar';
import Spinner from '../components/progress/spinner-indeterminate';
import ProgressBar from '../components/progress/linear-continuous';
import TransactionAmount from '../components/text/transaction-amount';
import StandardBody from '../components/text/body-standard';
import WokeSpan from '../components/text/span-woke';
Expand Down Expand Up @@ -47,7 +48,7 @@ const useStyles = makeStyles(theme => ({
minHeight: theme.spacing(5),
//height: '8vh',
paddingRight: theme.spacing(1),
paddingLeft: '2%', // theme.spacing(1),
paddingLeft: '0', // theme.spacing(1),
paddingTop: theme.spacing(0.5),
paddingBottom: theme.spacing(0.5),
marginBottom: '2%',
Expand Down Expand Up @@ -112,8 +113,26 @@ export default function TransactionList ({ listItems, ...props }) {
false;
}

const renderProgress = () => {
if(sendTransfers) {
return (
<ProgressBar organic
value={sendTransfers.timer.value}
endValue={sendTransfers.timer.transferTime}
styles={{
position: 'absolute',
bottom: '0',
left: '0',
paddingTop: '2vh',
}}
/>
);
}
}

const renderTransactions = () => listItems.map((tx, i) => (
<ListItem key={i} alignItems='flex-start' className={classes.listItem}>
{ (tx.pending || isCurrentTransaction(i, tx)) && renderProgress() }
<div className={classes.handleLabel}>
<ListItemAvatar className={classes.avatarItem}>
<Avatar
Expand Down Expand Up @@ -147,9 +166,6 @@ export default function TransactionList ({ listItems, ...props }) {
secondaryTypographyProps={timeSinceProps}
/>
</div>
<FlexRow styles={{alignItems: 'flex-start', justifyContent: 'center'}}>
{ (tx.pending || isCurrentTransaction(i, tx)) && <Spinner/> }
</FlexRow>
<ListItemSecondaryAction>
<TransactionAmount type={tx.type} amount={tx.amount || tx.returnValues.amount}/>
</ListItemSecondaryAction>
Expand Down

0 comments on commit 074876a

Please sign in to comment.