diff --git a/packages/ui/src/accounts/hooks/useTransactionFee.ts b/packages/ui/src/accounts/hooks/useTransactionFee.ts index 7570a2ab9f..9c0e405c41 100644 --- a/packages/ui/src/accounts/hooks/useTransactionFee.ts +++ b/packages/ui/src/accounts/hooks/useTransactionFee.ts @@ -1,45 +1,24 @@ import { SubmittableExtrinsic } from '@polkadot/api/types' import { ISubmittableResult } from '@polkadot/types/types' import BN from 'bn.js' -import { useEffect, useMemo, useRef } from 'react' -import { map, takeUntil, timer, merge, switchAll, defaultIfEmpty, of, Observable, Subject } from 'rxjs' +import { useEffect, useMemo } from 'react' import { BN_ZERO } from '@/common/constants' +import { useDefaultAfterTimeout } from '@/common/hooks/useDefaultAfterTimeout' import { useObservable } from '@/common/hooks/useObservable' import { useTransactionStatus } from '@/common/hooks/useTransactionStatus' import { Address } from '@/common/types' +import { whenDefined } from '@/common/utils' import { useBalance } from './useBalance' -const defaultWhenTimeout = - (fallback: T, timeout: number) => - (source: Observable) => - source.pipe( - takeUntil(timer(timeout)), - defaultIfEmpty(fallback), - map((data) => merge(of(data), source)), - switchAll() - ) - export function useTransactionFee(address?: Address, transaction?: SubmittableExtrinsic<'rxjs', ISubmittableResult>) { const { status, setStatus } = useTransactionStatus() - const transactionStream = useRef(new Subject>()) - const partialFee = useObservable( - transactionStream.current.pipe( - map((observable, index) => (index === 0 ? observable.pipe(defaultWhenTimeout(BN_ZERO, 1000)) : observable)), - switchAll() - ), - [] + const paymentInfo = useObservable( + whenDefined(address, (address) => transaction?.paymentInfo(address)), + [transaction, address] ) - - useEffect(() => { - if (transaction && address) { - transactionStream.current.next( - transaction.paymentInfo(address).pipe(map((paymentInfo) => paymentInfo.partialFee)) - ) - } - }, [transaction, address]) - + const partialFee = useDefaultAfterTimeout(paymentInfo?.partialFee, 3000, BN_ZERO) const balance = useBalance(address) useEffect(() => { diff --git a/packages/ui/src/common/hooks/useDefaultAfterTimeout.ts b/packages/ui/src/common/hooks/useDefaultAfterTimeout.ts new file mode 100644 index 0000000000..71fc86051f --- /dev/null +++ b/packages/ui/src/common/hooks/useDefaultAfterTimeout.ts @@ -0,0 +1,23 @@ +import { DependencyList, useEffect, useState } from 'react' + +import { isDefined } from '@/common/utils' + +export const useDefaultAfterTimeout = ( + value: T | undefined, + delay: number, + defaultValue: T, + deps: DependencyList = [value] +) => { + const [result, setResult] = useState(value) + + useEffect(() => value && setResult(value), [deps]) + + useEffect(() => { + if (!isDefined(result)) { + const timeout = setTimeout(() => setResult(defaultValue), delay) + return () => clearTimeout(timeout) + } + }, [result]) + + return result +}