import React, { useCallback, useMemo, useEffect, useState } from 'react'; import { Grid, Text, P, LinkButton } from 'indigo-react'; import * as azimuth from 'azimuth-js'; import { useNetwork } from 'store/network'; import { usePointCursor } from 'store/pointCursor'; import * as need from 'lib/need'; import useEthereumTransaction from 'lib/useEthereumTransaction'; import { GAS_LIMITS } from 'lib/constants'; import { useLocalRouter } from 'lib/LocalRouter'; import ViewHeader from 'components/ViewHeader'; import InlineEthereumTransaction from 'components/InlineEthereumTransaction'; import View from 'components/View'; import BridgeForm from 'form/BridgeForm'; import convertToInt from 'lib/convertToInt'; function useCastUpgradeVote() { const { contracts } = useNetwork(); const { pointCursor } = usePointCursor(); const _contracts = need.contracts(contracts); const _point = need.point(pointCursor); return useEthereumTransaction( useCallback( (address, accept) => { return azimuth.ecliptic.castUpgradeVote( _contracts, _point, address, accept ); }, [_contracts, _point] ), useCallback(() => null, []), //TODO update polls[address].hasVoted ? GAS_LIMITS.DEFAULT //TODO update once we have a decent sample size ); } export default function Upgrades() { const { pop } = useLocalRouter(); const { contracts } = useNetwork(); const { pointCursor } = usePointCursor(); const _contracts = need.contracts(contracts); const _point = convertToInt(need.point(pointCursor), 10); const { construct, reset, unconstruct, bind } = useCastUpgradeVote(); const [proposals, setProposals] = useState([]); const [polls, setPolls] = useState({}); const [loading, setLoading] = useState(true); const [votingOn, setVotingOn] = useState({}); //TODO update every second? const now = Math.round(new Date().getTime() / 1000); useEffect(() => { (async () => { let proposals = await azimuth.polls.getUpgradeProposals(_contracts); let polls = {}; for (let address of proposals) { let poll = await azimuth.polls.getUpgradePoll(_contracts, address); poll.endTime = convertToInt(poll.start) + convertToInt(poll.duration); poll.hasVoted = await azimuth.polls.hasVotedOnUpgradePoll( _contracts, _point, address ); polls[address] = poll; } setProposals(proposals); setPolls(polls); setLoading(false); })(); }, [_contracts, _point]); // eslint-disable-next-line const [open, closed] = useMemo(() => { let open = []; let closed = []; if (loading) return [open, closed]; for (let address of proposals) { if (now > polls[address].endTime) { closed.push(address); } else { open.push(address); } } return [open, closed]; }, [loading, proposals, polls, now]); const doVote = useCallback( (address, accept) => { construct(address, accept); setVotingOn({ address, accept }); }, [construct] ); const didVote = useCallback(() => { reset(); unconstruct(); setPolls(polls => { polls[votingOn.address].hasVoted = true; return polls; }); setVotingOn({}); }, [votingOn, reset, unconstruct]); const openList = useMemo(() => { return open.map(address => { const hasVoted = polls[address].hasVoted; return ( <> {address}↗

{hasVoted ? ( 'Your vote has been cast.' ) : ( <> doVote(address, true)}> {votingOn.address === address && votingOn.accept ? ( support ) : ( <>support )} {' / '} doVote(address, false)}> {votingOn.address === address && !votingOn.accept ? ( reject ) : ( <>reject )} )}

); }); }, [open, polls, votingOn, doVote]); return ( Senate: Upgrade Proposals Current Ecliptic: {_contracts.ecliptic.address} {openList.length > 0 && ( <> Open upgrade polls: {openList} {({ onSubmit, values }) => ( )} )} ); }