import { groupBy, map } from "lodash-es"; import { useCallback, useEffect, useMemo, useRef } from "react"; import { useTranslation } from "react-i18next"; import { useAuth } from "react-oidc-js"; import { CurrencyResponseVM, RequestError, useGetCapitalV1PublicCurrencyAll, useGetWalletV1PrivateUserassetSpotDefaultAll, UserAssetResponseVM, } from "../services"; export type Asset = UserAssetResponseVM & CurrencyResponseVM & { displayName: string }; const useAssets = ({ onSuccess, onError, }: { onSuccess?: (data: Asset[]) => void; onError?: (error?: RequestError | Error | null) => void; } = {}) => { const { userData } = useAuth(); const { i18n } = useTranslation(); const { data: privateUserAssets, isInitialLoading: isLoadingUserAsset, error: errorUserAsset, remove: removeUserAssets, refetch: refetchUserAssets, } = useGetWalletV1PrivateUserassetSpotDefaultAll({ enabled: __MOCK__ || !!userData?.access_token, onError: (e) => onError?.(e), }); const { data: assets, isLoading: isAssetLoading, error: errorAssets, remove: removeAssets, refetch: refetchAssets, } = useGetCapitalV1PublicCurrencyAll({ cacheTime: Infinity, staleTime: Infinity, onError: (e) => onError?.(e), }); const refetch = () => { refetchUserAssets(); refetchAssets(); }; useEffect(() => { if (userData === null) { removeUserAssets(); } }, [removeUserAssets, userData]); const { allAssets, userAssets } = useMemo<{ allAssets: Asset[] | undefined; userAssets: Asset[] | undefined; }>(() => { const groupedUserAssets = groupBy(privateUserAssets, (coin) => coin.symbol); const groupedAssets = groupBy(assets, (coin) => coin.symbol); return { allAssets: assets ? map(groupedAssets, (asset) => { const userAsset = groupedUserAssets[asset[0].symbol!]; return { ...asset[0], ...userAsset?.[0], displayName: (i18n.language === "fa" ? asset?.[0]?.persianName : asset?.[0]?.name) || "", }; }) : undefined, userAssets: privateUserAssets ? map(groupedUserAssets, (asset) => { const userAsset = groupedAssets[asset[0].symbol!]; return { ...asset[0], ...userAsset?.[0], displayName: (i18n.language === "fa" ? userAsset?.[0]?.persianName : userAsset?.[0]?.name) || "", }; }) : undefined, }; }, [assets, i18n.language, privateUserAssets]); const isOnSuccessCalled = useRef(false); const isOnErrorCalled = useRef(false); useEffect(() => { if (!allAssets) return; if (onSuccess && !isOnSuccessCalled.current) { isOnSuccessCalled.current = true; onSuccess(allAssets); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [allAssets]); useEffect(() => { if (errorAssets || errorUserAsset) { if (onError && !isOnErrorCalled.current) { isOnErrorCalled.current = true; onError?.(errorAssets || errorUserAsset); } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [errorAssets, errorUserAsset]); const remove = useCallback(() => { removeUserAssets(); removeAssets(); }, [removeAssets, removeUserAssets]); const getAssetBySymbol = useCallback( (symbol: string) => { return allAssets?.find( (i) => i.symbol?.toLowerCase() === symbol.toLowerCase(), ); }, [allAssets], ); return { allAssets, userAssets, errorUserAsset, remove, isLoading: isAssetLoading || isLoadingUserAsset, error: errorUserAsset || errorAssets, refetch, getAssetBySymbol, }; }; export { useAssets };