From 635be29df367f3d510e707f1679f9d11b740ffb7 Mon Sep 17 00:00:00 2001 From: Szymon Szlachtowicz <38212223+Szymx95@users.noreply.github.com> Date: Wed, 22 Sep 2021 03:24:52 +0200 Subject: [PATCH] Refactor components mobile version (#86) --- packages/core/src/classes/WakuMessaging.ts | 1 - .../src/components/ProposalCard.tsx | 32 ++++++---- .../src/components/ProposalInfo.tsx | 52 +++++++--------- .../src/components/ProposalList.tsx | 15 ++--- .../ProposalVoteCard/ProposalVote.tsx | 43 +++++++------ .../components/ProposalVoteCard/VoteChart.tsx | 61 ++++++++++++------- .../src/components/VoteModal/AmountModal.tsx | 3 + .../src/components/VoteModal/ConfirmModal.tsx | 3 + .../src/components/VoteModal/VoteModal.tsx | 4 ++ .../src/components/VotePropose.tsx | 2 +- .../components/mobile/ProposalVoteMobile.tsx | 4 +- .../src/components/Proposal.tsx | 8 ++- packages/proposal-example/src/index.tsx | 2 +- .../src/hooks/useMobileVersion.ts | 4 +- .../src/hooks/useRefMobileVersion.ts | 27 ++++++++ packages/react-components/src/index.tsx | 2 + 16 files changed, 167 insertions(+), 96 deletions(-) create mode 100644 packages/react-components/src/hooks/useRefMobileVersion.ts diff --git a/packages/core/src/classes/WakuMessaging.ts b/packages/core/src/classes/WakuMessaging.ts index e05ceb2..9cb0780 100644 --- a/packages/core/src/classes/WakuMessaging.ts +++ b/packages/core/src/classes/WakuMessaging.ts @@ -71,7 +71,6 @@ export class WakuMessaging { protected async setObserver() { this.tokenDecimals = await this.token.decimals() this.tokenSymbol = await this.token.symbol() - console.log(this.tokenSymbol) this.waku = await createWaku(this.waku) await Promise.all( Object.values(this.wakuMessages).map(async (msgObj) => { diff --git a/packages/proposal-components/src/components/ProposalCard.tsx b/packages/proposal-components/src/components/ProposalCard.tsx index a299091..f025c95 100644 --- a/packages/proposal-components/src/components/ProposalCard.tsx +++ b/packages/proposal-components/src/components/ProposalCard.tsx @@ -1,5 +1,4 @@ -import React, { ReactElement, useCallback, useState } from 'react' -import { useHistory } from 'react-router' +import React, { ReactElement, useCallback, useState, useRef, useMemo } from 'react' import styled from 'styled-components' import { Theme } from '@status-waku-voting/react-components' import { ProposalInfo } from './ProposalInfo' @@ -7,15 +6,17 @@ import { ProposalVote } from './ProposalVoteCard/ProposalVote' import { WakuVoting } from '@status-waku-voting/core' import { useVotingRoom } from '@status-waku-voting/proposal-hooks' import { VoteModal, VoteModalProps } from './VoteModal/VoteModal' +import { useRefMobileVersion } from '@status-waku-voting/react-components' +import { VotingRoom } from '@status-waku-voting/core/dist/esm/src/types/PollType' interface ProposalCardProps { votingRoomId: number - mobileVersion?: boolean theme: Theme hideModalFunction?: (val: boolean) => void availableAmount: number wakuVoting: WakuVoting account: string | null | undefined + mobileOnClick: (votingRoom: VotingRoom) => void CustomVoteModal?: (props: VoteModalProps) => ReactElement customAgainstClick?: () => void customForClick?: () => void @@ -25,16 +26,21 @@ export function ProposalCard({ account, theme, votingRoomId, - mobileVersion, availableAmount, wakuVoting, CustomVoteModal, customAgainstClick, customForClick, + mobileOnClick, }: ProposalCardProps) { - const history = useHistory() const votingRoom = useVotingRoom(votingRoomId, wakuVoting) - + const ref = useRef(null) + const mobileVersion = useRefMobileVersion(ref, 568) + const tabletVersion = useRefMobileVersion(ref, 703) + const className = useMemo( + () => (mobileVersion ? 'mobile' : tabletVersion ? 'tablet' : ''), + [mobileVersion, tabletVersion] + ) const [showVoteModal, setShowVoteModal] = useState(false) const [selectedVote, setSelectedVote] = useState(0) @@ -53,7 +59,7 @@ export function ProposalCard({ } return ( - mobileVersion && history.push(`/votingRoom/${votingRoom.id.toString()}`)}> + mobileVersion && mobileOnClick(votingRoom)}> {CustomVoteModal ? ( ) : ( )} - + ) @@ -93,19 +102,20 @@ export const Card = styled.div` align-items: stretch; margin-bottom: 24px; - @media (max-width: 768px) { + &.tablet { flex-direction: column; box-shadow: 0px 1px 6px rgba(0, 0, 0, 0.15); } - @media (max-width: 600px) { + &.mobile { + flex-direction: column; padding-bottom: 24px; box-shadow: none; border-bottom: 1px solid rgba(0, 0, 0, 0.3); } &:not:first-child { - @media (max-width: 768px) { + &.tablet { border-top: 1px solid #e0e0e0; } } diff --git a/packages/proposal-components/src/components/ProposalInfo.tsx b/packages/proposal-components/src/components/ProposalInfo.tsx index 593efa8..e803643 100644 --- a/packages/proposal-components/src/components/ProposalInfo.tsx +++ b/packages/proposal-components/src/components/ProposalInfo.tsx @@ -6,15 +6,15 @@ import { ViewLink } from './ViewLink' type ProposalInfoProps = { votingRoom: VotingRoom providerName: string - mobileMode?: boolean + className?: string } -export function ProposalInfo({ votingRoom, mobileMode, providerName }: ProposalInfoProps) { +export function ProposalInfo({ votingRoom, className, providerName }: ProposalInfoProps) { return ( - - {votingRoom.question} - {votingRoom.description} - + + {votingRoom.question} + {votingRoom.description} + void } -export function ProposalList({ theme, wakuVoting, votes, availableAmount, account }: ProposalListProps) { - const ref = useRef(null) - const mobileVersion = useMobileVersion(ref, 600) +export function ProposalList({ theme, wakuVoting, votes, availableAmount, account, mobileOnClick }: ProposalListProps) { return ( - + {votes.map((votingRoom) => { return ( ) })} diff --git a/packages/proposal-components/src/components/ProposalVoteCard/ProposalVote.tsx b/packages/proposal-components/src/components/ProposalVoteCard/ProposalVote.tsx index 7e35570..e0dccfe 100644 --- a/packages/proposal-components/src/components/ProposalVoteCard/ProposalVote.tsx +++ b/packages/proposal-components/src/components/ProposalVoteCard/ProposalVote.tsx @@ -14,6 +14,7 @@ interface ProposalVoteProps { account: string | null | undefined againstClick: () => void forClick: () => void + className: string } export function ProposalVote({ @@ -23,6 +24,7 @@ export function ProposalVote({ wakuVoting, againstClick, forClick, + className, }: ProposalVoteProps) { const [alreadyVoted, setAlreadyVoted] = useState(false) @@ -35,20 +37,20 @@ export function ProposalVote({ }, [account, votingRoom]) return ( - + {votingRoom.voteWinner ? ( - Proposal {votingRoom.voteWinner == 1 ? 'rejected' : 'passed'} + Proposal {votingRoom.voteWinner == 1 ? 'rejected' : 'passed'} ) : ( - + )} - + - + {votingRoom.voteWinner ? ( <> ) : ( - + Vote Against @@ -59,8 +61,8 @@ export function ProposalVote({ )} - - + + {' '} @@ -85,7 +87,7 @@ export const Card = styled.div` border-radius: 6px 0px 0px 6px; background-color: #fbfcfe; - @media (max-width: 768px) { + &.tablet { width: 100%; box-shadow: none; border-radius: unset; @@ -93,7 +95,11 @@ export const Card = styled.div` padding-top: 0; } - @media (max-width: 600px) { + &.mobile { + width: 100%; + box-shadow: none; + border-radius: unset; + background-color: unset; flex-direction: column; padding: 0; border-bottom: none; @@ -108,13 +114,16 @@ export const CardHeading = styled.h2` margin: 0; margin-bottom: 15px; - @media (max-width: 768px) { + &.tablet { font-size: 15px; line-height: 22px; margin-bottom: 6px; } - @media (max-width: 600px) { + &.mobile { + font-size: 15px; + line-height: 22px; + margin-bottom: 6px; display: none; } ` @@ -122,7 +131,7 @@ export const CardHeading = styled.h2` const CardButtons = styled.div` width: 100%; - @media (max-width: 600px) { + &.mobile { display: none; } ` @@ -132,7 +141,7 @@ export const VotesBtns = styled.div` justify-content: space-between; width: 100%; - @media (max-width: 600px) { + &.mobile { margin-top: 24px; } ` @@ -144,18 +153,18 @@ const CardVoteBottom = styled.div` width: 100%; margin-top: 24px; - @media (max-width: 768px) { + &.tablet { justify-content: space-between; } - @media (max-width: 600px) { + &.mobile { display: none; } ` const CardViewLink = styled.div` display: none; - @media (max-width: 768px) { + &.tablet { display: block; } ` diff --git a/packages/proposal-components/src/components/ProposalVoteCard/VoteChart.tsx b/packages/proposal-components/src/components/ProposalVoteCard/VoteChart.tsx index 9bc71c5..98022ba 100644 --- a/packages/proposal-components/src/components/ProposalVoteCard/VoteChart.tsx +++ b/packages/proposal-components/src/components/ProposalVoteCard/VoteChart.tsx @@ -15,6 +15,7 @@ import { WakuVoting } from '@status-waku-voting/core' export interface VoteChartProps { votingRoom: VotingRoom wakuVoting: WakuVoting + className: string proposingAmount?: number selectedVote?: number isAnimation?: boolean @@ -28,10 +29,8 @@ export function VoteChart({ selectedVote, isAnimation, tabletMode, + className, }: VoteChartProps) { - const ref = useRef(null) - const mobileVersion = useMobileVersion(ref, 600) - const totalVotesFor = useMemo( () => (isAnimation ? votingRoom.totalVotesFor : votingRoom.wakuTotalVotesFor), [votingRoom, proposingAmount] @@ -61,11 +60,12 @@ export function VoteChart({ const voteWinner = useMemo(() => votingRoom.voteWinner, [votingRoom.voteWinner]) return ( - - + + {!voteWinner && ( - {formatTimeLeft(votingRoom.timeLeft)} + + {formatTimeLeft(votingRoom.timeLeft)} + )} - + - + {formatTimeLeft(votingRoom.timeLeft)} @@ -106,13 +109,24 @@ type VoteBoxProps = { voteType: number totalVotes: number wakuVoting: WakuVoting + className: string selected?: boolean proposingAmount?: number } -function VoteBox({ won, mobileVersion, voteType, totalVotes, proposingAmount, selected, wakuVoting }: VoteBoxProps) { +function VoteBox({ + won, + mobileVersion, + className, + voteType, + totalVotes, + proposingAmount, + selected, + wakuVoting, +}: VoteBoxProps) { return ( void setProposingAmount: (val: number) => void wakuVoting: WakuVoting + className: string } export function AmountModal({ @@ -25,6 +26,7 @@ export function AmountModal({ setShowConfirmModal, setProposingAmount, wakuVoting, + className, }: AmountModalProps) { const disabled = proposingAmount === 0 const funds = availableAmount > 0 @@ -39,6 +41,7 @@ export function AmountModal({ proposingAmount={proposingAmount} selectedVote={selectedVote} wakuVoting={wakuVoting} + className={className} /> void wakuVoting: WakuVoting + className: string } export function ConfirmModal({ @@ -19,6 +20,7 @@ export function ConfirmModal({ proposingAmount, setShowModal, wakuVoting, + className, }: ConfirmModalProps) { return ( @@ -29,6 +31,7 @@ export function ConfirmModal({ selectedVote={selectedVote} isAnimation={true} wakuVoting={wakuVoting} + className={className} /> setShowModal(false)}>Close diff --git a/packages/proposal-components/src/components/VoteModal/VoteModal.tsx b/packages/proposal-components/src/components/VoteModal/VoteModal.tsx index d717740..4994200 100644 --- a/packages/proposal-components/src/components/VoteModal/VoteModal.tsx +++ b/packages/proposal-components/src/components/VoteModal/VoteModal.tsx @@ -13,6 +13,7 @@ export interface VoteModalProps { selectedVote: number wakuVoting: WakuVoting theme: Theme + className: string } export function VoteModal({ @@ -23,6 +24,7 @@ export function VoteModal({ selectedVote, wakuVoting, theme, + className, }: VoteModalProps) { const [screen, setScreen] = useState(0) useEffect(() => setScreen(0), []) @@ -44,6 +46,7 @@ export function VoteModal({ setShowConfirmModal={() => setScreen(1)} setProposingAmount={setProposingAmount} wakuVoting={wakuVoting} + className={className} /> ) : ( )} diff --git a/packages/proposal-components/src/components/VotePropose.tsx b/packages/proposal-components/src/components/VotePropose.tsx index 34ada5d..9b8a9dd 100644 --- a/packages/proposal-components/src/components/VotePropose.tsx +++ b/packages/proposal-components/src/components/VotePropose.tsx @@ -44,7 +44,7 @@ export function VotePropose({ availableAmount, proposingAmount, setProposingAmou { setProposingAmount(Number(e.currentTarget.value)) }} diff --git a/packages/proposal-components/src/components/mobile/ProposalVoteMobile.tsx b/packages/proposal-components/src/components/mobile/ProposalVoteMobile.tsx index d4722c8..a23a3c7 100644 --- a/packages/proposal-components/src/components/mobile/ProposalVoteMobile.tsx +++ b/packages/proposal-components/src/components/mobile/ProposalVoteMobile.tsx @@ -30,9 +30,9 @@ export function ProposalVoteMobile({ wakuVoting, availableAmount, account }: Pro return ( - + - + {!voteWinner && ( (null) - const mobileVersion = useMobileVersion(ref, 600) + const mobileVersion = useMobileVersion(600) const onCreateClick = useCallback(() => { mobileVersion ? history.push(`/creation`) : setShowNewVoteModal(true) @@ -66,7 +67,7 @@ type ProposalProps = { export function Proposal({ wakuVoting, account }: ProposalProps) { const votes = useVotingRoomsId(wakuVoting) const tokenBalance = useTokenBalance(account, wakuVoting) - + const history = useHistory() return ( @@ -84,6 +85,7 @@ export function Proposal({ wakuVoting, account }: ProposalProps) { wakuVoting={wakuVoting} votes={votes} availableAmount={tokenBalance} + mobileOnClick={(votingRoom: VotingRoom) => history.push(`/votingRoom/${votingRoom.id.toString()}`)} /> )} diff --git a/packages/proposal-example/src/index.tsx b/packages/proposal-example/src/index.tsx index 39f7789..334c7b7 100644 --- a/packages/proposal-example/src/index.tsx +++ b/packages/proposal-example/src/index.tsx @@ -36,7 +36,7 @@ function Proposals() { config?.multicallAddresses?.[chainId ?? 1337] ) const ref = useRef(null) - const mobileVersion = useMobileVersion(ref, 600) + const mobileVersion = useMobileVersion(600) return ( diff --git a/packages/react-components/src/hooks/useMobileVersion.ts b/packages/react-components/src/hooks/useMobileVersion.ts index 52b1179..7e51c2b 100644 --- a/packages/react-components/src/hooks/useMobileVersion.ts +++ b/packages/react-components/src/hooks/useMobileVersion.ts @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react' -export function useMobileVersion(myRef: React.RefObject, sizeThreshold: number) { +export function useMobileVersion(sizeThreshold: number) { const [mobileVersion, setMobileVersion] = useState(false) useEffect(() => { @@ -21,7 +21,7 @@ export function useMobileVersion(myRef: React.RefObject, siz return () => { window.removeEventListener('resize', checkDimensions) } - }, [myRef, mobileVersion]) + }, [mobileVersion]) return mobileVersion } diff --git a/packages/react-components/src/hooks/useRefMobileVersion.ts b/packages/react-components/src/hooks/useRefMobileVersion.ts new file mode 100644 index 0000000..58ddbe9 --- /dev/null +++ b/packages/react-components/src/hooks/useRefMobileVersion.ts @@ -0,0 +1,27 @@ +import React, { useEffect, useState } from 'react' + +export function useRefMobileVersion(myRef: React.RefObject, sizeThreshold: number) { + const [mobileVersion, setMobileVersion] = useState(false) + + useEffect(() => { + const checkDimensions = () => { + const width = myRef?.current?.offsetWidth ?? 0 + if (width && width < sizeThreshold && width > 0) { + if (mobileVersion === false) { + setMobileVersion(true) + } + } else { + if (mobileVersion === true) { + setMobileVersion(false) + } + } + } + checkDimensions() + window.addEventListener('resize', checkDimensions) + return () => { + window.removeEventListener('resize', checkDimensions) + } + }, [myRef, mobileVersion, myRef?.current?.offsetWidth]) + + return mobileVersion +} diff --git a/packages/react-components/src/index.tsx b/packages/react-components/src/index.tsx index d945983..7eb43fc 100644 --- a/packages/react-components/src/index.tsx +++ b/packages/react-components/src/index.tsx @@ -16,10 +16,12 @@ import statusIcon from './assets/svg/status.svg' import themes, { Theme } from './style/themes' import { useRefSize } from './hooks/useRefSize' import { useMobileVersion } from './hooks/useMobileVersion' +import { useRefMobileVersion } from './hooks/useRefMobileVersion' import { useTokenBalance } from './hooks/useTokenBalance' export { useTokenBalance, useMobileVersion, + useRefMobileVersion, useRefSize, Modal, Input,