Remove signer from polling (#91)

This commit is contained in:
Szymon Szlachtowicz 2021-09-23 13:52:20 +02:00 committed by GitHub
parent 3700dac0a7
commit 58300680e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 158 additions and 38 deletions

View File

@ -1,2 +1,4 @@
# status-community-dapp # status-community-dapp
Community directory curator dApp for Status Community directory curator dApp for Status
Webpack for hosting polling and proposal apps

View File

@ -0,0 +1,18 @@
This packages contains react components used to display waku polls
## Components
-`Poll`
Components that displays poll as a card
```
type PollProps = {
theme: Theme // see react-components theme
poll: DetailedTimedPoll // see core DetailedTimedPoll
wakuPolling: WakuPolling | undefined // see core
signer: Wallet | JsonRpcSigner | undefined
}
```

View File

@ -35,7 +35,6 @@
"@status-waku-voting/core": "^0.1.0", "@status-waku-voting/core": "^0.1.0",
"@status-waku-voting/polling-hooks": "^0.1.0", "@status-waku-voting/polling-hooks": "^0.1.0",
"@status-waku-voting/react-components": "^0.1.0", "@status-waku-voting/react-components": "^0.1.0",
"@usedapp/core": "^0.4.7",
"ethers": "^5.4.4", "ethers": "^5.4.4",
"react": "^17.0.2", "react": "^17.0.2",
"styled-components": "^5.3.0" "styled-components": "^5.3.0"

View File

@ -1,42 +1,32 @@
import { WakuPolling } from '@status-waku-voting/core' import { WakuPolling } from '@status-waku-voting/core'
import { DetailedTimedPoll } from '@status-waku-voting/core/dist/esm/src/models/DetailedTimedPoll' import { DetailedTimedPoll } from '@status-waku-voting/core/dist/esm/src/models/DetailedTimedPoll'
import { Wallet, BigNumber } from 'ethers' import { BigNumber } from 'ethers'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { JsonRpcSigner } from '@ethersproject/providers'
import { PollType } from '@status-waku-voting/core/dist/esm/src/types/PollType' import { PollType } from '@status-waku-voting/core/dist/esm/src/types/PollType'
import styled from 'styled-components' import styled from 'styled-components'
import { RadioGroup, SmallButton, Theme } from '@status-waku-voting/react-components' import { RadioGroup, SmallButton, Theme } from '@status-waku-voting/react-components'
import { PollResults } from './PollResults' import { PollResults } from './PollResults'
import { useEthers } from '@usedapp/core'
import { Modal } from '@status-waku-voting/react-components' import { Modal } from '@status-waku-voting/react-components'
type PollProps = { type PollProps = {
theme: Theme theme: Theme
poll: DetailedTimedPoll poll: DetailedTimedPoll
wakuPolling: WakuPolling | undefined wakuPolling: WakuPolling | undefined
signer: Wallet | JsonRpcSigner | undefined account: string | null | undefined
} }
export function Poll({ poll, wakuPolling, theme, signer }: PollProps) { export function Poll({ poll, wakuPolling, theme, account }: PollProps) {
const { account } = useEthers()
const [selectedAnswer, setSelectedAnswer] = useState<number | undefined>(undefined) const [selectedAnswer, setSelectedAnswer] = useState<number | undefined>(undefined)
const [tokenAmount, setTokenAmount] = useState(0) const [tokenAmount, setTokenAmount] = useState(0)
const [address, setAddress] = useState('')
const [userInVoters, setUserInVoters] = useState(-1) const [userInVoters, setUserInVoters] = useState(-1)
const [showNotEnoughTokens, setShowNotEnoughTokens] = useState(false) const [showNotEnoughTokens, setShowNotEnoughTokens] = useState(false)
useEffect(() => { useEffect(() => {
if (signer) { if (account) {
signer.getAddress().then((e) => setAddress(e)) const msg = poll.votesMessages.find((vote) => vote.voter === account)
} else { setUserInVoters(msg?.answer ?? -1)
setAddress('')
} }
}, [signer]) }, [poll, account])
useEffect(() => {
const msg = poll.votesMessages.find((vote) => vote.voter === address)
setUserInVoters(msg?.answer ?? -1)
}, [poll, address])
return ( return (
<PollWrapper> <PollWrapper>
@ -65,9 +55,9 @@ export function Poll({ poll, wakuPolling, theme, signer }: PollProps) {
</PollAnswersWrapper> </PollAnswersWrapper>
{userInVoters < 0 && ( {userInVoters < 0 && (
<SmallButton <SmallButton
disabled={!signer || !account} disabled={!account}
onClick={async () => { onClick={async () => {
if (wakuPolling && signer) { if (wakuPolling && account) {
const result = await wakuPolling.sendTimedPollVote( const result = await wakuPolling.sendTimedPollVote(
poll.poll.id, poll.poll.id,
selectedAnswer ?? 0, selectedAnswer ?? 0,

View File

@ -1,6 +1,4 @@
import React, { ReactNode, useEffect, useState } from 'react' import React, { ReactNode, useState } from 'react'
import { Wallet } from 'ethers'
import { JsonRpcSigner } from '@ethersproject/providers'
import styled from 'styled-components' import styled from 'styled-components'
import { PollType } from '@status-waku-voting/core/dist/esm/src/types/PollType' import { PollType } from '@status-waku-voting/core/dist/esm/src/types/PollType'
import { WakuPolling } from '@status-waku-voting/core' import { WakuPolling } from '@status-waku-voting/core'
@ -36,12 +34,11 @@ function ConfirmScreen({ children, setShowModal }: ConfirmScreenProps) {
type PollCreationProps = { type PollCreationProps = {
theme: Theme theme: Theme
signer: JsonRpcSigner | Wallet
wakuPolling: WakuPolling | undefined wakuPolling: WakuPolling | undefined
setShowPollCreation: (val: boolean) => void setShowPollCreation: (val: boolean) => void
} }
export function PollCreation({ signer, wakuPolling, theme, setShowPollCreation }: PollCreationProps) { export function PollCreation({ wakuPolling, theme, setShowPollCreation }: PollCreationProps) {
const [answers, setAnswers] = useState<string[]>(['', '']) const [answers, setAnswers] = useState<string[]>(['', ''])
const [question, setQuestion] = useState('') const [question, setQuestion] = useState('')
const [showCreateConfirmation, setShowCreateConfirmation] = useState(false) const [showCreateConfirmation, setShowCreateConfirmation] = useState(false)

View File

@ -1,19 +1,17 @@
import { WakuPolling } from '@status-waku-voting/core' import { WakuPolling } from '@status-waku-voting/core'
import { DetailedTimedPoll } from '@status-waku-voting/core/dist/esm/src/models/DetailedTimedPoll' import { DetailedTimedPoll } from '@status-waku-voting/core/dist/esm/src/models/DetailedTimedPoll'
import { Wallet } from 'ethers'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { Poll } from './Poll' import { Poll } from './Poll'
import { JsonRpcSigner } from '@ethersproject/providers'
import styled from 'styled-components' import styled from 'styled-components'
import { Theme } from '@status-waku-voting/react-components' import { Theme } from '@status-waku-voting/react-components'
type PollListProps = { type PollListProps = {
theme: Theme theme: Theme
wakuPolling: WakuPolling | undefined wakuPolling: WakuPolling | undefined
signer: Wallet | JsonRpcSigner | undefined account: string | null | undefined
} }
export function PollList({ wakuPolling, signer, theme }: PollListProps) { export function PollList({ wakuPolling, account, theme }: PollListProps) {
const [polls, setPolls] = useState<DetailedTimedPoll[]>([]) const [polls, setPolls] = useState<DetailedTimedPoll[]>([])
const [dividedPolls, setDividedPolls] = useState<DetailedTimedPoll[][]>([[], [], []]) const [dividedPolls, setDividedPolls] = useState<DetailedTimedPoll[][]>([[], [], []])
useEffect(() => { useEffect(() => {
@ -45,7 +43,7 @@ export function PollList({ wakuPolling, signer, theme }: PollListProps) {
return ( return (
<ColumnWrapper key={idx}> <ColumnWrapper key={idx}>
{pollArray.map((poll) => { {pollArray.map((poll) => {
return <Poll key={poll.poll.id} poll={poll} wakuPolling={wakuPolling} signer={signer} theme={theme} /> return <Poll key={poll.poll.id} poll={poll} wakuPolling={wakuPolling} account={account} theme={theme} />
})} })}
</ColumnWrapper> </ColumnWrapper>
) )

View File

@ -28,12 +28,7 @@ export function WakuPolling({ appName, signer, theme }: WakuPollingProps) {
return ( return (
<Wrapper> <Wrapper>
{showPollCreation && signer && ( {showPollCreation && signer && (
<PollCreation <PollCreation wakuPolling={wakuPolling} setShowPollCreation={setShowPollCreation} theme={theme} />
signer={signer}
wakuPolling={wakuPolling}
setShowPollCreation={setShowPollCreation}
theme={theme}
/>
)} )}
{account ? ( {account ? (
<CreateButton theme={theme} disabled={!signer} onClick={() => setShowPollCreation(true)}> <CreateButton theme={theme} disabled={!signer} onClick={() => setShowPollCreation(true)}>
@ -57,7 +52,7 @@ export function WakuPolling({ appName, signer, theme }: WakuPollingProps) {
</Modal> </Modal>
)} )}
<PollList wakuPolling={wakuPolling} signer={signer} theme={theme} /> <PollList wakuPolling={wakuPolling} account={account} theme={theme} />
</Wrapper> </Wrapper>
) )
} }

View File

@ -0,0 +1,121 @@
Package containing react hooks and components helpers
## hooks
- `useTokenBalance(address: string | null | undefined, wakuVoting: WakuMessaging)` returns memoized token (token address is dervied from waku messaging object)balance of given address
- `useMobileVersion(sizeThreshold: number)` returns true if web browser width is below threshold
- `useRefMobileVersion(myRef: React.RefObject<HTMLHeadingElement>, sizeThreshold: number)` returns true if ref element width is below threshold
## theme
Some of package components require theme object, package provides 2 themes
```
export type Theme = {
primaryColor: string
secondaryColor: string
activeTextColor: string
activeBackgroundColor: string
backgroundColor: string
}
export const orangeTheme: Theme = {
primaryColor: '#ffb571',
secondaryColor: '#a53607',
activeTextColor: '#ffffff',
activeBackgroundColor: '#f4b77e',
backgroundColor: '#fbfcfe',
}
export const blueTheme: Theme = {
primaryColor: '#5d7be2',
secondaryColor: '#0f3595',
activeTextColor: '#7e98f4',
activeBackgroundColor: '#7e98f4',
backgroundColor: '#f8faff',
}
```
## components
- `Modal`
Component that overlays over other components
```
type ModalProps = {
heading: string // text that shows on top of modal
children: ReactNode // children to show in modal
theme: Theme // theme of modal
setShowModal: (val: boolean) => void // function that changes modal visibility
}
```
- `Input`
Input with a label
```
type InputProps = {
label: string
value: string
onChange: (e: any) => void
placeholder?: string
}
```
- `TopBar`
stylized topBar component with web3 connect button
```
type TopBarProps = {
logo: string // logo icon
title: string
theme: Theme
activate: () => void // function that connects web3 provider used if account is undefined
deactivate: () => void // function that disconnects web3 provider used when account is defined
account: string | undefined | null // user address
}
```
- `RadioGroup`
Component that shows a list of radio buttons and only one possible select
```
type RadioGroupProps = {
options: string[] // list of buttons labels
setSelectedOption: (option: number) => void // state update function
selectedOption: number | undefined // state which holds selectedOption number
}
```
## buttons
Package also contains styled buttons
```Button, SmallButton, ConnectButton, CreateButton, ButtonDisconnect, Account```
## icons
Package contains following icons
```checkCircleIcon, addIcon, checkIcon, closeIcon, dappIcon, metamaskIcon, statusIcon```
## functions
- `colorRouletteGenerator()`
generator which next function returns color from a roulette
### example usage
```
const colors = colorRouletteGenerator()
const color1 = colors.next().value
const color2 = colors.next().value
const color3 = colors.next().value
```