Added landing page and lazy loading of IPFS text

This commit is contained in:
Richard Ramos 2018-11-28 14:51:10 -04:00
parent f7b1b0084e
commit 0aba085ed7
12 changed files with 152 additions and 29 deletions

View File

@ -18,6 +18,7 @@ import VotingCredits from './flow/VotingCredits';
import PollVoting from './flow/PollVoting'; import PollVoting from './flow/PollVoting';
import ReviewVotes from './flow/ReviewVotes'; import ReviewVotes from './flow/ReviewVotes';
import Results from './flow/Results'; import Results from './flow/Results';
import LandingPage from './flow/LandingPage';
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
@ -54,13 +55,14 @@ class Voting extends PureComponent {
return ( return (
<VotingContext.Consumer> <VotingContext.Consumer>
{({ getPolls, rawPolls, loading, symbol }) => {({ getPolls, rawPolls, loading, symbol, replacePoll, loadPollContent }) =>
<div> <div>
<CssBaseline /> <CssBaseline />
{loading && <LinearProgress />} {loading && <LinearProgress />}
<div id="votingDapp"> <div id="votingDapp">
<Switch> <Switch>
<Route exact path="/" render={props => <TitleScreen polls={rawPolls} />} /> <Route exact path="/" render={props => <LandingPage polls={rawPolls} replacePoll={replacePoll} />} />
<Route path="/titleScreen/:id" render={props => <TitleScreen polls={rawPolls} idPoll={props.match.params.id} loadPollContent={loadPollContent} />} />
<Route path="/learn/:id" render={props => <LearnAboutBallots polls={rawPolls} idPoll={props.match.params.id} />} /> <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} polls={rawPolls} updateBalances={this.updatePollBalance} />} /> <Route path="/votingHelp/:id" render={props => <HowVotingWorks idPoll={props.match.params.id} polls={rawPolls} updateBalances={this.updatePollBalance} />} />
<Route path="/wallet/:id" render={props => <ConnectYourWallet polls={rawPolls} idPoll={props.match.params.id} updateBalances={this.updatePollBalance} />} /> <Route path="/wallet/:id" render={props => <ConnectYourWallet polls={rawPolls} idPoll={props.match.params.id} updateBalances={this.updatePollBalance} />} />

View File

@ -19,7 +19,7 @@ class ExternalWallet extends Component {
const {history, polls, updateBalances, idPoll} = this.props; const {history, polls, updateBalances, idPoll} = this.props;
if(!polls) return; if(!polls) return;
const poll = polls[idPoll]; const poll = polls.find(p => p.idPoll == idPoll);
if(!poll) return null; if(!poll) return null;

View File

@ -52,7 +52,7 @@ class HowVotingWorks extends Component {
if(cont){ if(cont){
// TODO: extract this code to utils. It's repeated in ConnectYourWallt, ExternalWallet and HowVotingWorks // TODO: extract this code to utils. It's repeated in ConnectYourWallt, ExternalWallet and HowVotingWorks
const poll = polls[idPoll]; const poll = polls.find(p => p.idPoll == idPoll);
if(!poll) return null; if(!poll) return null;
const tknVotes = await PollManager.methods.getVote(idPoll, web3.eth.defaultAccount).call({from: web3.eth.defaultAccount}); const tknVotes = await PollManager.methods.getVote(idPoll, web3.eth.defaultAccount).call({from: web3.eth.defaultAccount});

View File

@ -0,0 +1,89 @@
import Button from '@material-ui/core/Button';
import React, {Component, Fragment} from 'react';
import Typography from '@material-ui/core/Typography';
import { withRouter } from 'react-router-dom'
import {Link} from "react-router-dom";
class LandingPage extends Component {
state = {
openPoll: null,
closedPoll: null
}
componentDidUpdate(prevProps) {
if (this.props.polls !== prevProps.polls) {
let polls = this.props.polls;
if(polls && polls.length){
polls = polls.sort((x,y) => x.idPoll < y.idPoll);
}
if(polls && polls.length){
const openPoll = polls.find(x => !x._cancelled && x._endTime > (new Date()).getTime() / 1000);
EmbarkJS.Storage.get(web3.utils.toAscii(openPoll._description)).then(content => {
openPoll.content = JSON.parse(content);
this.setState({openPoll})
this.props.replacePoll(openPoll);
})
const closedPoll = polls.find(x => !x._cancelled || x._endTime < (new Date()).getTime() / 1000);
EmbarkJS.Storage.get(web3.utils.toAscii(closedPoll._description)).then(content => {
closedPoll.content = JSON.parse(content);
this.setState({closedPoll});
this.props.replacePoll(openPoll);
})
}
}
}
render(){
const { openPoll, closedPoll } = this.state;
return <Fragment>
<div>
<div className="section" style={{marginBottom: 0}}>
<img src="images/status-logo.svg" width="36" />
<Typography variant="headline">Status SNT Voting</Typography>
<Typography variant="body1" component="div">Create a poll or vote in one. Your vote helps us decide our product and community direction.</Typography>
</div>
{ openPoll && openPoll.content &&
<div>
<h2>Open Polls</h2>
<div>
<h3>{openPoll.content.title}</h3>
[Closes: 12/12/2018]
Voters: 300
Total SNT: 50.000
{openPoll._description}
<Link to={"/titleScreen/" + openPoll.idPoll}><Button variant="contained" color="primary">Vote now</Button></Link>
</div>
<p>More Open Polls</p>
</div>
}
{ closedPoll && closedPoll.content &&
<div>
<h2>Closed Polls</h2>
<div>
<h3>{closedPoll.content.title}</h3>
[Closes: 12/12/2018]
Voters: 300
Total SNT: 50.000
{closedPoll._description}
Vote Now
</div>
<p>More Closed Polls</p>
</div>
}
</div>
</Fragment>;
}
}
export default LandingPage;

View File

@ -34,7 +34,7 @@ class LearnAboutBallots extends Component {
if(!polls) return null; if(!polls) return null;
const poll = polls[idPoll]; const poll = polls.find(p => p.idPoll == idPoll);
if(!poll) return null; if(!poll) return null;
const title = poll.content.title; const title = poll.content.title;

View File

@ -54,7 +54,9 @@ class OtherWallets extends Component {
if(!props.polls){ if(!props.polls){
return null; return null;
} }
const poll = props.polls[props.idPoll];
const poll = props.polls.find(p => p.idPoll == props.idPoll);
if(!poll) return null; if(!poll) return null;
d = new Date(poll.blockInfo.timestamp * 1000); d = new Date(poll.blockInfo.timestamp * 1000);

View File

@ -59,7 +59,7 @@ class PollVoting extends Component {
return; return;
} }
const poll = polls[idPoll]; const poll = polls.find(p => p.idPoll == idPoll);
if(!poll){ if(!poll){
history.push('/'); history.push('/');
return; return;
@ -112,7 +112,7 @@ class PollVoting extends Component {
const symbol = "SNT"; // TODO: const symbol = "SNT"; // TODO:
const poll = polls[idPoll]; const poll = polls.find(p => p.idPoll == idPoll);
if(!poll) return null; if(!poll) return null;
const title = poll.content.title; const title = poll.content.title;

View File

@ -18,7 +18,7 @@ class Results extends Component {
super(props); super(props);
if(props.polls) if(props.polls)
this.state.poll = props.polls[props.idPoll]; this.state.poll = props.polls.find(p => p.idPoll == props.idPoll);
} }
componentDidUpdate(prevProps){ componentDidUpdate(prevProps){
@ -84,8 +84,10 @@ class Results extends Component {
return null; return null;
} }
const title = polls[idPoll].content.title; const p = polls.find(p => p.idPoll == idPoll);
const ballots = polls[idPoll].content.ballots;
const title = p.content.title;
const ballots = p.content.ballots;
const totalVotes = poll._quadraticVotes.map(x => parseInt(x, 10)).reduce((x, y) => x + y, 0); const totalVotes = poll._quadraticVotes.map(x => parseInt(x, 10)).reduce((x, y) => x + y, 0);
const etherscanURL = netId == 3 ? 'https://ropsten.etherscan.io/tx/' : ( netId == 1 ? "https://etherscan.io/tx/" : ''); const etherscanURL = netId == 3 ? 'https://ropsten.etherscan.io/tx/' : ( netId == 1 ? "https://etherscan.io/tx/" : '');

View File

@ -66,7 +66,7 @@ class ReviewVotes extends Component {
return; return;
} }
const poll = polls[idPoll]; const poll = polls.find(p => p.idPoll == idPoll);
if(!poll) { if(!poll) {
history.push('/'); history.push('/');
return; return;
@ -82,7 +82,7 @@ class ReviewVotes extends Component {
return null; return null;
} }
const poll = polls[idPoll]; const poll = polls.find(p => p.idPoll == idPoll);;
if(!poll) return null; if(!poll) return null;
const ballots = poll.content.ballots const ballots = poll.content.ballots

View File

@ -65,20 +65,24 @@ class TitleScreen extends Component {
componentDidUpdate(prevProps){ componentDidUpdate(prevProps){
if (this.props.polls !== prevProps.polls && this.props.polls) { if (this.props.polls !== prevProps.polls && this.props.polls) {
this.initTimer(); this.initTimer();
const poll = this.props.polls.find(p => p.idPoll == this.props.idPoll);
if(poll && !poll.content){
this.props.loadPollContent(poll);
}
} }
} }
initTimer(){ initTimer(){
const ids = Object.keys(this.props.polls); if(!this.props.polls || !this.props.polls.length) return;
if(!ids.length) return;
if(this.state.initTimer) return; if(this.state.initTimer) return;
this.setState({initTimer: true}); this.setState({initTimer: true});
const idPoll = ids[ids.length - 1]; const poll = this.props.polls.find(p => p.idPoll == this.props.idPoll);
const seconds = this.props.polls[idPoll]._endTime - (new Date()).getTime() / 1000 const seconds = poll._endTime - (new Date()).getTime() / 1000
if(seconds > 0){ if(seconds > 0){
let timeLeftVar = this.secondsToTime(seconds); let timeLeftVar = this.secondsToTime(seconds);
this.setState({ time: timeLeftVar, seconds }); this.setState({ time: timeLeftVar, seconds });
@ -90,19 +94,19 @@ class TitleScreen extends Component {
render(){ render(){
const {time, seconds} = this.state; const {time, seconds} = this.state;
const {polls} = this.props; const {polls, idPoll} = this.props;
if(!polls) return null; if(!polls || !polls.length) return null;
const ids = Object.keys(this.props.polls);
if(!ids.length) return null;
const idPoll = ids[ids.length - 1]; const poll = polls.find(p => p.idPoll == idPoll);
const poll = polls[idPoll]; if(!poll) return null;
if(!poll.content) return null;
const title = poll.content.title; const title = poll.content.title;
const description = poll.content.description; const description = poll.content.description;
const canceled = poll._canceled; const canceled = poll._canceled;
return <Fragment> return <Fragment>
<div> <div>

View File

@ -54,7 +54,7 @@ class VotingCredits extends Component {
if(!polls || !balances) return null; if(!polls || !balances) return null;
const poll = polls[idPoll]; const poll = polls.find(p => p.idPoll == idPoll);
if(!poll) return null; if(!poll) return null;
let title = poll.content.title; let title = poll.content.title;

View File

@ -32,7 +32,7 @@ class App extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
} }
state = { admin: false, pollOrder: 'NEWEST_ADDED', web3Provider: true, loading: true, symbol: "SNT", networkName: "" }; state = { admin: false, pollOrder: 'NEWEST_ADDED', web3Provider: true, loading: true, symbol: "SNT", networkName: "" , rawPolls: []};
componentDidMount(){ componentDidMount(){
EmbarkJS.onReady((err) => { EmbarkJS.onReady((err) => {
@ -91,7 +91,10 @@ class App extends React.Component {
getPolls(polls, poll) getPolls(polls, poll)
.then(omitPolls) .then(omitPolls)
.then(rawPolls => { .then(rawPolls => {
this._loadIPFSContent(rawPolls);
// this._loadIPFSContent(rawPolls);
this.setState({rawPolls, loading: false});
}); });
else else
this.setState({ rawPolls: [], loading: false }); this.setState({ rawPolls: [], loading: false });
@ -134,10 +137,31 @@ class App extends React.Component {
</Fragment>; </Fragment>;
} }
replacePoll = (poll) => {
let rawPolls = this.state.rawPolls;
for(let i = 0; i < rawPolls.length; i++){
if(rawPolls[i].idPoll == poll.idPoll){
rawPolls[i] = poll;
this.setState({rawPolls});
break;
}
}
}
loadPollContent = async (poll) => {
let ipfsContent = await EmbarkJS.Storage.get(web3.utils.toAscii(poll._description));
poll.content = JSON.parse(ipfsContent);
this.replacePoll(poll);
}
render(){ render(){
let { web3Provider, networkName } = this.state; let { web3Provider, networkName } = this.state;
const { _getPolls, updatePoll, setPollOrder, appendToPoll } = this; const { _getPolls, updatePoll, setPollOrder, appendToPoll, replacePoll, loadPollContent } = this;
const votingContext = { getPolls: _getPolls, updatePoll, appendToPoll, setPollOrder, ...this.state }; const votingContext = { getPolls: _getPolls, updatePoll, appendToPoll, setPollOrder, replacePoll, loadPollContent, ...this.state };
console.log(this.state.rawPolls);
if(web3Provider){ if(web3Provider){
return <Router> return <Router>