Refactor VoteProgress (#70)
This commit is contained in:
parent
d1790007c0
commit
98fb2ea515
|
@ -5,6 +5,7 @@ import { Provider } from '@ethersproject/providers'
|
||||||
import { Contract } from '@ethersproject/contracts'
|
import { Contract } from '@ethersproject/contracts'
|
||||||
import { Interface } from '@ethersproject/abi'
|
import { Interface } from '@ethersproject/abi'
|
||||||
import { ERC20 } from '../abi'
|
import { ERC20 } from '../abi'
|
||||||
|
import { createWaku } from '../utils/createWaku'
|
||||||
const ABI = [
|
const ABI = [
|
||||||
'function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)',
|
'function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)',
|
||||||
]
|
]
|
||||||
|
@ -23,7 +24,7 @@ type WakuMessageStores = {
|
||||||
|
|
||||||
export class WakuMessaging {
|
export class WakuMessaging {
|
||||||
protected appName: string
|
protected appName: string
|
||||||
protected waku: Waku
|
protected waku: Waku | undefined
|
||||||
public tokenAddress: string
|
public tokenAddress: string
|
||||||
protected provider: Provider
|
protected provider: Provider
|
||||||
protected chainId = 0
|
protected chainId = 0
|
||||||
|
@ -34,10 +35,10 @@ export class WakuMessaging {
|
||||||
protected constructor(
|
protected constructor(
|
||||||
appName: string,
|
appName: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
waku: Waku,
|
|
||||||
provider: Provider,
|
provider: Provider,
|
||||||
chainId: number,
|
chainId: number,
|
||||||
multicall: string
|
multicall: string,
|
||||||
|
waku?: Waku
|
||||||
) {
|
) {
|
||||||
this.appName = appName
|
this.appName = appName
|
||||||
this.tokenAddress = tokenAddress
|
this.tokenAddress = tokenAddress
|
||||||
|
@ -48,18 +49,19 @@ export class WakuMessaging {
|
||||||
}
|
}
|
||||||
|
|
||||||
public cleanUp() {
|
public cleanUp() {
|
||||||
this.observers.forEach((observer) => this.waku.relay.deleteObserver(observer.callback, observer.topics))
|
this.observers.forEach((observer) => this?.waku?.relay.deleteObserver(observer.callback, observer.topics))
|
||||||
this.wakuMessages = {}
|
this.wakuMessages = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async setObserver() {
|
protected async setObserver() {
|
||||||
|
this.waku = await createWaku(this.waku)
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Object.values(this.wakuMessages).map(async (msgObj) => {
|
Object.values(this.wakuMessages).map(async (msgObj) => {
|
||||||
const storeMessages = await this.waku?.store.queryHistory([msgObj.topic])
|
const storeMessages = await this.waku?.store.queryHistory([msgObj.topic])
|
||||||
if (storeMessages) {
|
if (storeMessages) {
|
||||||
msgObj.updateFunction(storeMessages)
|
msgObj.updateFunction(storeMessages)
|
||||||
}
|
}
|
||||||
this.waku.relay.addObserver((msg) => msgObj.updateFunction([msg]), [msgObj.topic])
|
this?.waku?.relay.addObserver((msg) => msgObj.updateFunction([msg]), [msgObj.topic])
|
||||||
this.observers.push({ callback: (msg) => msgObj.updateFunction([msg]), topics: [msgObj.topic] })
|
this.observers.push({ callback: (msg) => msgObj.updateFunction([msg]), topics: [msgObj.topic] })
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
|
@ -21,12 +21,12 @@ export class WakuPolling extends WakuMessaging {
|
||||||
protected constructor(
|
protected constructor(
|
||||||
appName: string,
|
appName: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
waku: Waku,
|
|
||||||
provider: Provider,
|
provider: Provider,
|
||||||
chainId: number,
|
chainId: number,
|
||||||
multicall: string
|
multicall: string,
|
||||||
|
waku?: Waku
|
||||||
) {
|
) {
|
||||||
super(appName, tokenAddress, waku, provider, chainId, multicall)
|
super(appName, tokenAddress, provider, chainId, multicall, waku)
|
||||||
this.wakuMessages['pollInit'] = {
|
this.wakuMessages['pollInit'] = {
|
||||||
topic: `/${this.appName}/waku-polling/timed-polls-init/proto/`,
|
topic: `/${this.appName}/waku-polling/timed-polls-init/proto/`,
|
||||||
hashMap: {},
|
hashMap: {},
|
||||||
|
@ -59,14 +59,7 @@ export class WakuPolling extends WakuMessaging {
|
||||||
waku?: Waku
|
waku?: Waku
|
||||||
) {
|
) {
|
||||||
const network = await provider.getNetwork()
|
const network = await provider.getNetwork()
|
||||||
const wakuPolling = new WakuPolling(
|
const wakuPolling = new WakuPolling(appName, tokenAddress, provider, network.chainId, multicall, waku)
|
||||||
appName,
|
|
||||||
tokenAddress,
|
|
||||||
await createWaku(waku),
|
|
||||||
provider,
|
|
||||||
network.chainId,
|
|
||||||
multicall
|
|
||||||
)
|
|
||||||
return wakuPolling
|
return wakuPolling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,12 @@ export class WakuVoting extends WakuMessaging {
|
||||||
appName: string,
|
appName: string,
|
||||||
votingContract: Contract,
|
votingContract: Contract,
|
||||||
token: string,
|
token: string,
|
||||||
waku: Waku,
|
|
||||||
provider: Provider,
|
provider: Provider,
|
||||||
chainId: number,
|
chainId: number,
|
||||||
multicallAddress: string
|
multicallAddress: string,
|
||||||
|
waku?: Waku
|
||||||
) {
|
) {
|
||||||
super(appName, token, waku, provider, chainId, multicallAddress)
|
super(appName, token, provider, chainId, multicallAddress, waku)
|
||||||
this.votingContract = votingContract
|
this.votingContract = votingContract
|
||||||
this.wakuMessages['vote'] = {
|
this.wakuMessages['vote'] = {
|
||||||
topic: `/${this.appName}/waku-voting/votes/proto/`,
|
topic: `/${this.appName}/waku-voting/votes/proto/`,
|
||||||
|
@ -38,6 +38,7 @@ export class WakuVoting extends WakuMessaging {
|
||||||
this.wakuMessages['vote']
|
this.wakuMessages['vote']
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
this.setObserver()
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async create(
|
public static async create(
|
||||||
|
@ -50,15 +51,7 @@ export class WakuVoting extends WakuMessaging {
|
||||||
const network = await provider.getNetwork()
|
const network = await provider.getNetwork()
|
||||||
const votingContract = new Contract(contractAddress, VotingContract.abi, provider)
|
const votingContract = new Contract(contractAddress, VotingContract.abi, provider)
|
||||||
const tokenAddress = await votingContract.token()
|
const tokenAddress = await votingContract.token()
|
||||||
return new WakuVoting(
|
return new WakuVoting(appName, votingContract, tokenAddress, provider, network.chainId, multicall, waku)
|
||||||
appName,
|
|
||||||
votingContract,
|
|
||||||
tokenAddress,
|
|
||||||
await createWaku(waku),
|
|
||||||
provider,
|
|
||||||
network.chainId,
|
|
||||||
multicall
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createVote(
|
public async createVote(
|
||||||
|
|
|
@ -19,6 +19,7 @@ export function Proposal({ wakuVoting }: ProposalProps) {
|
||||||
const interval = setInterval(async () => {
|
const interval = setInterval(async () => {
|
||||||
setVotes(await wakuVoting.getVotingRooms())
|
setVotes(await wakuVoting.getVotingRooms())
|
||||||
}, 10000)
|
}, 10000)
|
||||||
|
wakuVoting.getVotingRooms().then((e) => setVotes(e))
|
||||||
return () => clearInterval(interval)
|
return () => clearInterval(interval)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
|
@ -11,16 +11,26 @@ interface ProposalCardProps {
|
||||||
heading: string
|
heading: string
|
||||||
text: string
|
text: string
|
||||||
address: string
|
address: string
|
||||||
|
mobileVersion?: boolean
|
||||||
vote?: number
|
vote?: number
|
||||||
voteWinner?: number
|
voteWinner?: number
|
||||||
hideModalFunction?: (val: boolean) => void
|
hideModalFunction?: (val: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProposalCard({ id, heading, text, address, vote, voteWinner, theme }: ProposalCardProps) {
|
export function ProposalCard({
|
||||||
|
id,
|
||||||
|
heading,
|
||||||
|
text,
|
||||||
|
address,
|
||||||
|
vote,
|
||||||
|
voteWinner,
|
||||||
|
theme,
|
||||||
|
mobileVersion,
|
||||||
|
}: ProposalCardProps) {
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card onClick={() => history.push(`/votingRoom/${id.toString}`)}>
|
<Card onClick={() => mobileVersion && history.push(`/votingRoom/${id.toString}`)}>
|
||||||
<ProposalInfo heading={heading} text={text} address={address} />
|
<ProposalInfo heading={heading} text={text} address={address} />
|
||||||
<ProposalVote vote={vote} voteWinner={voteWinner} address={address} heading={heading} theme={theme} />
|
<ProposalVote vote={vote} voteWinner={voteWinner} address={address} heading={heading} theme={theme} />
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react'
|
import React, { useRef } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { Theme } from '@status-waku-voting/react-components'
|
import { Theme, useMobileVersion } from '@status-waku-voting/react-components'
|
||||||
import { ProposalCard } from './ProposalCard'
|
import { ProposalCard } from './ProposalCard'
|
||||||
import { WakuVoting } from '@status-waku-voting/core'
|
import { WakuVoting } from '@status-waku-voting/core'
|
||||||
import { VotingEmpty } from './VotingEmpty'
|
import { VotingEmpty } from './VotingEmpty'
|
||||||
|
@ -12,8 +12,10 @@ type ProposalListProps = {
|
||||||
votes: VotingRoom[]
|
votes: VotingRoom[]
|
||||||
}
|
}
|
||||||
export function ProposalList({ theme, wakuVoting, votes }: ProposalListProps) {
|
export function ProposalList({ theme, wakuVoting, votes }: ProposalListProps) {
|
||||||
|
const ref = useRef<HTMLHeadingElement>(null)
|
||||||
|
const mobileVersion = useMobileVersion(ref, 600)
|
||||||
return (
|
return (
|
||||||
<List>
|
<List ref={ref}>
|
||||||
{votes.map((vote) => {
|
{votes.map((vote) => {
|
||||||
return (
|
return (
|
||||||
<ProposalCard
|
<ProposalCard
|
||||||
|
@ -23,6 +25,7 @@ export function ProposalList({ theme, wakuVoting, votes }: ProposalListProps) {
|
||||||
theme={theme}
|
theme={theme}
|
||||||
key={vote.id}
|
key={vote.id}
|
||||||
id={vote.id}
|
id={vote.id}
|
||||||
|
mobileVersion={mobileVersion}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { addCommas } from '../helpers/addCommas'
|
import { addCommas } from '../helpers/addCommas'
|
||||||
|
@ -11,36 +11,26 @@ export interface VoteProposingProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function VotePropose({ availableAmount, proposingAmount, setProposingAmount }: VoteProposingProps) {
|
export function VotePropose({ availableAmount, proposingAmount, setProposingAmount }: VoteProposingProps) {
|
||||||
const [displayAmount, setDisplayAmount] = useState(addCommas(proposingAmount) + ' ABC')
|
const [inputFocused, setInputFocused] = useState(false)
|
||||||
const disabled = availableAmount === 0
|
const disabled = useMemo(() => availableAmount === 0, [availableAmount])
|
||||||
|
const step = useMemo(
|
||||||
let step = 10 ** (Math.floor(Math.log10(availableAmount)) - 2)
|
() => (availableAmount < 100 ? 1 : 10 ** (Math.floor(Math.log10(availableAmount)) - 2)),
|
||||||
|
[availableAmount]
|
||||||
if (availableAmount < 100) {
|
)
|
||||||
step = 1
|
const progress = useMemo(() => (proposingAmount / availableAmount) * 100 + '%', [proposingAmount, availableAmount])
|
||||||
}
|
|
||||||
|
|
||||||
const setAvailableAmount = () => {
|
|
||||||
setProposingAmount(availableAmount)
|
|
||||||
setDisplayAmount(addCommas(availableAmount) + ' ABC')
|
|
||||||
}
|
|
||||||
|
|
||||||
const sliderChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const sliderChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
if (Number(e.target.value) == step * Math.floor(availableAmount / step)) {
|
if (Number(e.target.value) == step * Math.floor(availableAmount / step)) {
|
||||||
setAvailableAmount()
|
setProposingAmount(availableAmount)
|
||||||
} else {
|
} else {
|
||||||
setProposingAmount(Number(e.target.value))
|
setProposingAmount(Number(e.target.value))
|
||||||
setDisplayAmount(addCommas(Number(e.target.value)) + ' ABC')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const progress = (proposingAmount / availableAmount) * 100 + '%'
|
|
||||||
|
|
||||||
const onInputAmountBlur = () => {
|
const onInputAmountBlur = () => {
|
||||||
|
setInputFocused(false)
|
||||||
if (proposingAmount > availableAmount) {
|
if (proposingAmount > availableAmount) {
|
||||||
setAvailableAmount()
|
setProposingAmount(availableAmount)
|
||||||
} else {
|
|
||||||
setDisplayAmount(addCommas(proposingAmount) + ' ABC')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,13 +41,12 @@ export function VotePropose({ availableAmount, proposingAmount, setProposingAmou
|
||||||
<span>Available {addCommas(availableAmount)} ABC</span>
|
<span>Available {addCommas(availableAmount)} ABC</span>
|
||||||
</VoteProposingInfo>
|
</VoteProposingInfo>
|
||||||
<VoteProposingAmount
|
<VoteProposingAmount
|
||||||
value={displayAmount}
|
value={inputFocused ? proposingAmount.toString() : addCommas(proposingAmount) + ' ABC'}
|
||||||
onInput={(e) => {
|
onInput={(e) => {
|
||||||
setProposingAmount(Number(e.currentTarget.value))
|
setProposingAmount(Number(e.currentTarget.value))
|
||||||
setDisplayAmount(e.currentTarget.value)
|
|
||||||
}}
|
}}
|
||||||
onBlur={onInputAmountBlur}
|
onBlur={onInputAmountBlur}
|
||||||
onFocus={() => setDisplayAmount(proposingAmount.toString())}
|
onFocus={() => setInputFocused(true)}
|
||||||
/>
|
/>
|
||||||
<VoteProposingRangeWrap>
|
<VoteProposingRangeWrap>
|
||||||
<VoteProposingRange
|
<VoteProposingRange
|
||||||
|
|
Loading…
Reference in New Issue