u waku provider

This commit is contained in:
Felicio Mununga 2023-11-06 21:32:54 +01:00
parent c5768ab8ce
commit a78a5b750a
No known key found for this signature in database
GPG Key ID: C4736C7AEBA55BE5
9 changed files with 102 additions and 20 deletions

View File

@ -9,6 +9,7 @@ import { useSendWakuFeature } from '../../hooks/useSendWakuFeature'
import { useContractFunction } from '@usedapp/core'
import { useContracts } from '../../hooks/useContracts'
import { useFeaturedVotes } from '../../hooks/useFeaturedVotes'
import { useWaku } from '../../providers/waku/provider'
interface FeatureModalProps {
community: CommunityDetail
@ -17,11 +18,12 @@ interface FeatureModalProps {
export function FeatureModal({ community, setShowConfirmModal }: FeatureModalProps) {
const [proposingAmount, setProposingAmount] = useState(0)
const { isConnected } = useWaku()
const sendWaku = useSendWakuFeature()
const { featuredVotingContract } = useContracts()
const { send } = useContractFunction(featuredVotingContract, 'initializeVoting')
const { activeVoting } = useFeaturedVotes()
const disabled = proposingAmount === 0
const disabled = !isConnected || proposingAmount === 0
return (
<ColumnFlexDiv>

View File

@ -8,6 +8,7 @@ import { VoteType } from '../../constants/voteTypes'
import { useSendWakuVote } from '../../hooks/useSendWakuVote'
import { ColumnFlexDiv } from '../../constants/styles'
import { DetailedVotingRoom } from '../../models/smartContract'
import { useWaku } from '../../providers/waku/provider'
export interface VoteModalProps {
vote: CurrentVoting
@ -33,7 +34,7 @@ export function VoteModal({
votesFor,
votesAgainst,
}: VoteModalProps) {
const disabled = proposingAmount === 0
const { isConnected } = useWaku()
const sendWakuVote = useSendWakuVote()
return (
@ -61,7 +62,7 @@ export function VoteModal({
setShowConfirmModal(true)
}}
disabled={disabled}
disabled={!isConnected || proposingAmount === 0}
>{`Vote ${selectedVote.verb} community ${selectedVote.icon}`}</VoteConfirmBtn>
</ColumnFlexDiv>
)

View File

@ -7,9 +7,12 @@ import { CommunityDetail } from '../../models/community'
import { ProposeButton } from '../Button'
import { ConnectionNetwork } from '../ConnectionNetwork'
import { useAccount } from '../../hooks/useAccount'
import { useWaku } from '../../providers/waku/provider'
export function VotesInfo() {
const { isActive } = useAccount()
const { isConnected } = useWaku()
const [showProposeModal, setShowProposeModal] = useState(false)
const [showConfirmModal, setShowConfirmModal] = useState(false)
const [communityFound, setCommunityFound] = useState<undefined | CommunityDetail>(undefined)
@ -44,7 +47,11 @@ export function VotesInfo() {
</Modal>
)}
{isActive && <ProposeButton onClick={() => setShowProposeModal(true)}>Propose community</ProposeButton>}
{isActive && (
<ProposeButton onClick={() => setShowProposeModal(true)} disabled={!isConnected}>
Propose community
</ProposeButton>
)}
<ConnectionNetwork />
</InfoWrap>
)

View File

@ -9,9 +9,11 @@ import { ConnectionNetwork } from '../ConnectionNetwork'
import styled from 'styled-components'
import { Colors, ColumnFlexDiv } from '../../constants/styles'
import { useAccount } from '../../hooks/useAccount'
import { useWaku } from '../../providers/waku/provider'
export function VotingEmpty() {
const { isActive } = useAccount()
const { isConnected } = useWaku()
const [showProposeModal, setShowProposeModal] = useState(false)
const [showConfirmModal, setShowConfirmModal] = useState(false)
const [communityFound, setCommunityFound] = useState<undefined | CommunityDetail>(undefined)
@ -68,7 +70,11 @@ export function VotingEmpty() {
{!mobileVersion && (
<>
{isActive && <ProposeButton onClick={() => setShowProposeModal(true)}>Propose community</ProposeButton>}
{isActive && (
<ProposeButton onClick={() => setShowProposeModal(true)} disabled={!isConnected}>
Propose community
</ProposeButton>
)}
<ConnectionNetwork />
</>
)}

View File

@ -23,6 +23,7 @@ import { WrapperBottom, WrapperTop } from '../constants/styles'
import { useUnverifiedVotes } from '../hooks/useUnverifiedVotes'
import { useVotingBatches } from '../hooks/useVotingBatches'
import { useAccount } from '../hooks/useAccount'
import { useWaku } from '../providers/waku/provider'
interface CardVoteMobileProps {
room: DetailedVotingRoom
@ -84,6 +85,7 @@ export const CardVoteMobile = ({ room }: CardVoteMobileProps) => {
const [showHistory, setShowHistory] = useState(false)
const isDisabled = room.details.votingHistory.length === 0
const { isConnected } = useWaku()
const sendWakuVote = useSendWakuVote()
const includeUnverifiedVotes = !winner || verificationPeriod
@ -158,7 +160,7 @@ export const CardVoteMobile = ({ room }: CardVoteMobileProps) => {
{!verificationPeriod && !finalizationPeriod && (
<VotesBtns>
<VoteBtn
disabled={!canVote}
disabled={!isConnected || !canVote}
onClick={async () => {
await sendWakuVote(proposingAmount, room.roomNumber, 0)
setVoted(true)
@ -168,7 +170,7 @@ export const CardVoteMobile = ({ room }: CardVoteMobileProps) => {
{voteConstants.against.text} <span>{voteConstants.against.icon}</span>
</VoteBtn>
<VoteBtn
disabled={!canVote}
disabled={!isConnected || !canVote}
onClick={async () => {
await sendWakuVote(proposingAmount, room.roomNumber, 1)
setVoted(true)

View File

@ -23,12 +23,14 @@ import { useContracts } from '../hooks/useContracts'
import { useSendWakuFeature } from '../hooks/useSendWakuFeature'
import { useFeaturedVotingState } from '../hooks/useFeaturedVotingState'
import { useAccount } from '../hooks/useAccount'
import { useWaku } from '../providers/waku/provider'
export function FeatureMobile() {
const { publicKey } = useParams<{ publicKey: string }>()
const [community] = useCommunities([publicKey])
const [proposingAmount, setProposingAmount] = useState(0)
const { account, isActive } = useAccount()
const { isConnected } = useWaku()
const sendWaku = useSendWakuFeature()
const { activeVoting } = useFeaturedVotes()
const { featuredVotingContract } = useContracts()
@ -66,6 +68,7 @@ export function FeatureMobile() {
<VotePropose setProposingAmount={setProposingAmount} proposingAmount={proposingAmount} />
<FeatureBtn
disabled={
!isConnected ||
!account ||
!isActive ||
inFeatured ||

View File

@ -8,10 +8,11 @@ import { DAppProvider } from '@usedapp/core'
import { WakuProvider } from './providers/waku/provider'
import { CommunitiesProvider } from './providers/communities/provider'
import { config } from './config'
import { peers } from './constants/peers'
render(
<React.StrictMode>
<WakuProvider>
<WakuProvider peers={peers[config.wakuConfig.environment]}>
<DAppProvider config={config.daapConfig}>
<CommunitiesProvider>
<App />

View File

@ -16,9 +16,11 @@ import { ConnectionNetwork } from '../components/ConnectionNetwork'
import { VotingSkeletonMobile } from '../componentsMobile/VotingSkeletonMobile'
import { DetailedVotingRoom } from '../models/smartContract'
import { useAccount } from '../hooks/useAccount'
import { useWaku } from '../providers/waku/provider'
export function VotesMobile() {
const { isActive } = useAccount()
const { isConnected } = useWaku()
const [sortedBy, setSortedBy] = useState(VotingSortingEnum.EndingSoonest)
const [voteType, setVoteType] = useState('')
const [filterKeyword, setFilterKeyword] = useState('')
@ -62,7 +64,11 @@ export function VotesMobile() {
<VotingCardsWrapper>{renderCommunities()}</VotingCardsWrapper>
<ProposeButtonWrapper>
{isActive && <ProposeButton onClick={() => history.push('/propose')}>Propose community</ProposeButton>}
{isActive && (
<ProposeButton onClick={() => history.push('/propose')} disabled={!isConnected}>
Propose community
</ProposeButton>
)}
<ConnectionNetwork />
</ProposeButtonWrapper>
</div>

View File

@ -1,30 +1,48 @@
// note: pull on restart/reconnect
// note: upgrade waku in status-im
// note: tooltip
// note: permanent? notification/toast
// fixme: const { waku } = useWaku(); !waku conditions
import React, { ReactNode, createContext, useContext, useEffect, useState } from 'react'
import { Protocols } from 'js-waku'
import { createLightNode } from 'js-waku/lib/create_waku'
import { PeerDiscoveryStaticPeers } from 'js-waku/lib/peer_discovery_static_list'
import { waitForRemotePeer } from 'js-waku/lib/wait_for_remote_peer'
import type { WakuLight } from 'js-waku/lib/interfaces'
import { peers } from '../../constants/peers'
import { config } from '../../config'
const WakuContext = createContext<WakuLight | undefined>(undefined)
type Context = {
waku: WakuLight | undefined
isLoading: boolean
isConnected: boolean
isError: boolean
restart: () => Promise<void>
}
interface Props {
const WakuContext = createContext<Context | null>(null)
type Props = {
peers: string[]
children: ReactNode
}
export function WakuProvider({ children }: Props) {
export function WakuProvider({ peers, children }: Props) {
const [waku, setWaku] = useState<WakuLight>()
const [isLoading, setIsLoading] = useState<boolean>(true)
const [isConnected, setIsConnected] = useState<boolean>(false)
const [isError, setIsError] = useState<boolean>(false)
useEffect(() => {
const start = async () => {
try {
setIsLoading(true)
const waku = await createLightNode({
defaultBootstrap: false,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
emitSelf: true,
libp2p: {
peerDiscovery: [new PeerDiscoveryStaticPeers(peers[config.wakuConfig.environment], { maxPeers: 1 })],
peerDiscovery: [new PeerDiscoveryStaticPeers(peers, { maxPeers: 1 })],
},
})
@ -32,16 +50,52 @@ export function WakuProvider({ children }: Props) {
await waitForRemotePeer(waku, [Protocols.Store, Protocols.LightPush], 15 * 1000)
setWaku(waku)
setIsLoading(false)
setIsConnected(true)
} catch (error) {
setIsError(true)
setIsLoading(false)
}
}
const restart = async () => {
if (isLoading) {
throw new Error('Cannot restart while loading')
}
await waku?.stop()
await start()
}
const stop = async () => {
if (!waku) {
return
}
await waku.stop()
setIsConnected(false)
}
useEffect(() => {
start()
return () => {
stop()
}
}, [])
return <WakuContext.Provider value={waku}>{children}</WakuContext.Provider>
return (
<WakuContext.Provider value={{ waku, isLoading, isConnected, isError, restart }}>{children}</WakuContext.Provider>
)
}
export function useWaku() {
const waku = useContext(WakuContext)
const context = useContext(WakuContext)
return { waku }
if (!context) {
throw new Error('useWaku must be used within a WakuProvider')
}
return context
}