Load last poll, handling browser refresh, result button in init screen

This commit is contained in:
Richard Ramos 2018-10-20 21:37:32 -04:00
parent 71835d6ecf
commit 4c962687f5
10 changed files with 96 additions and 76 deletions

View File

@ -58,14 +58,14 @@ class Voting extends PureComponent {
<div id="votingDapp">
<Switch>
<Route exact path="/" render={() => <TitleScreen polls={rawPolls} />} />
<Route path="/learn" render={() => <LearnAboutBallots polls={rawPolls} />} />
<Route path="/votingHelp" render={HowVotingWorks} />
<Route path="/wallet" render={() => <ConnectYourWallet polls={rawPolls} updateBalances={this.updatePollBalance} />} />
<Route path="/otherWallets" render={OtherWallets} />
<Route path="/votingCredits" render={() => <VotingCredits polls={rawPolls} balances={pollTokenBalances} />} />
<Route path="/voting" render={() => <PollVoting polls={rawPolls} balances={pollTokenBalances} originalVotes={votes} setVotesToReview={this.setVotesToReview} />} />
<Route path="/review" render={() => <ReviewVotes polls={rawPolls} votes={votes} balances={pollTokenBalances} setTransactionPromise={this.setTransactionPromise} />} />
<Route path="/results" render={() => <Results polls={rawPolls} transaction={transaction} />} />
<Route path="/learn/:id" render={props => <LearnAboutBallots polls={rawPolls} idPoll={props.match.params.id} />} />
<Route path="/votingHelp/:id" render={props => <HowVotingWorks idPoll={props.match.params.id} />} />
<Route path="/wallet/:id" render={props => <ConnectYourWallet polls={rawPolls} idPoll={props.match.params.id} updateBalances={this.updatePollBalance} />} />
<Route path="/otherWallets/:id" render={props => <OtherWallets idPoll={props.match.params.id} />} />
<Route path="/votingCredits/:id" render={props => <VotingCredits polls={rawPolls} idPoll={props.match.params.id} balances={pollTokenBalances} />} />
<Route path="/voting/:id" render={props => <PollVoting polls={rawPolls} idPoll={props.match.params.id} balances={pollTokenBalances} originalVotes={votes} setVotesToReview={this.setVotesToReview} />} />
<Route path="/review/:id" render={props => <ReviewVotes polls={rawPolls} idPoll={props.match.params.id} votes={votes} balances={pollTokenBalances} setTransactionPromise={this.setTransactionPromise} />} />
<Route path="/results/:id" render={props => <Results polls={rawPolls} idPoll={props.match.params.id} transaction={transaction} />} />
</Switch>
</div>
</div>

View File

@ -8,14 +8,12 @@ import PollManager from 'Embark/contracts/PollManager';
class ConnectYourWallet extends Component {
connectWallet = async () => {
const {history, polls, updateBalances} = this.props;
const {history, polls, updateBalances, idPoll} = this.props;
// TODO:
web3.currentProvider.isStatus = true;
const poll = polls[0];
const idPoll = 0;
const poll = polls[idPoll];
const tknVotes = await PollManager.methods.getVote(idPoll, web3.eth.defaultAccount).call();
const votes = tknVotes.map(x => Math.sqrt(parseInt(web3.utils.fromWei(x, "ether"))));
@ -26,14 +24,16 @@ class ConnectYourWallet extends Component {
if(web3.currentProvider.isStatus){
const tokenBalance = await SNT.methods.balanceOfAt(web3.eth.defaultAccount, poll._startBlock).call();
const ethBalance = await web3.eth.getBalance(web3.eth.defaultAccount);
updateBalances(0, tokenBalance, ethBalance, votes);
history.push('/votingCredits');
updateBalances(idPoll, tokenBalance, ethBalance, votes);
history.push('/votingCredits/' + idPoll);
} else {
window.location.href = "https://get.status.im/browse/" + location.href.replace(/^http(s?):\/\//, '');
}
}
render(){
const {idPoll} = this.props;
return <div className="section center">
<Typography variant="headline">Connect your wallet</Typography>
<Typography variant="body1">To start voting, connect to a wallet where you hold your SNT assets.</Typography>
@ -41,7 +41,7 @@ class ConnectYourWallet extends Component {
<Button color="primary" onClick={this.connectWallet} variant="contained">CONNECT USING STATUS</Button>
</div>
<div className="action">
<Link to="/otherWallets">
<Link to={"/otherWallets/" + idPoll}>
<Button color="primary">CONNECT WITH ANOTHER WALLET</Button>
</Link>
</div>

View File

@ -54,7 +54,7 @@ const HowVotingWorks = (props) => <Fragment><div className="section">
</Card>
</div>
<div className="buttonNav">
<Link to="/wallet"><Button>Connect with your wallet</Button></Link>
<Link to={"/wallet/" + props.idPoll}><Button>Connect with your wallet</Button></Link>
</div>
</Fragment>;

View File

@ -30,13 +30,12 @@ class LearnAboutBallots extends Component {
};
render(){
const {polls} = this.props;
const {polls, idPoll} = this.props;
let title, ballots = [];
if(polls && polls.length){
title = polls[0].content.title;
ballots = polls[0].content.ballots;
}
if(!polls || !polls.length) return null;
const title = polls[idPoll].content.title;
const ballots = polls[idPoll].content.ballots;
return (<Fragment>
<div className="section">
@ -62,7 +61,7 @@ class LearnAboutBallots extends Component {
}
</div>
<div className="buttonNav">
<Link to="/votingHelp"><Button className="nextAction">How voting works</Button></Link>
<Link to={"/votingHelp/" + idPoll}><Button className="nextAction">How voting works</Button></Link>
</div>
</Fragment>
);

View File

@ -1,11 +1,11 @@
import {Link} from "react-router-dom";
import Button from '@material-ui/core/Button';
import React from 'react';
import React, {Fragment} from 'react';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import Typography from '@material-ui/core/Typography';
const OtherWallets = (props) => <div className="section">
const OtherWallets = (props) => <Fragment><div className="section">
<Typography variant="headline">Connect with another wallet</Typography>
<Typography variant="body1">Do you hold your SNT in another wallet? Don't worry, we've got you covered. You can also vote using the following wallets.</Typography>
<Card className="card">
@ -41,7 +41,10 @@ const OtherWallets = (props) => <div className="section">
</Typography>
</CardContent>
</Card>
<Link to="/wallet"><Button variant="text">Back</Button></Link>
</div>
<div className="buttonNav back">
<Link to={"/wallet/" + props.idPoll}><Button variant="text">Back</Button></Link>
</div>
</Fragment>
export default OtherWallets;

View File

@ -44,13 +44,14 @@ class PollVoting extends Component {
}
componentDidMount(){
const {polls, originalVotes} = this.props;
const {polls, originalVotes, idPoll, history} = this.props;
if(!polls || !polls.length){
this.props.history.push('/');
history.push('/');
return;
}
const poll = polls[0];
const poll = polls[idPoll];
const votes = [];
if(originalVotes.length){
@ -73,11 +74,11 @@ class PollVoting extends Component {
sendToReview = () => {
this.props.setVotesToReview(this.state.votes);
this.props.history.push('/review');
this.props.history.push('/review/' + this.props.idPoll);
}
render(){
const {polls, classes, balances} = this.props;
const {polls, classes, balances, idPoll} = this.props;
const {originalVotes, votes} = this.state;
const {fromWei} = web3.utils;
@ -87,15 +88,15 @@ class PollVoting extends Component {
const symbol = "SNT"; // TODO:
const poll = polls[0];
const poll = polls[idPoll];
const title = poll.content.title;
const ballots = poll.content.ballots
const balance = fromWei(balances[0].tokenBalance, "ether");
const balance = fromWei(balances[idPoll].tokenBalance, "ether");
const cantVote = balance == 0 || !poll._canVote;
const availableCredits = parseInt(balance, 10) - votes.reduce((prev, curr) => prev + curr * curr, 0);
const disableVote = cantVote || availableCredits == parseInt(balance, 10) || arraysEqual(votes, originalVotes.slice(0, votes.length));
const disableVote = cantVote || availableCredits == parseInt(balance, 10);
// Votes calculation
const originalVotesQty = originalVotes.reduce((x,y) => x+y, 0);

View File

@ -15,23 +15,23 @@ class Results extends Component {
super(props);
if(props.polls && props.polls.length)
this.state.poll = props.polls[0]; // TODO:
this.state.poll = props.polls[props.idPoll];
}
updatePoll(){
const idPoll = 0; // TODO:
const idPoll = this.props.idPoll;
PollManager.methods.poll(idPoll).call().then(poll => {
this.setState({poll});
})
}
componentDidMount(){
const {transaction} = this.props;
const idPoll = 0; // TODO:
const {transaction, idPoll} = this.props;
EmbarkJS.onReady(() => {
this.updatePoll();
if(transaction){
transaction.then(receipt => {
this.updatePoll();
})
@ -39,24 +39,27 @@ class Results extends Component {
this.setState({isError: true});
});
}
});
}
render(){
const {polls} = this.props;
const {polls, idPoll} = this.props;
let {isError, poll} = this.state;
const title = polls[0].content.title;
const ballots = polls[0].content.ballots;
if(!poll){
if(!poll || !polls){
return null;
}
const title = polls[idPoll].content.title;
const ballots = polls[idPoll].content.ballots;
return <div className="section">
{ isError && <div className="errorTrx">
<div className="image"><img src="images/sad-face.svg" width="24" /></div>
<Typography variant="headline">Transaction failed</Typography>
<Typography variant="body1">Copy with apologies and invitation to try again</Typography>
<Link to="/review">
<Link to={"/review/" + idPoll}>
<Button color="primary" variant="contained">Try again</Button>
</Link>
</div> }

View File

@ -16,11 +16,9 @@ class ReviewVotes extends Component {
this.setState({isSubmitting: true});
const { vote, unvote } = PollManager.methods;
const { polls, votes, history} = this.props;
const { votes, history, idPoll} = this.props;
const { toWei, toBN } = web3.utils;
const idPoll = 0; // TODO:
const ballots = votes.map(el => {
let num = toBN(el);
num = num.mul(num);
@ -36,22 +34,31 @@ class ReviewVotes extends Component {
console.log("voting gas estimated: " + gasEstimated);
const transaction = toSend.send({gas: gasEstimated + 100000});
this.props.setTransactionPromise(transaction);
history.push('/results');
history.push('/results/' + idPoll);
});
}
componentDidMount(){
const {polls, originalVotes, idPoll, history} = this.props;
if(!polls || !polls.length){
history.push('/');
return;
}
}
render(){
const {polls, balances, votes} = this.props;
const {polls, balances, votes, idPoll} = this.props;
const {isSubmitting} = this.state;
const {fromWei} = web3.utils;
if(!polls || !polls.length){
if(!polls || !polls.length || !balances[idPoll]){
return null;
}
const poll = polls[0];
const poll = polls[idPoll];
const ballots = poll.content.ballots
const balance = fromWei(balances[0].tokenBalance, "ether");
const balance = fromWei(balances[idPoll].tokenBalance, "ether");
const availableCredits = parseInt(balance, 10) - votes.reduce((prev, curr) => prev + curr * curr, 0);
return (polls ? <Fragment><div className="section">
@ -80,7 +87,7 @@ class ReviewVotes extends Component {
<CardContent>
<Typography gutterBottom component="p">Unused voting power</Typography>
<Typography gutterBottom component="h2">{availableCredits} credits</Typography>
<Link to="/voting"><Button variant="text">Add votes</Button></Link>
<Link to={"/voting/" + idPoll}><Button variant="text">Add votes</Button></Link>
</CardContent>
</Card>
</div>

View File

@ -57,7 +57,8 @@ class TitleScreen extends Component {
componentDidUpdate(prevProps){
if (this.props.polls !== prevProps.polls && this.props.polls && this.props.polls.length) {
const seconds = this.props.polls[0]._endTime - (new Date()).getTime() / 1000
const idPoll = this.props.polls[this.props.polls.length - 1].idPoll;
const seconds = this.props.polls[idPoll]._endTime - (new Date()).getTime() / 1000
if(seconds > 0){
let timeLeftVar = this.secondsToTime(seconds);
this.setState({ time: timeLeftVar, seconds });
@ -75,12 +76,18 @@ class TitleScreen extends Component {
let startBlock, endTime, title, description;
let idPoll;
if(polls && polls.length){
title = polls[0].content.title;
description = polls[0].content.description;
canceled = polls[0]._canceled;
startBlock = polls[0]._startBlock;
endTime = polls[0]._endTime;
idPoll = polls[polls.length - 1].idPoll;
title = polls[idPoll].content.title;
description = polls[idPoll].content.description;
canceled = polls[idPoll]._canceled;
startBlock = polls[idPoll]._startBlock;
endTime = polls[idPoll]._endTime;
}
return (polls && !canceled ? <div>
@ -107,14 +114,14 @@ class TitleScreen extends Component {
</li>
</ul>
<div className="action">
<Link to="/learn"><Button variant="contained" color="primary">Get started</Button></Link>
<Link to={"/learn/" + idPoll}><Button variant="contained" color="primary">Get started</Button></Link>
</div>
</div>}
{ seconds < 0 && <div className="pollClosed">
<Typography variant="headline">Poll closed</Typography>
<Typography variant="body1">The vote was finished {parseInt(Math.abs(seconds) / 86400, 10)} day(s) ago</Typography>
<div className="action">
<Link to="/learn"><Button variant="contained" color="primary">View results</Button></Link>
<Link to={"/results/" + idPoll}><Button variant="contained" color="primary">View results</Button></Link>
</div>
</div> }
</div> : null);

View File

@ -16,14 +16,14 @@ class VotingCredits extends Component {
}
render(){
const {polls, balances, history} = this.props;
const {polls, balances, idPoll} = this.props;
if(!polls || !balances) return null;
let title = polls[0].content.title;
let description = polls[0].content.description;
let ethBalance = web3.utils.fromWei(balances[0].ethBalance, "ether");
let tokenBalance = Math.floor(web3.utils.fromWei(balances[0].tokenBalance, "ether"));
let title = polls[idPoll].content.title;
let description = polls[idPoll].content.description;
let ethBalance = web3.utils.fromWei(balances[idPoll].ethBalance, "ether");
let tokenBalance = Math.floor(web3.utils.fromWei(balances[idPoll].tokenBalance, "ether"));
return (polls ? <Fragment><div className="section">
<Typography variant="headline">{title}</Typography>
@ -68,8 +68,8 @@ class VotingCredits extends Component {
</Card> }
</div>
<div className={(ethBalance == 0 || tokenBalance == 0) ? 'buttonNav back' : 'buttonNav'}>
{ (ethBalance == 0 || tokenBalance == 0) && <Link to="/wallet"><Button variant="text">Back</Button></Link> }
{ (ethBalance > 0 && tokenBalance > 0) && <Link to="/voting"><Button variant="text">Vote</Button></Link> }
{ (ethBalance == 0 || tokenBalance == 0) && <Link to={"/wallet/" + idPoll}><Button variant="text">Back</Button></Link> }
{ (ethBalance > 0 && tokenBalance > 0) && <Link to={"/voting/" + idPoll}><Button variant="text">Vote</Button></Link> }
</div>
</Fragment> : null);
}