Use directory contract (#105)
This commit is contained in:
parent
d1fd8e04a5
commit
01710ff198
|
@ -4,16 +4,14 @@ import { CardCommunity } from '../card/CardCommunity'
|
|||
import { CardFeature } from '../card/CardFeature'
|
||||
import styled from 'styled-components'
|
||||
import { CommunityDetail, DirectorySortingEnum } from '../../models/community'
|
||||
import { useCommunities } from '../../hooks/useCommunities'
|
||||
import { getCommunitiesInDirectory } from '../../helpers/apiMock'
|
||||
import { FilterList } from '../Filter'
|
||||
import { Search } from '../Input'
|
||||
import { PageBar } from '../PageBar'
|
||||
import { DirectorySortingOptions } from '../../constants/SortingOptions'
|
||||
import { useConfig } from '../../providers/config'
|
||||
import { Colors } from '../../constants/styles'
|
||||
import { WeeklyFeature } from '../WeeklyFeature'
|
||||
import { DirectoryCardSkeleton } from './DirectoryCardSkeleton'
|
||||
import { useDirectoryCommunities } from '../../hooks/useDirectoryCommunities'
|
||||
import { useContracts } from '../../hooks/useContracts'
|
||||
import { useContractCall } from '@usedapp/core'
|
||||
import { votingFromRoom } from '../../helpers/voting'
|
||||
|
@ -70,14 +68,9 @@ function DirectoryCard({ community }: DirectoryCardProps) {
|
|||
}
|
||||
|
||||
export function DirectoryCards() {
|
||||
const { config } = useConfig()
|
||||
const [filterKeyword, setFilterKeyword] = useState('')
|
||||
const [sortedBy, setSortedBy] = useState(DirectorySortingEnum.IncludedRecently)
|
||||
const { communities, loading } = useCommunities(getCommunitiesInDirectory, {
|
||||
numberPerPage: config.numberPerPage,
|
||||
sortedBy,
|
||||
filterKeyword,
|
||||
})
|
||||
const communities = useDirectoryCommunities(filterKeyword, sortedBy)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -95,14 +88,8 @@ export function DirectoryCards() {
|
|||
{communities.map((community) => (
|
||||
<DirectoryCard key={community.publicKey} community={community} />
|
||||
))}
|
||||
{communities.length === 0 && <DirectoryCardSkeleton />}
|
||||
</Voting>
|
||||
{loading && (
|
||||
<>
|
||||
<DirectoryCardSkeleton />
|
||||
<DirectoryCardSkeleton />
|
||||
<DirectoryCardSkeleton />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
import { CommunityDetail, DirectorySortingEnum, VotingSortingEnum } from '../models/community'
|
||||
import { DetailedVotingRoom } from '../models/smartContract'
|
||||
|
||||
export function isTextInDetails(filterKeyword: string, details: any) {
|
||||
return (
|
||||
details.name.toLowerCase().includes(filterKeyword.toLowerCase()) ||
|
||||
details.description.toLowerCase().includes(filterKeyword.toLowerCase()) ||
|
||||
details.tags.findIndex((item: any) => filterKeyword.toLowerCase() === item.toLowerCase()) > -1
|
||||
)
|
||||
}
|
||||
|
||||
export function isTypeInRoom(voteType: string, room: any) {
|
||||
if (!voteType) {
|
||||
return true
|
||||
}
|
||||
if (voteType === 'Add') {
|
||||
return room.voteType === 1
|
||||
}
|
||||
if (voteType === 'Remove') {
|
||||
return room.voteType === 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export function sortVotingFunction(sortedBy: VotingSortingEnum) {
|
||||
switch (sortedBy) {
|
||||
case VotingSortingEnum.AtoZ:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => (a.details.name < b.details.name ? -1 : 1)
|
||||
case VotingSortingEnum.ZtoA:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => (a.details.name < b.details.name ? 1 : -1)
|
||||
case VotingSortingEnum.EndingLatest:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => {
|
||||
return a.endAt < b.endAt ? -1 : 1
|
||||
}
|
||||
case VotingSortingEnum.EndingSoonest:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => {
|
||||
return a.endAt < b.endAt ? 1 : -1
|
||||
}
|
||||
case VotingSortingEnum.MostVotes:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => {
|
||||
const aSum = a.totalVotesAgainst.add(a.totalVotesFor)
|
||||
const bSum = b.totalVotesAgainst.add(b.totalVotesFor)
|
||||
return aSum < bSum ? 1 : -1
|
||||
}
|
||||
case VotingSortingEnum.LeastVotes:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => {
|
||||
const aSum = a.totalVotesAgainst.add(a.totalVotesFor)
|
||||
const bSum = b.totalVotesAgainst.add(b.totalVotesFor)
|
||||
return aSum < bSum ? -1 : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function sortDirectoryFunction(sortedBy: DirectorySortingEnum) {
|
||||
switch (sortedBy) {
|
||||
case DirectorySortingEnum.AtoZ:
|
||||
return (a: CommunityDetail, b: CommunityDetail) => (a.name < b.name ? -1 : 1)
|
||||
case DirectorySortingEnum.ZtoA:
|
||||
return (a: CommunityDetail, b: CommunityDetail) => (a.name < b.name ? 1 : -1)
|
||||
case DirectorySortingEnum.IncludedLongAgo:
|
||||
return (a: CommunityDetail, b: CommunityDetail) => {
|
||||
if (!a.directoryInfo) return 1
|
||||
if (!b.directoryInfo) return -1
|
||||
return a?.directoryInfo?.additionDate < b?.directoryInfo?.additionDate ? -1 : 1
|
||||
}
|
||||
case DirectorySortingEnum.IncludedRecently:
|
||||
return (a: CommunityDetail, b: CommunityDetail) => {
|
||||
if (!a.directoryInfo) return -1
|
||||
if (!b.directoryInfo) return 1
|
||||
return a?.directoryInfo?.additionDate < b?.directoryInfo?.additionDate ? 1 : -1
|
||||
}
|
||||
case DirectorySortingEnum.MostVotes:
|
||||
return (a: CommunityDetail, b: CommunityDetail) => {
|
||||
if (!a.directoryInfo?.featureVotes) return 1
|
||||
if (!b.directoryInfo?.featureVotes) return -1
|
||||
return a?.directoryInfo?.featureVotes < b?.directoryInfo?.featureVotes ? 1 : -1
|
||||
}
|
||||
case DirectorySortingEnum.LeastVotes:
|
||||
return (a: CommunityDetail, b: CommunityDetail) => {
|
||||
if (!a.directoryInfo?.featureVotes) return 1
|
||||
if (!b.directoryInfo?.featureVotes) return -1
|
||||
return a?.directoryInfo?.featureVotes < b?.directoryInfo?.featureVotes ? -1 : 1
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,19 +2,22 @@ import { useEthers } from '@usedapp/core'
|
|||
import { useConfig } from '../providers/config'
|
||||
import { Contract } from '@usedapp/core/node_modules/ethers'
|
||||
import { Interface } from '@ethersproject/abi'
|
||||
import { MockContract } from '@status-community-dapp/contracts/abi'
|
||||
import { MockContract, Directory } from '@status-community-dapp/contracts/abi'
|
||||
|
||||
export function useContracts() {
|
||||
const { config } = useConfig()
|
||||
const { chainId } = useEthers()
|
||||
|
||||
let votingContract = new Contract('0x0000000000000000000000000000000000000000', new Interface(MockContract.abi))
|
||||
let directoryContract = new Contract('0x0000000000000000000000000000000000000000', new Interface(Directory.abi))
|
||||
|
||||
if (chainId) {
|
||||
const chainConfig = config.contracts[chainId]
|
||||
if (chainConfig) {
|
||||
votingContract = new Contract(chainConfig.votingContract, new Interface(MockContract.abi))
|
||||
directoryContract = new Contract(chainConfig.directoryContract, new Interface(Directory.abi))
|
||||
}
|
||||
}
|
||||
|
||||
return { votingContract }
|
||||
return { votingContract, directoryContract }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import { useContractCall } from '@usedapp/core'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { getCommunityDetails } from '../helpers/apiMock'
|
||||
import { isTextInDetails, sortDirectoryFunction } from '../helpers/communityFiltering'
|
||||
import { CommunityDetail, DirectorySortingEnum } from '../models/community'
|
||||
import { useContracts } from './useContracts'
|
||||
|
||||
export function useDirectoryCommunities(filterKeyword: string, sortedBy: DirectorySortingEnum) {
|
||||
const { directoryContract } = useContracts()
|
||||
const [communities] = useContractCall({
|
||||
abi: directoryContract.interface,
|
||||
address: directoryContract.address,
|
||||
method: 'getCommunities',
|
||||
args: [],
|
||||
}) ?? [[]]
|
||||
|
||||
const [unfilteredComm, setUnfilteredComm] = useState(communities)
|
||||
const [filteredCommunities, setFilteredCommunities] = useState<CommunityDetail[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
const getDetails = async () => {
|
||||
if (communities.length > 0) {
|
||||
const detailedComm = await Promise.all(communities.map(async (key: string) => await getCommunityDetails(key)))
|
||||
setUnfilteredComm(detailedComm)
|
||||
}
|
||||
}
|
||||
getDetails()
|
||||
}, [JSON.stringify(communities)])
|
||||
|
||||
useEffect(() => {
|
||||
const filterCommunities = unfilteredComm.filter((comm: CommunityDetail) => {
|
||||
if (comm) {
|
||||
return isTextInDetails(filterKeyword, comm)
|
||||
}
|
||||
return false
|
||||
})
|
||||
setFilteredCommunities(filterCommunities.sort(sortDirectoryFunction(sortedBy)))
|
||||
}, [unfilteredComm, sortedBy, filterKeyword])
|
||||
|
||||
return filteredCommunities
|
||||
}
|
|
@ -4,56 +4,7 @@ import { getCommunityDetails } from '../helpers/apiMock'
|
|||
import { VotingSortingEnum } from '../models/community'
|
||||
import { DetailedVotingRoom } from '../models/smartContract'
|
||||
import { useContracts } from './useContracts'
|
||||
|
||||
function isTextInRoom(filterKeyword: string, room: any) {
|
||||
return (
|
||||
room.details.name.toLowerCase().includes(filterKeyword.toLowerCase()) ||
|
||||
room.details.description.toLowerCase().includes(filterKeyword.toLowerCase()) ||
|
||||
room.details.tags.findIndex((item: any) => filterKeyword.toLowerCase() === item.toLowerCase()) > -1
|
||||
)
|
||||
}
|
||||
|
||||
function isTypeInRoom(voteType: string, room: any) {
|
||||
if (!voteType) {
|
||||
return true
|
||||
}
|
||||
if (voteType === 'Add') {
|
||||
return room.voteType === 1
|
||||
}
|
||||
if (voteType === 'Remove') {
|
||||
return room.voteType === 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function sortFunction(sortedBy: VotingSortingEnum) {
|
||||
switch (sortedBy) {
|
||||
case VotingSortingEnum.AtoZ:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => (a.details.name < b.details.name ? -1 : 1)
|
||||
case VotingSortingEnum.ZtoA:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => (a.details.name < b.details.name ? 1 : -1)
|
||||
case VotingSortingEnum.EndingLatest:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => {
|
||||
return a.endAt < b.endAt ? -1 : 1
|
||||
}
|
||||
case VotingSortingEnum.EndingSoonest:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => {
|
||||
return a.endAt < b.endAt ? 1 : -1
|
||||
}
|
||||
case VotingSortingEnum.MostVotes:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => {
|
||||
const aSum = a.totalVotesAgainst.add(a.totalVotesFor)
|
||||
const bSum = b.totalVotesAgainst.add(b.totalVotesFor)
|
||||
return aSum < bSum ? 1 : -1
|
||||
}
|
||||
case VotingSortingEnum.LeastVotes:
|
||||
return (a: DetailedVotingRoom, b: DetailedVotingRoom) => {
|
||||
const aSum = a.totalVotesAgainst.add(a.totalVotesFor)
|
||||
const bSum = b.totalVotesAgainst.add(b.totalVotesFor)
|
||||
return aSum < bSum ? -1 : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
import { isTextInDetails, isTypeInRoom, sortVotingFunction } from '../helpers/communityFiltering'
|
||||
|
||||
export function useVotingCommunities(
|
||||
filterKeyword: string,
|
||||
|
@ -102,11 +53,11 @@ export function useVotingCommunities(
|
|||
useEffect(() => {
|
||||
const filteredRooms = roomsWithCommunity.filter((room: any) => {
|
||||
if (room) {
|
||||
return isTextInRoom(filterKeyword, room) && isTypeInRoom(voteType, room)
|
||||
return isTextInDetails(filterKeyword, room.details) && isTypeInRoom(voteType, room)
|
||||
}
|
||||
return false
|
||||
})
|
||||
setFilteredRooms(filteredRooms.sort(sortFunction(sortedBy)))
|
||||
setFilteredRooms(filteredRooms.sort(sortVotingFunction(sortedBy)))
|
||||
}, [roomsWithCommunity, filterKeyword, voteType, sortedBy])
|
||||
|
||||
return filteredRooms
|
||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react'
|
|||
import { render } from 'react-dom'
|
||||
import { App } from './App'
|
||||
import { DAppProvider, ChainId } from '@usedapp/core'
|
||||
import { DEFAULT_CONFIG } from '@usedapp/core/dist/cjs/src/model/config/default'
|
||||
import { ConfigProvider } from './providers/config/provider'
|
||||
import { WakuProvider } from './providers/waku/provider'
|
||||
|
||||
|
@ -10,6 +11,11 @@ const config = {
|
|||
readOnlyUrls: {
|
||||
[ChainId.Ropsten]: 'https://ropsten.infura.io/v3/b4451d780cc64a078ccf2181e872cfcf',
|
||||
},
|
||||
multicallAddresses: {
|
||||
...DEFAULT_CONFIG.multicallAddresses,
|
||||
1337: '0x049e017b504F85d3c07AFE712fC79501aa1DB712',
|
||||
},
|
||||
supportedChains: [...DEFAULT_CONFIG.supportedChains, 1337],
|
||||
}
|
||||
|
||||
render(
|
||||
|
|
|
@ -16,23 +16,28 @@ interface EnvConfigs {
|
|||
|
||||
const contracts = {
|
||||
3: {
|
||||
votingContract: '0x942C8248d14c20b9E79d7A60178B5b17Dd7186c3',
|
||||
votingContract: '0xDAd243C1D47f25b129001181F09c53F93B66c721',
|
||||
directoryContract: '0x78055B8E0fD4a130f4D3536EfdcF0A5617077D24',
|
||||
},
|
||||
1337: {
|
||||
votingContract: '0x7623410b03A75B75133488032886c1E6Fb58222f',
|
||||
directoryContract: '0xD17456480B991979a2882395a5Def44F8C48282C',
|
||||
},
|
||||
}
|
||||
|
||||
export const config: EnvConfigs = {
|
||||
localhost: {
|
||||
wakuTopic: `/myApp/localhost/${uuidv4()}/0.0.2/votingRoom/`,
|
||||
wakuTopic: `/myApp/localhost/${uuidv4()}/0.0.3/votingRoom/`,
|
||||
numberPerPage: 2,
|
||||
contracts,
|
||||
},
|
||||
development: {
|
||||
wakuTopic: '/myApp/development/0.0.2/votingRoom/',
|
||||
wakuTopic: '/myApp/development/0.0.3/votingRoom/',
|
||||
numberPerPage: 3,
|
||||
contracts,
|
||||
},
|
||||
production: {
|
||||
wakuTopic: '/myApp/production/0.0.2/votingRoom/',
|
||||
wakuTopic: '/myApp/production/0.0.3/votingRoom/',
|
||||
numberPerPage: 4,
|
||||
contracts,
|
||||
},
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import MockContract from './../build/MockContract.json'
|
||||
import Directory from './../build/Directory.json'
|
||||
|
||||
export { MockContract }
|
||||
export { MockContract, Directory }
|
|
@ -0,0 +1,25 @@
|
|||
import { ethers } from 'ethers'
|
||||
import { deployContract } from 'ethereum-waffle'
|
||||
import MockContract from '../build/MockContract.json'
|
||||
import Directory from '../build/Directory.json'
|
||||
|
||||
const deploy = async () => {
|
||||
const providerName = process.env.ETHEREUM_PROVIDER
|
||||
const privateKey = process.env.ETHEREUM_PRIVATE_KEY
|
||||
console.log(privateKey)
|
||||
if (privateKey && providerName) {
|
||||
console.log(`deploying on ${providerName}`)
|
||||
const provider = ethers.getDefaultProvider(process.env.ETHEREUM_PROVIDER)
|
||||
const wallet = new ethers.Wallet(privateKey, provider)
|
||||
|
||||
const mockContract = await deployContract(wallet, MockContract)
|
||||
console.log(`Voting contract deployed with address: ${mockContract.address}`)
|
||||
|
||||
const directoryContract = await deployContract(wallet,Directory,[mockContract.address])
|
||||
await mockContract.setDirectory(directoryContract.address)
|
||||
console.log(`Directory contract deployed with address: ${directoryContract.address}`)
|
||||
}
|
||||
}
|
||||
|
||||
deploy()
|
||||
|
|
@ -78,7 +78,7 @@ describe('Contract', () => {
|
|||
await provider.send('evm_mine', [Math.floor(Date.now() / 1000)])
|
||||
return { contract, directory, alice, firstAddress, secondAddress, provider }
|
||||
}
|
||||
|
||||
loadFixture(fixture)
|
||||
it('deploys properly', async () => {
|
||||
const { contract, directory } = await loadFixture(fixture)
|
||||
expect(await contract.directory()).to.eq(directory.address)
|
||||
|
|
Loading…
Reference in New Issue