Refactor resizing hook (#69)

This commit is contained in:
Szymon Szlachtowicz 2021-09-14 18:06:21 +02:00 committed by GitHub
parent 5b200bc60e
commit d1790007c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 70 additions and 55 deletions

View File

@ -6,13 +6,14 @@ import { ProposalList } from './ProposalList'
import { NotificationItem } from './NotificationItem' import { NotificationItem } from './NotificationItem'
import { WakuVoting } from '@status-waku-voting/core' import { WakuVoting } from '@status-waku-voting/core'
import { VotingEmpty } from './VotingEmpty' import { VotingEmpty } from './VotingEmpty'
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
type ProposalProps = { type ProposalProps = {
wakuVoting: WakuVoting wakuVoting: WakuVoting
} }
export function Proposal({ wakuVoting }: ProposalProps) { export function Proposal({ wakuVoting }: ProposalProps) {
const [votes, setVotes] = useState<any[]>([]) const [votes, setVotes] = useState<VotingRoom[]>([])
useEffect(() => { useEffect(() => {
const interval = setInterval(async () => { const interval = setInterval(async () => {

View File

@ -9,7 +9,7 @@ import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType
type ProposalListProps = { type ProposalListProps = {
theme: Theme theme: Theme
wakuVoting: WakuVoting wakuVoting: WakuVoting
votes: any[] votes: VotingRoom[]
} }
export function ProposalList({ theme, wakuVoting, votes }: ProposalListProps) { export function ProposalList({ theme, wakuVoting, votes }: ProposalListProps) {
return ( return (

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react' import React, { useRef } from 'react'
import CountUp from 'react-countup' import CountUp from 'react-countup'
import styled from 'styled-components' import styled from 'styled-components'
import { addCommas } from '../../helpers/addCommas' import { addCommas } from '../../helpers/addCommas'
@ -8,6 +8,7 @@ import crossIcon from '../../assets/svg/cross.svg'
import crossWinnerIcon from '../../assets/svg/crossWinner.svg' import crossWinnerIcon from '../../assets/svg/crossWinner.svg'
import checkIcon from '../../assets/svg/check.svg' import checkIcon from '../../assets/svg/check.svg'
import checkWinnerIcon from '../../assets/svg/checkWinner.svg' import checkWinnerIcon from '../../assets/svg/checkWinner.svg'
import { useMobileVersion } from '@status-waku-voting/react-components'
export interface VoteChartProps { export interface VoteChartProps {
votesFor: number votesFor: number
@ -30,20 +31,8 @@ export function VoteChart({
isAnimation, isAnimation,
tabletMode, tabletMode,
}: VoteChartProps) { }: VoteChartProps) {
const [mobileVersion, setMobileVersion] = useState(false) const ref = useRef<HTMLHeadingElement>(null)
const mobileVersion = useMobileVersion(ref, 600)
useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 600) {
setMobileVersion(true)
} else {
setMobileVersion(false)
}
}
handleResize()
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
const voteSum = votesFor + votesAgainst const voteSum = votesFor + votesAgainst
const graphWidth = (100 * votesAgainst) / voteSum const graphWidth = (100 * votesAgainst) / voteSum
@ -58,7 +47,7 @@ export function VoteChart({
} }
return ( return (
<Votes> <Votes ref={ref}>
<VotesChart className={selectedVote || tabletMode ? '' : 'notModal'}> <VotesChart className={selectedVote || tabletMode ? '' : 'notModal'}>
<VoteBox <VoteBox
style={{ style={{

View File

@ -1,8 +1,8 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState, useRef } from 'react'
import { useHistory } from 'react-router' import { useHistory } from 'react-router'
import { useEthers } from '@usedapp/core' import { useEthers } from '@usedapp/core'
import styled from 'styled-components' import styled from 'styled-components'
import { CreateButton, Modal, Networks, Theme } from '@status-waku-voting/react-components' import { CreateButton, Modal, Networks, Theme, useMobileVersion } from '@status-waku-voting/react-components'
import { ProposeModal } from './ProposeModal' import { ProposeModal } from './ProposeModal'
import { ProposeVoteModal } from './ProposeVoteModal' import { ProposeVoteModal } from './ProposeVoteModal'
import { WakuVoting } from '@status-waku-voting/core' import { WakuVoting } from '@status-waku-voting/core'
@ -17,31 +17,20 @@ export function VotingEmpty({ wakuVoting, theme }: VotingEmptyProps) {
const [selectConnect, setSelectConnect] = useState(false) const [selectConnect, setSelectConnect] = useState(false)
const [showProposeModal, setShowProposeModal] = useState(false) const [showProposeModal, setShowProposeModal] = useState(false)
const [showProposeVoteModal, setShowProposeVoteModal] = useState(false) const [showProposeVoteModal, setShowProposeVoteModal] = useState(false)
const [mobileVersion, setMobileVersion] = useState(false)
const [title, setTitle] = useState('') const [title, setTitle] = useState('')
const [text, setText] = useState('') const [text, setText] = useState('')
const history = useHistory() const history = useHistory()
const ref = useRef<HTMLHeadingElement>(null)
const mobileVersion = useMobileVersion(ref, 600)
const setNext = (val: boolean) => { const setNext = (val: boolean) => {
setShowProposeVoteModal(val) setShowProposeVoteModal(val)
setShowProposeModal(false) setShowProposeModal(false)
} }
useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 600) {
setMobileVersion(true)
} else {
setMobileVersion(false)
}
}
handleResize()
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
return ( return (
<VotingEmptyWrap> <VotingEmptyWrap ref={ref}>
<EmptyWrap> <EmptyWrap>
<EmptyHeading>There are no proposals at the moment!</EmptyHeading> <EmptyHeading>There are no proposals at the moment!</EmptyHeading>
<EmptyText> <EmptyText>

View File

@ -7,13 +7,14 @@ import { ProposalHeaderMobile } from './ProposalHeaderMobile'
import styled from 'styled-components' import styled from 'styled-components'
import { WakuVoting } from '@status-waku-voting/core' import { WakuVoting } from '@status-waku-voting/core'
import { ProposalVotesWrapper } from '../Proposal' import { ProposalVotesWrapper } from '../Proposal'
import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType'
type ProposalMainMobileProps = { type ProposalMainMobileProps = {
wakuVoting: WakuVoting wakuVoting: WakuVoting
} }
export function ProposalMainMobile({ wakuVoting }: ProposalMainMobileProps) { export function ProposalMainMobile({ wakuVoting }: ProposalMainMobileProps) {
const [votes, setVotes] = useState<any[]>([]) const [votes, setVotes] = useState<VotingRoom[]>([])
useEffect(() => { useEffect(() => {
const interval = setInterval(async () => { const interval = setInterval(async () => {

View File

@ -3,10 +3,10 @@ import React, { useEffect, useState } from 'react'
import { providers } from 'ethers' import { providers } from 'ethers'
export function useWakuProposal() { export function useWakuProposal() {
;(window as any).ethereum.on('chainChanged', () => window.location.reload())
const [waku, setWaku] = useState<WakuVoting | undefined>(undefined) const [waku, setWaku] = useState<WakuVoting | undefined>(undefined)
useEffect(() => { useEffect(() => {
;(window as any).ethereum.on('chainChanged', () => window.location.reload())
const createWaku = async () => { const createWaku = async () => {
const provider = new providers.Web3Provider((window as any).ethereum) const provider = new providers.Web3Provider((window as any).ethereum)
const wak = await WakuVoting.create( const wak = await WakuVoting.create(
@ -18,6 +18,8 @@ export function useWakuProposal() {
setWaku(wak) setWaku(wak)
} }
createWaku() createWaku()
return () => (window as any).ethereum.removeListener('chainChanged', () => window.location.reload())
}, []) }, [])
return waku return waku

View File

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react' import React, { useRef } from 'react'
import { useWakuProposal } from '@status-waku-voting/proposal-hooks' import { useWakuProposal } from '@status-waku-voting/proposal-hooks'
import { Proposal, ProposalMobile } from '@status-waku-voting/proposal-components' import { Proposal, ProposalMobile } from '@status-waku-voting/proposal-components'
import { TopBar, GlobalStyle } from '@status-waku-voting/react-components' import { TopBar, GlobalStyle, useMobileVersion } from '@status-waku-voting/react-components'
import votingIcon from './assets/images/voting.svg' import votingIcon from './assets/images/voting.svg'
import styled from 'styled-components' import styled from 'styled-components'
import { blueTheme } from '@status-waku-voting/react-components/dist/esm/src/style/themes' import { blueTheme } from '@status-waku-voting/react-components/dist/esm/src/style/themes'
@ -25,25 +25,13 @@ const config = {
} }
function Proposals() { function Proposals() {
const { account, library, activateBrowserWallet, deactivate } = useEthers() const { account, activateBrowserWallet, deactivate } = useEthers()
const waku = useWakuProposal() const waku = useWakuProposal()
const [mobileVersion, setMobileVersion] = useState(false) const ref = useRef<HTMLHeadingElement>(null)
const mobileVersion = useMobileVersion(ref, 600)
useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 600) {
setMobileVersion(true)
} else {
setMobileVersion(false)
}
}
handleResize()
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
return ( return (
<Wrapper> <Wrapper ref={ref}>
<TopBar <TopBar
logo={votingIcon} logo={votingIcon}
title={'Proposals Dapp'} title={'Proposals Dapp'}

View File

@ -0,0 +1,16 @@
import React, { useEffect, useState } from 'react'
import { useRefSize } from './useRefSize'
export function useMobileVersion(myRef: React.RefObject<HTMLHeadingElement>, sizeThreshold: number) {
const [mobileVersion, setMobileVersion] = useState(false)
const { width } = useRefSize(myRef)
useEffect(() => {
if (width < sizeThreshold && width > 0) {
setMobileVersion(true)
} else {
setMobileVersion(false)
}
}, [width])
return mobileVersion
}

View File

@ -0,0 +1,25 @@
import React, { useEffect, useState } from 'react'
export function useRefSize(myRef: React.RefObject<HTMLHeadingElement>) {
const [width, setWidth] = useState(0)
const [height, setHeight] = useState(0)
const setDimensions = () => {
if (myRef?.current?.offsetWidth) {
setWidth(myRef?.current?.offsetWidth)
}
if (myRef?.current?.offsetHeight) {
setHeight(myRef?.current?.offsetHeight)
}
}
useEffect(() => {
setDimensions()
window.addEventListener('resize', setDimensions)
return () => {
window.removeEventListener('resize', setDimensions)
}
}, [myRef])
return { width, height }
}

View File

@ -14,7 +14,11 @@ import dappIcon from './assets/svg/dapp.svg'
import metamaskIcon from './assets/metamask.png' import metamaskIcon from './assets/metamask.png'
import statusIcon from './assets/svg/status.svg' import statusIcon from './assets/svg/status.svg'
import themes, { Theme } from './style/themes' import themes, { Theme } from './style/themes'
import { useRefSize } from './hooks/useRefSize'
import { useMobileVersion } from './hooks/useMobileVersion'
export { export {
useMobileVersion,
useRefSize,
Modal, Modal,
Input, Input,
Networks, Networks,