1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00
Matthias Kretschmann 94139f42b4
fix marketFeeAddress (#633)
* fix marketFeeAddress

* UseSiteMetadata typing fixes
2021-05-31 12:53:37 +02:00

179 lines
4.9 KiB
TypeScript

import React, { ReactElement, useEffect, useState } from 'react'
import { toast } from 'react-toastify'
import { File as FileMetadata, DDO } from '@oceanprotocol/lib'
import File from '../../atoms/File'
import Price from '../../atoms/Price'
import Web3Feedback from '../../molecules/Wallet/Feedback'
import styles from './Consume.module.css'
import { useSiteMetadata } from '../../../hooks/useSiteMetadata'
import { useAsset } from '../../../providers/Asset'
import { secondsToString } from '../../../utils/metadata'
import { gql, useQuery } from '@apollo/client'
import { OrdersData } from '../../../@types/apollo/OrdersData'
import BigNumber from 'bignumber.js'
import { useOcean } from '../../../providers/Ocean'
import { useWeb3 } from '../../../providers/Web3'
import { usePricing } from '../../../hooks/usePricing'
import { useConsume } from '../../../hooks/useConsume'
import ButtonBuy from '../../atoms/ButtonBuy'
const previousOrderQuery = gql`
query PreviousOrder($id: String!, $account: String!) {
tokenOrders(
first: 1
where: { datatokenId: $id, payer: $account }
orderBy: timestamp
orderDirection: desc
) {
timestamp
tx
}
}
`
export default function Consume({
ddo,
file,
isBalanceSufficient,
dtBalance
}: {
ddo: DDO
file: FileMetadata
isBalanceSufficient: boolean
dtBalance: string
}): ReactElement {
const { accountId } = useWeb3()
const { ocean } = useOcean()
const { appConfig } = useSiteMetadata()
const [hasPreviousOrder, setHasPreviousOrder] = useState(false)
const [previousOrderId, setPreviousOrderId] = useState<string>()
const { isInPurgatory, price, type } = useAsset()
const {
buyDT,
pricingStepText,
pricingError,
pricingIsLoading
} = usePricing()
const { consumeStepText, consume, consumeError } = useConsume()
const [isDisabled, setIsDisabled] = useState(true)
const [hasDatatoken, setHasDatatoken] = useState(false)
const [isConsumable, setIsConsumable] = useState(true)
const [assetTimeout, setAssetTimeout] = useState('')
const { data } = useQuery<OrdersData>(previousOrderQuery, {
variables: {
id: ddo.dataToken?.toLowerCase(),
account: accountId?.toLowerCase()
},
pollInterval: 5000
})
useEffect(() => {
if (!data || !assetTimeout || data.tokenOrders.length === 0) return
const lastOrder = data.tokenOrders[0]
if (assetTimeout === 'Forever') {
setPreviousOrderId(lastOrder.tx)
setHasPreviousOrder(true)
} else {
const expiry = new BigNumber(lastOrder.timestamp).plus(assetTimeout)
const unixTime = new BigNumber(Math.floor(Date.now() / 1000))
if (unixTime.isLessThan(expiry)) {
setPreviousOrderId(lastOrder.tx)
setHasPreviousOrder(true)
} else {
setHasPreviousOrder(false)
}
}
}, [data, assetTimeout])
useEffect(() => {
const { timeout } = ddo.findServiceByType('access').attributes.main
setAssetTimeout(secondsToString(timeout))
}, [ddo])
useEffect(() => {
if (!price) return
setIsConsumable(
price.isConsumable !== undefined ? price.isConsumable === 'true' : true
)
}, [price])
useEffect(() => {
setHasDatatoken(Number(dtBalance) >= 1)
}, [dtBalance])
useEffect(() => {
setIsDisabled(
(!ocean ||
!isBalanceSufficient ||
typeof consumeStepText !== 'undefined' ||
pricingIsLoading ||
!isConsumable) &&
!hasPreviousOrder &&
!hasDatatoken
)
}, [
ocean,
hasPreviousOrder,
isBalanceSufficient,
consumeStepText,
pricingIsLoading,
isConsumable,
hasDatatoken
])
async function handleConsume() {
!hasPreviousOrder && !hasDatatoken && (await buyDT('1', price, ddo))
await consume(
ddo.id,
ddo.dataToken,
'access',
appConfig.marketFeeAddress,
previousOrderId
)
setHasPreviousOrder(true)
}
// Output errors in UI
useEffect(() => {
consumeError && toast.error(consumeError)
pricingError && toast.error(pricingError)
}, [consumeError, pricingError])
const PurchaseButton = () => (
<ButtonBuy
action="download"
disabled={isDisabled}
hasPreviousOrder={hasPreviousOrder}
hasDatatoken={hasDatatoken}
dtSymbol={ddo.dataTokenInfo?.symbol}
dtBalance={dtBalance}
onClick={handleConsume}
assetTimeout={assetTimeout}
assetType={type}
stepText={consumeStepText || pricingStepText}
isLoading={pricingIsLoading}
/>
)
return (
<aside className={styles.consume}>
<div className={styles.info}>
<div className={styles.filewrapper}>
<File file={file} />
</div>
<div className={styles.pricewrapper}>
<Price price={price} conversion />
{!isInPurgatory && <PurchaseButton />}
</div>
</div>
<footer className={styles.feedback}>
<Web3Feedback isBalanceSufficient={isBalanceSufficient} />
</footer>
</aside>
)
}