// Copyright 2017-2025 @pezkuwi/react-components authors & contributors // SPDX-License-Identifier: Apache-2.0 import type { SubmittableResult } from '@pezkuwi/api'; import type { SubmittableExtrinsic } from '@pezkuwi/api/types'; import type { TxButtonProps as Props } from './types.js'; import React, { useCallback, useEffect, useState } from 'react'; import { useIsMountedRef, useQueue } from '@pezkuwi/react-hooks'; import { assert, isFunction } from '@pezkuwi/util'; import Button from './Button/index.js'; import { useTranslation } from './translate.js'; function TxButton ({ accountId, className = '', extrinsic: propsExtrinsic, icon, isBasic, isBusy, isDisabled, isIcon, isToplevel, isUnsigned, label, onClick, onFailed, onSendRef, onStart, onSuccess, onUpdate, params, tooltip, tx, withSpinner, withoutLink }: Props): React.ReactElement { const { t } = useTranslation(); const mountedRef = useIsMountedRef(); const { queueExtrinsic } = useQueue(); const [isSending, setIsSending] = useState(false); const [isStarted, setIsStarted] = useState(false); useEffect((): void => { (isStarted && onStart) && onStart(); }, [isStarted, onStart]); const _onFailed = useCallback( (result: Error | SubmittableResult | null): void => { mountedRef.current && setIsSending(false); onFailed && onFailed(result); }, [onFailed, setIsSending, mountedRef] ); const _onSuccess = useCallback( (result: SubmittableResult): void => { mountedRef.current && setIsSending(false); onSuccess && onSuccess(result); }, [onSuccess, setIsSending, mountedRef] ); const _onStart = useCallback( (): void => { mountedRef.current && setIsStarted(true); }, [setIsStarted, mountedRef] ); const _onSend = useCallback( (): void => { let extrinsics: SubmittableExtrinsic<'promise'>[] | undefined; if (propsExtrinsic) { extrinsics = Array.isArray(propsExtrinsic) ? propsExtrinsic : [propsExtrinsic]; } else if (tx) { extrinsics = [ tx(...( isFunction(params) ? params() : (params || []) )) ]; } assert(extrinsics?.length, 'Expected generated extrinsic passed to TxButton'); mountedRef.current && withSpinner && setIsSending(true); extrinsics.forEach((extrinsic): void => { queueExtrinsic({ accountId: accountId?.toString(), extrinsic, isUnsigned, txFailedCb: withSpinner ? _onFailed : onFailed, txStartCb: _onStart, txSuccessCb: withSpinner ? _onSuccess : onSuccess, txUpdateCb: onUpdate }); }); onClick && onClick(); }, [_onFailed, _onStart, _onSuccess, accountId, isUnsigned, mountedRef, onClick, onFailed, onSuccess, onUpdate, params, propsExtrinsic, queueExtrinsic, tx, withSpinner] ); if (onSendRef) { onSendRef.current = _onSend; } return (