import { useCallback, useEffect, useRef } from "react"; import { useDebounce } from "reactjs-view-core"; import { useTranslation } from "react-i18next"; import { useAuth } from "react-oidc-js"; import { usePostOtcV1PublicOtcConvertPreview } from "../../services"; import { useAssets } from "../useAssets"; import { useDisplayDecimalDigits } from "../useDisplayDecimalDigits"; import { ConvertContext } from "./context"; const REFRESH_TIME = 8000; const REFRESH_COUNT = 5; export const useUpdatePreview = ({ mode, type, }: { mode: "from" | "to"; type: "limit" | "market"; }) => { const { fromAmount, toAmount, lastChangedField, fromAsset, toAsset, isPreviewOpen, } = ConvertContext.useWatch(); const [deobunceAmount] = useDebounce( 500, mode === "from" ? fromAmount : toAmount, ); const { userData } = useAuth(); const { t } = useTranslation(); const { setValue, setError } = ConvertContext.useFormContext(); const { isValid } = ConvertContext.useFormState(); const { getAssetBySymbol } = useAssets(); const { truncFix } = useDisplayDecimalDigits(); const { mutate: requestPreview } = usePostOtcV1PublicOtcConvertPreview({ onSuccess: ({ finalDestinationQuantity, finalSourceQuantity, sourceCurrencySymbol, destinationCurrencySymbol, }) => { if (mode === "from" && type === "market") { setValue( "toAmount", truncFix( finalDestinationQuantity, destinationCurrencySymbol, ).toString(), ); } else { setValue( "fromAmount", truncFix(finalSourceQuantity, sourceCurrencySymbol).toString(), ); } const availableRemain = sourceCurrencySymbol ? getAssetBySymbol(sourceCurrencySymbol)?.availableRemain || 0 : 0; if ( availableRemain < finalSourceQuantity && isValid && userData !== null ) { lastChangedField === "to" && setError("toAmount", { message: " " }); return setError("fromAmount", { message: t("insufficientBalance") }); } }, }); const request = useCallback(() => { if ( deobunceAmount && fromAsset && toAsset && lastChangedField === mode && !isPreviewOpen ) { requestPreview({ requestBody: { validityDurationInSecond: 10, sourceQuantity: lastChangedField === "from" ? Number(deobunceAmount) : undefined, destinationQunatity: lastChangedField === "to" ? Number(deobunceAmount) : undefined, destinationCurrencySymbol: toAsset, sourceCurrencySymbol: fromAsset, }, }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [ deobunceAmount, fromAsset, isPreviewOpen, lastChangedField, mode, requestPreview, toAsset, ]); const refreshCount = useRef(0); useEffect(() => { request(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [deobunceAmount, lastChangedField]); useEffect(() => { const interval = setInterval(() => { if (refreshCount.current >= REFRESH_COUNT) { return; } request(); refreshCount.current = refreshCount.current + 1; }, REFRESH_TIME); return () => { if (interval) clearInterval(interval); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [deobunceAmount]); return { resetRefreshCount: () => (refreshCount.current = 0), }; };