1
0
mirror of https://github.com/oceanprotocol/react.git synced 2025-02-14 21:10:38 +01:00

Merge pull request #120 from oceanprotocol/feature/usecallback

fix hooks dependencies
This commit is contained in:
mihaisc 2020-09-24 13:06:49 +03:00 committed by GitHub
commit c93784720b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 134 additions and 113 deletions

View File

@ -1,8 +1,7 @@
import { useState } from 'react' import { useState } from 'react'
import { useOcean } from '../../providers' import { useOcean } from '../../providers'
import { ComputeValue } from './ComputeOptions' import { ComputeValue } from './ComputeOptions'
import { feedback } from './../../utils' import { Logger } from '@oceanprotocol/lib'
import { DID, Logger } from '@oceanprotocol/lib'
import { MetadataAlgorithm } from '@oceanprotocol/lib/dist/node/ddo/interfaces/MetadataAlgorithm' import { MetadataAlgorithm } from '@oceanprotocol/lib/dist/node/ddo/interfaces/MetadataAlgorithm'
import { ComputeJob } from '@oceanprotocol/lib/dist/node/ocean/interfaces/ComputeJob' import { ComputeJob } from '@oceanprotocol/lib/dist/node/ocean/interfaces/ComputeJob'
import { checkAndBuyDT } from '../../utils/dtUtils' import { checkAndBuyDT } from '../../utils/dtUtils'
@ -14,7 +13,7 @@ interface UseCompute {
dataTokenAddress: string, dataTokenAddress: string,
algorithmRawCode: string, algorithmRawCode: string,
computeContainer: ComputeValue computeContainer: ComputeValue
) => Promise<ComputeJob> ) => Promise<ComputeJob | void>
computeStep?: number computeStep?: number
computeStepText?: string computeStepText?: string
computeError?: string computeError?: string
@ -45,7 +44,13 @@ function useCompute(): UseCompute {
const [computeError, setComputeError] = useState<string | undefined>() const [computeError, setComputeError] = useState<string | undefined>()
const [isLoading, setIsLoading] = useState(false) const [isLoading, setIsLoading] = useState(false)
function setStep(index: number) { function setStep(index?: number) {
if (!index) {
setComputeStep(undefined)
setComputeStepText(undefined)
return
}
setComputeStep(index) setComputeStep(index)
setComputeStepText(computeFeedback[index]) setComputeStepText(computeFeedback[index])
} }
@ -56,7 +61,7 @@ function useCompute(): UseCompute {
dataTokenAddress: string, dataTokenAddress: string,
algorithmRawCode: string, algorithmRawCode: string,
computeContainer: ComputeValue computeContainer: ComputeValue
): Promise<ComputeJob> { ): Promise<ComputeJob | void> {
if (!ocean || !account) return if (!ocean || !account) return
setComputeError(undefined) setComputeError(undefined)

View File

@ -1,4 +1,4 @@
import { useState, useEffect } from 'react' import { useState, useEffect, useCallback } from 'react'
import { DID, DDO, Metadata, Logger } from '@oceanprotocol/lib' import { DID, DDO, Metadata, Logger } from '@oceanprotocol/lib'
import { useOcean } from '../../providers' import { useOcean } from '../../providers'
import ProviderStatus from '../../providers/OceanProvider/ProviderStatus' import ProviderStatus from '../../providers/OceanProvider/ProviderStatus'
@ -7,83 +7,100 @@ import { isDDO } from '../../utils'
import BestPrice from './BestPrice' import BestPrice from './BestPrice'
interface UseMetadata { interface UseMetadata {
ddo: DDO ddo: DDO | undefined
did: DID | string did: DID | string | undefined
metadata: Metadata metadata: Metadata | undefined
title: string title: string | undefined
price: BestPrice price: BestPrice | undefined
isLoaded: boolean isLoaded: boolean
getPrice: (dataTokenAddress?: string) => Promise<BestPrice> getPrice: (dataTokenAddress: string) => Promise<BestPrice | void>
} }
function useMetadata(asset?: DID | string | DDO): UseMetadata { function useMetadata(asset?: DID | string | DDO): UseMetadata {
const { ocean, status, accountId } = useOcean() const { ocean, status, accountId, chainId } = useOcean()
const [internalDdo, setDDO] = useState<DDO | undefined>() const [internalDdo, setDDO] = useState<DDO>()
const [internalDid, setDID] = useState<DID | string | undefined>() const [internalDid, setDID] = useState<DID | string>()
const [metadata, setMetadata] = useState<Metadata | undefined>() const [metadata, setMetadata] = useState<Metadata>()
const [title, setTitle] = useState<string | undefined>() const [title, setTitle] = useState<string>()
const [isLoaded, setIsLoaded] = useState(false) const [isLoaded, setIsLoaded] = useState(false)
const [price, setPrice] = useState<BestPrice | undefined>() const [price, setPrice] = useState<BestPrice>()
async function getDDO(did: DID | string): Promise<DDO | null> {
if (status !== ProviderStatus.CONNECTED) return null
const getDDO = useCallback(
async (did: DID | string): Promise<DDO> => {
const ddo = await ocean.metadatastore.retrieveDDO(did) const ddo = await ocean.metadatastore.retrieveDDO(did)
return ddo return ddo
} },
[ocean?.metadatastore]
)
async function getPrice(dataTokenAddress?: string): Promise<BestPrice> { const getPrice = useCallback(
if (!dataTokenAddress) dataTokenAddress = internalDdo.dataToken async (dataTokenAddress: string): Promise<BestPrice> => {
return await getBestDataTokenPrice(ocean, dataTokenAddress, accountId) const price = await getBestDataTokenPrice(
} ocean,
dataTokenAddress,
accountId
)
return price
},
[ocean, accountId]
)
async function getMetadata(): Promise<Metadata | null> { const getMetadata = useCallback(async (ddo: DDO): Promise<Metadata> => {
if (!internalDdo) return null const metadata = ddo.findServiceByType('metadata')
const metadata = internalDdo.findServiceByType('metadata')
return metadata.attributes return metadata.attributes
} }, [])
//
// Get and set DDO based on passed DDO or DID
//
useEffect(() => { useEffect(() => {
if (!asset || !ocean || status !== ProviderStatus.CONNECTED) return
async function init(): Promise<void> { async function init(): Promise<void> {
if (ocean && status === ProviderStatus.CONNECTED) {
if (!asset) return if (!asset) return
if (isDDO(asset)) { if (isDDO(asset as string | DDO | DID)) {
setDDO(asset) setDDO(asset as DDO)
setDID(asset.id) setDID((asset as DDO).id)
} else { } else {
const ddo = await getDDO(asset) // asset is a DID
const ddo = await getDDO(asset as DID)
Logger.debug('DDO', ddo) Logger.debug('DDO', ddo)
setDDO(ddo) setDDO(ddo)
setDID(asset) setDID(asset as DID)
}
} }
} }
init() init()
}, [ocean, status]) }, [ocean, status, asset, getDDO])
//
// Get metadata for stored DDO
//
useEffect(() => { useEffect(() => {
if (!accountId) return if (!accountId) return
async function init(): Promise<void> { async function init(): Promise<void> {
if (internalDdo) { if (!internalDdo) return
const metadata = await getMetadata()
const metadata = await getMetadata(internalDdo)
setMetadata(metadata) setMetadata(metadata)
setTitle(metadata.main.name) setTitle(metadata.main.name)
const price = await getPrice() const price = await getPrice(internalDdo.dataToken)
price && setPrice(price)
setPrice(price)
setIsLoaded(true) setIsLoaded(true)
} }
}
init() init()
const interval = setInterval(async () => { const interval = setInterval(async () => {
const price = await getPrice() if (!internalDdo) return
setPrice(price) const price = await getPrice(internalDdo.dataToken)
price && setPrice(price)
}, 10000) }, 10000)
return () => clearInterval(interval)
}, [accountId, internalDdo]) return () => {
clearInterval(interval)
}
}, [accountId, chainId, internalDdo, getMetadata, getPrice])
return { return {
ddo: internalDdo, ddo: internalDdo,

View File

@ -49,7 +49,7 @@ function usePublish(): UsePublish {
): Promise<void | null> { ): Promise<void | null> {
switch (priceOptions.type) { switch (priceOptions.type) {
case 'dynamic': { case 'dynamic': {
const pool = await ocean.pool.createDTPool( await ocean.pool.createDTPool(
accountId, accountId,
dataTokenAddress, dataTokenAddress,
priceOptions.tokensToMint.toString(), priceOptions.tokensToMint.toString(),
@ -64,7 +64,7 @@ function usePublish(): UsePublish {
return null return null
} }
const fixedPriceExchange = await ocean.fixedRateExchange.create( await ocean.fixedRateExchange.create(
dataTokenAddress, dataTokenAddress,
priceOptions.price.toString(), priceOptions.price.toString(),
accountId accountId

View File

@ -3,7 +3,9 @@ import React, {
useState, useState,
useEffect, useEffect,
createContext, createContext,
ReactElement ReactElement,
useCallback,
ReactNode
} from 'react' } from 'react'
import Web3 from 'web3' import Web3 from 'web3'
import ProviderStatus from './ProviderStatus' import ProviderStatus from './ProviderStatus'
@ -42,7 +44,7 @@ function OceanProvider({
}: { }: {
initialConfig: Config initialConfig: Config
web3ModalOpts?: Partial<ICoreOptions> web3ModalOpts?: Partial<ICoreOptions>
children: any children: ReactNode
}): ReactElement { }): ReactElement {
const [web3, setWeb3] = useState<Web3 | undefined>() const [web3, setWeb3] = useState<Web3 | undefined>()
const [web3Provider, setWeb3Provider] = useState<any | undefined>() const [web3Provider, setWeb3Provider] = useState<any | undefined>()
@ -60,22 +62,23 @@ function OceanProvider({
ProviderStatus.NOT_AVAILABLE ProviderStatus.NOT_AVAILABLE
) )
async function init() { const init = useCallback(async () => {
Logger.log('Ocean Provider init') Logger.log('Ocean Provider init')
window && window &&
window.ethereum && window.ethereum &&
(window.ethereum.autoRefreshOnNetworkChange = false) (window.ethereum.autoRefreshOnNetworkChange = false)
Logger.log('Web3Modal init.') Logger.log('Web3Modal init.')
if (web3ModalOpts === undefined) {
web3ModalOpts = await getDefaultProviders() const web3ModalInstance = new Web3Modal(
} web3ModalOpts || (await getDefaultProviders())
const web3ModalInstance = new Web3Modal(web3ModalOpts) )
setWeb3Modal(web3ModalInstance) setWeb3Modal(web3ModalInstance)
Logger.log('Web3Modal instance created.', web3ModalInstance) Logger.log('Web3Modal instance created.', web3ModalInstance)
} }, [web3ModalOpts])
async function connect(newConfig?: Config) { const connect = useCallback(
async (newConfig?: Config) => {
try { try {
Logger.log('Connecting ...', newConfig) Logger.log('Connecting ...', newConfig)
@ -113,18 +116,20 @@ function OceanProvider({
} catch (error) { } catch (error) {
Logger.error(error) Logger.error(error)
} }
} },
[config, web3Modal]
)
// On mount setup Web3Modal instance // On mount setup Web3Modal instance
useEffect(() => { useEffect(() => {
init() init()
}, []) }, [init])
// Connect automatically to cached provider if present // Connect automatically to cached provider if present
useEffect(() => { useEffect(() => {
if (!web3Modal) return if (!web3Modal) return
web3Modal.cachedProvider && connect() web3Modal.cachedProvider && connect()
}, [web3Modal]) }, [web3Modal, connect])
async function refreshBalance() { async function refreshBalance() {
const balance = account && (await getBalance(account)) const balance = account && (await getBalance(account))
@ -135,14 +140,13 @@ function OceanProvider({
web3Modal?.clearCachedProvider() web3Modal?.clearCachedProvider()
} }
// TODO: #68 Refetch balance periodically, or figure out some event to subscribe to
useEffect(() => {
const handleAccountsChanged = async (accounts: string[]) => { const handleAccountsChanged = async (accounts: string[]) => {
Logger.debug("Handling 'accountsChanged' event with payload", accounts) Logger.debug("Handling 'accountsChanged' event with payload", accounts)
connect() connect()
} }
// TODO: #68 Refetch balance periodically, or figure out some event to subscribe to
useEffect(() => {
// web3Modal && web3Modal.on('connect', handleConnect) // web3Modal && web3Modal.on('connect', handleConnect)
if (web3Provider !== undefined && web3Provider !== null) { if (web3Provider !== undefined && web3Provider !== null) {
@ -154,7 +158,7 @@ function OceanProvider({
// web3Provider.removeListener('chainChanged', handleNetworkChanged) // web3Provider.removeListener('chainChanged', handleNetworkChanged)
} }
} }
}, [web3Modal, web3Provider]) }, [web3Modal, web3Provider, connect])
return ( return (
<OceanContext.Provider <OceanContext.Provider

View File

@ -50,8 +50,7 @@ export async function getCheapestPool(
export async function getCheapestExchange( export async function getCheapestExchange(
ocean: Ocean, ocean: Ocean,
dataTokenAddress: string dataTokenAddress: string
): Promise<{ address?: string; price: string } | null> { ): Promise<{ address?: string; price: string }> {
if (!ocean || !dataTokenAddress) return
try { try {
const tokenExchanges = await ocean.fixedRateExchange.searchforDT( const tokenExchanges = await ocean.fixedRateExchange.searchforDT(
dataTokenAddress, dataTokenAddress,
@ -94,7 +93,7 @@ export async function getBestDataTokenPrice(
ocean: Ocean, ocean: Ocean,
dataTokenAddress: string, dataTokenAddress: string,
accountId: string accountId: string
): Promise<BestPrice | undefined> { ): Promise<BestPrice> {
const cheapestPool = await getCheapestPool(ocean, accountId, dataTokenAddress) const cheapestPool = await getCheapestPool(ocean, accountId, dataTokenAddress)
const cheapestExchange = await getCheapestExchange(ocean, dataTokenAddress) const cheapestExchange = await getCheapestExchange(ocean, dataTokenAddress)
Decimal.set({ precision: 5 }) Decimal.set({ precision: 5 })

View File

@ -11,11 +11,7 @@
"sourceMap": true, "sourceMap": true,
"declaration": true, "declaration": true,
"importHelpers": true, "importHelpers": true,
"strict": true
/* Strict Type-Checking */
// TODO: remove and adapt for `strictNullChecks`
"strict": true,
"strictNullChecks": false
}, },
"include": ["./src/@types", "./src/index.ts"] "include": ["./src/@types", "./src/index.ts"]
} }