From b1bb3fe48477050dc722e4980bf7e2252446b91b Mon Sep 17 00:00:00 2001 From: gregs Date: Wed, 4 Dec 2024 14:02:21 -0300 Subject: [PATCH 01/11] aa --- .../Swap/hooks/useSearchCurrencyLists.ts | 44 ++++++++++++------- src/analytics/event.ts | 10 +++++ .../asset-list/RecyclerAssetList2/index.tsx | 1 + src/utils/reviewAlert.ts | 2 +- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/__swaps__/screens/Swap/hooks/useSearchCurrencyLists.ts b/src/__swaps__/screens/Swap/hooks/useSearchCurrencyLists.ts index 82e78bed66c..f6800c925c8 100644 --- a/src/__swaps__/screens/Swap/hooks/useSearchCurrencyLists.ts +++ b/src/__swaps__/screens/Swap/hooks/useSearchCurrencyLists.ts @@ -15,6 +15,7 @@ import { TokenToBuyListItem } from '../components/TokenList/TokenToBuyList'; import { useSwapContext } from '../providers/swap-provider'; import { RecentSwap } from '@/__swaps__/types/swap'; import { useTokenDiscovery } from '../resources/search'; +import { analyticsV2 } from '@/analytics'; export type AssetToBuySectionId = 'bridge' | 'recent' | 'favorites' | 'verified' | 'unverified' | 'other_networks' | 'popular'; @@ -429,21 +430,34 @@ export function useSearchCurrencyLists() { const verifiedResults = query === '' ? verifiedAssets : verifiedAssets?.filter(asset => asset.chainId === toChainId); const unverifiedResults = memoizedData.enableUnverifiedSearch ? unverifiedAssets : undefined; - return { - results: buildListSectionsData({ - combinedData: { - bridgeAsset: bridgeResult, - crosschainExactMatches: crosschainMatches, - unverifiedAssets: unverifiedResults, - verifiedAssets: verifiedResults, - recentSwaps: recentsForChain, - popularAssets: popularAssetsForChain, - }, - favoritesList, - filteredBridgeAssetAddress: memoizedData.filteredBridgeAsset?.address, - }), - isLoading: isLoadingVerifiedAssets || isLoadingUnverifiedAssets || isLoadingPopularAssets, - }; + const results = buildListSectionsData({ + combinedData: { + bridgeAsset: bridgeResult, + crosschainExactMatches: crosschainMatches, + unverifiedAssets: unverifiedResults, + verifiedAssets: verifiedResults, + recentSwaps: recentsForChain, + popularAssets: popularAssetsForChain, + }, + favoritesList, + filteredBridgeAssetAddress: memoizedData.filteredBridgeAsset?.address, + }); + + const isLoading = isLoadingVerifiedAssets || isLoadingUnverifiedAssets || isLoadingPopularAssets; + + if (!isLoading) { + let total_tokens = 0; + let no_icon = 0; + for (const assetOrHeader of results) { + if (assetOrHeader.listItemType === 'header') continue; + const asset = assetOrHeader; + if (!asset.icon_url) no_icon += 1; + total_tokens += 1; + } + analyticsV2.track(analyticsV2.event.tokenList, { screen: 'swap', total_tokens, no_icon }); + } + + return { results, isLoading }; }, [ favoritesList, isLoadingUnverifiedAssets, diff --git a/src/analytics/event.ts b/src/analytics/event.ts index 8beb36d4e45..5a68f06537d 100644 --- a/src/analytics/event.ts +++ b/src/analytics/event.ts @@ -158,6 +158,9 @@ export const event = { claimClaimableSucceeded: 'claim_claimable.succeeded', claimClaimableFailed: 'claim_claimable.failed', claimablePanelOpened: 'claimable_panel.opened', + + // Token Lists + tokenList: 'token_list', } as const; type SwapEventParameters = { @@ -643,4 +646,11 @@ export type EventProperties = { amount: string; usdValue: number; }; + + [event.tokenList]: { + screen: 'wallet' | 'swap' | 'send' | 'discover'; + total_tokens: number; + no_icon: number; + no_price?: number; + }; }; diff --git a/src/components/asset-list/RecyclerAssetList2/index.tsx b/src/components/asset-list/RecyclerAssetList2/index.tsx index 779bce675da..31d66491eae 100644 --- a/src/components/asset-list/RecyclerAssetList2/index.tsx +++ b/src/components/asset-list/RecyclerAssetList2/index.tsx @@ -18,6 +18,7 @@ import ContextMenuButton from '@/components/native-context-menu/contextMenu'; import { analytics } from '@/analytics'; import lang from 'i18n-js'; import { IS_ANDROID } from '@/env'; +import { useTimeout } from '@/hooks'; export type AssetListType = 'wallet' | 'ens-profile' | 'select-nft'; diff --git a/src/utils/reviewAlert.ts b/src/utils/reviewAlert.ts index dfbda01e918..9770bf6ab34 100644 --- a/src/utils/reviewAlert.ts +++ b/src/utils/reviewAlert.ts @@ -78,7 +78,7 @@ export const promptForReview = async () => { onPress: async () => { try { ls.review.set(['hasReviewed'], true); - await StoreReview.requestReview(); + // await StoreReview.requestReview(); } catch (e) { logger.error(new RainbowError('[reviewAlert]: Failed to request review'), { error: e, From 49b13634ac4988b52abeb3e2033b3fbd1706db3a Mon Sep 17 00:00:00 2001 From: gregs Date: Wed, 4 Dec 2024 14:05:07 -0300 Subject: [PATCH 02/11] af --- src/utils/reviewAlert.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/reviewAlert.ts b/src/utils/reviewAlert.ts index 9770bf6ab34..dfbda01e918 100644 --- a/src/utils/reviewAlert.ts +++ b/src/utils/reviewAlert.ts @@ -78,7 +78,7 @@ export const promptForReview = async () => { onPress: async () => { try { ls.review.set(['hasReviewed'], true); - // await StoreReview.requestReview(); + await StoreReview.requestReview(); } catch (e) { logger.error(new RainbowError('[reviewAlert]: Failed to request review'), { error: e, From bf5a34c432ee46e2907a73e4a67825886c79d517 Mon Sep 17 00:00:00 2001 From: gregs Date: Thu, 5 Dec 2024 11:57:27 -0300 Subject: [PATCH 03/11] useTimeoutEffect --- .../UniqueTokenExpandedState.tsx | 7 +++--- .../asset/ChartExpandedState.js | 6 ++--- src/hooks/useTimeout.ts | 23 ++++++++++++++----- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/components/expanded-state/UniqueTokenExpandedState.tsx b/src/components/expanded-state/UniqueTokenExpandedState.tsx index a16b843bfa5..338a3c56c35 100644 --- a/src/components/expanded-state/UniqueTokenExpandedState.tsx +++ b/src/components/expanded-state/UniqueTokenExpandedState.tsx @@ -417,18 +417,17 @@ const UniqueTokenExpandedState = ({ asset: passedAsset, external }: UniqueTokenE const hideNftMarketplaceAction = isPoap || !slug; - const mountedAt = useRef(Date.now()); useTimeoutEffect( - () => { + ({ elapsedTime }) => { const { address, chainId } = getAddressAndChainIdFromUniqueId(uniqueId); const { name, description, image_url } = asset; analyticsV2.track(analyticsV2.event.tokenDetailsNFT, { - eventSentAfterMs: Date.now() - mountedAt.current, + eventSentAfterMs: elapsedTime, token: { isPoap, isParty: !!isParty, isENS, address, chainId, name, image_url }, available_data: { description: !!description, image_url: !!image_url, floorPrice: !!offer?.floorPrice }, }); }, - 5 * 1000 // 5s + { delay: 5 * 1000 } ); return ( <> diff --git a/src/components/expanded-state/asset/ChartExpandedState.js b/src/components/expanded-state/asset/ChartExpandedState.js index 136e3eeb4ce..7ef245fd071 100644 --- a/src/components/expanded-state/asset/ChartExpandedState.js +++ b/src/components/expanded-state/asset/ChartExpandedState.js @@ -260,15 +260,15 @@ export default function ChartExpandedState({ asset }) { const mountedAt = useRef(Date.now()); useTimeoutEffect( - () => { + ({ elapsedTime }) => { const { address, chainId, symbol, name, icon_url, price } = assetWithPrice; analyticsV2.track(analyticsV2.event.tokenDetailsErc20, { - eventSentAfterMs: Date.now() - mountedAt.current, + eventSentAfterMs: elapsedTime, token: { address, chainId, symbol, name, icon_url, price }, available_data: { chart: showChart, description: !!data?.description, iconUrl: !!icon_url }, }); }, - 5 * 1000 // 5s + { delay: 5 * 1000 } ); return ( diff --git a/src/hooks/useTimeout.ts b/src/hooks/useTimeout.ts index 3c663ea779c..d49f4182725 100644 --- a/src/hooks/useTimeout.ts +++ b/src/hooks/useTimeout.ts @@ -18,7 +18,10 @@ export default function useTimeout(): [(func: () => void, ms?: number) => void, return [start, stop, handle]; } -export function useTimeoutEffect(onTimeout: (cancelled: boolean) => void, delay: number) { +export function useTimeoutEffect( + onTimeout: (e: { cancelled: boolean; elapsedTime: number }) => void, + { delay, enabled = true }: { delay: number; enabled?: boolean } +) { const callback = useRef(onTimeout); useLayoutEffect(() => { callback.current = onTimeout; @@ -26,12 +29,20 @@ export function useTimeoutEffect(onTimeout: (cancelled: boolean) => void, delay: const timeoutRef = useRef(); useEffect(() => { + if (!enabled) return; const startedAt = Date.now(); - timeoutRef.current = setTimeout(() => callback.current(false), delay); - const timeout = timeoutRef.current; + timeoutRef.current = setTimeout(() => { + callback.current({ + cancelled: false, + elapsedTime: Date.now() - startedAt, + }); + }, delay); return () => { - clearTimeout(timeout); - if (Date.now() - startedAt < delay) callback.current(true); + clearTimeout(timeoutRef.current); + const elapsedTime = Date.now() - startedAt; + if (elapsedTime < delay) { + callback.current({ cancelled: true, elapsedTime }); + } }; - }, [delay]); + }, [delay, enabled]); } From 3f1d5a8556eccb985fe90ebd615068aff3b447c9 Mon Sep 17 00:00:00 2001 From: gregs Date: Thu, 5 Dec 2024 13:11:30 -0300 Subject: [PATCH 04/11] useTimeoutEffect --- .../expanded-state/UniqueTokenExpandedState.tsx | 2 +- src/components/expanded-state/asset/ChartExpandedState.js | 2 +- src/hooks/useTimeout.ts | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/expanded-state/UniqueTokenExpandedState.tsx b/src/components/expanded-state/UniqueTokenExpandedState.tsx index 338a3c56c35..1d2dcafbcae 100644 --- a/src/components/expanded-state/UniqueTokenExpandedState.tsx +++ b/src/components/expanded-state/UniqueTokenExpandedState.tsx @@ -427,7 +427,7 @@ const UniqueTokenExpandedState = ({ asset: passedAsset, external }: UniqueTokenE available_data: { description: !!description, image_url: !!image_url, floorPrice: !!offer?.floorPrice }, }); }, - { delay: 5 * 1000 } + { timeout: 5 * 1000 } ); return ( <> diff --git a/src/components/expanded-state/asset/ChartExpandedState.js b/src/components/expanded-state/asset/ChartExpandedState.js index 7ef245fd071..e881d8f5ae5 100644 --- a/src/components/expanded-state/asset/ChartExpandedState.js +++ b/src/components/expanded-state/asset/ChartExpandedState.js @@ -268,7 +268,7 @@ export default function ChartExpandedState({ asset }) { available_data: { chart: showChart, description: !!data?.description, iconUrl: !!icon_url }, }); }, - { delay: 5 * 1000 } + { timeout: 5 * 1000 } ); return ( diff --git a/src/hooks/useTimeout.ts b/src/hooks/useTimeout.ts index d49f4182725..2150f3c3d22 100644 --- a/src/hooks/useTimeout.ts +++ b/src/hooks/useTimeout.ts @@ -20,7 +20,7 @@ export default function useTimeout(): [(func: () => void, ms?: number) => void, export function useTimeoutEffect( onTimeout: (e: { cancelled: boolean; elapsedTime: number }) => void, - { delay, enabled = true }: { delay: number; enabled?: boolean } + { timeout, enabled = true }: { timeout: number; enabled?: boolean } ) { const callback = useRef(onTimeout); useLayoutEffect(() => { @@ -36,13 +36,13 @@ export function useTimeoutEffect( cancelled: false, elapsedTime: Date.now() - startedAt, }); - }, delay); + }, timeout); return () => { clearTimeout(timeoutRef.current); const elapsedTime = Date.now() - startedAt; - if (elapsedTime < delay) { + if (elapsedTime < timeout) { callback.current({ cancelled: true, elapsedTime }); } }; - }, [delay, enabled]); + }, [timeout, enabled]); } From a68ce5532d61b2d5b07365fab3a9d215b6f1cf69 Mon Sep 17 00:00:00 2001 From: gregs Date: Thu, 5 Dec 2024 13:31:11 -0300 Subject: [PATCH 05/11] track token lists --- .../Swap/hooks/useSearchCurrencyLists.ts | 29 ++++++++++--------- src/analytics/event.ts | 2 ++ src/hooks/useWalletSectionsData.ts | 11 +++++++ src/resources/assets/useSortedUserAssets.ts | 3 +- src/screens/SendSheet.tsx | 15 ++++++++-- 5 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/__swaps__/screens/Swap/hooks/useSearchCurrencyLists.ts b/src/__swaps__/screens/Swap/hooks/useSearchCurrencyLists.ts index f6800c925c8..03ac19f3181 100644 --- a/src/__swaps__/screens/Swap/hooks/useSearchCurrencyLists.ts +++ b/src/__swaps__/screens/Swap/hooks/useSearchCurrencyLists.ts @@ -8,7 +8,7 @@ import { useFavorites } from '@/resources/favorites'; import { useSwapsStore } from '@/state/swaps/swapsStore'; import { isAddress } from '@ethersproject/address'; import { rankings } from 'match-sorter'; -import { useCallback, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { runOnJS, useAnimatedReaction } from 'react-native-reanimated'; import { useDebouncedCallback } from 'use-debounce'; import { TokenToBuyListItem } from '../components/TokenList/TokenToBuyList'; @@ -423,7 +423,7 @@ export function useSearchCurrencyLists() { } ); - return useMemo(() => { + const searchCurrencyLists = useMemo(() => { const toChainId = selectedOutputChainId.value ?? ChainId.mainnet; const bridgeResult = memoizedData.filteredBridgeAsset ?? undefined; const crosschainMatches = query === '' ? undefined : verifiedAssets?.filter(asset => asset.chainId !== toChainId); @@ -445,18 +445,6 @@ export function useSearchCurrencyLists() { const isLoading = isLoadingVerifiedAssets || isLoadingUnverifiedAssets || isLoadingPopularAssets; - if (!isLoading) { - let total_tokens = 0; - let no_icon = 0; - for (const assetOrHeader of results) { - if (assetOrHeader.listItemType === 'header') continue; - const asset = assetOrHeader; - if (!asset.icon_url) no_icon += 1; - total_tokens += 1; - } - analyticsV2.track(analyticsV2.event.tokenList, { screen: 'swap', total_tokens, no_icon }); - } - return { results, isLoading }; }, [ favoritesList, @@ -472,4 +460,17 @@ export function useSearchCurrencyLists() { recentsForChain, popularAssetsForChain, ]); + + useEffect(() => { + if (searchCurrencyLists.isLoading) return; + const params = { screen: 'swap' as const, total_tokens: 0, no_icon: 0, query }; + for (const assetOrHeader of searchCurrencyLists.results) { + if (assetOrHeader.listItemType === 'header') continue; + if (!assetOrHeader.icon_url) params.no_icon += 1; + params.total_tokens += 1; + } + analyticsV2.track(analyticsV2.event.tokenList, params); + }, [searchCurrencyLists.results, searchCurrencyLists.isLoading, query]); + + return searchCurrencyLists; } diff --git a/src/analytics/event.ts b/src/analytics/event.ts index 15708db526d..47a5abc0b35 100644 --- a/src/analytics/event.ts +++ b/src/analytics/event.ts @@ -703,5 +703,7 @@ export type EventProperties = { total_tokens: number; no_icon: number; no_price?: number; + query?: string; // query is only sent for the swap screen + eventSentAfterMs?: number; }; }; diff --git a/src/hooks/useWalletSectionsData.ts b/src/hooks/useWalletSectionsData.ts index a14a4aa525a..4f6f7a8937c 100644 --- a/src/hooks/useWalletSectionsData.ts +++ b/src/hooks/useWalletSectionsData.ts @@ -20,6 +20,7 @@ import { useUserAssetsStore } from '@/state/assets/userAssets'; import { analyticsV2 } from '@/analytics'; import { Claimable } from '@/resources/addys/claimables/types'; import { throttle } from 'lodash'; +import { useTimeoutEffect } from './useTimeout'; // user properties analytics for claimables that executes at max once every 2 min const throttledClaimablesAnalytics = throttle( @@ -98,6 +99,16 @@ export default function useWalletSectionsData({ const { isCoinListEdited } = useCoinListEdited(); + useEffect(() => { + if (isLoadingUserAssets || type !== 'wallet') return; + const params = { screen: 'wallet' as const, no_icon: 0, no_price: 0, total_tokens: sortedAssets.length }; + for (const asset of sortedAssets) { + if (!asset.icon_url) params.no_icon += 1; + if (!asset.price?.relative_change_24h) params.no_price += 1; + } + analyticsV2.track(analyticsV2.event.tokenList, params); + }, [isLoadingUserAssets, sortedAssets, type]); + const walletSections = useMemo(() => { const accountInfo = { hiddenAssets, diff --git a/src/resources/assets/useSortedUserAssets.ts b/src/resources/assets/useSortedUserAssets.ts index b7e80d92c71..ce3a1780b94 100644 --- a/src/resources/assets/useSortedUserAssets.ts +++ b/src/resources/assets/useSortedUserAssets.ts @@ -2,6 +2,7 @@ import { useAccountSettings } from '@/hooks'; import { selectSortedUserAssets } from '@/resources/assets/assetSelectors'; import { useUserAssets } from '@/resources/assets/UserAssetsQuery'; import { useConnectedToHardhatStore } from '@/state/connectedToHardhat'; +import { useCallback } from 'react'; export function useSortedUserAssets() { const { accountAddress, nativeCurrency } = useAccountSettings(); @@ -14,7 +15,7 @@ export function useSortedUserAssets() { connectedToHardhat, }, { - select: selectSortedUserAssets(nativeCurrency), + select: useCallback(selectSortedUserAssets(nativeCurrency), [nativeCurrency]), } ); } diff --git a/src/screens/SendSheet.tsx b/src/screens/SendSheet.tsx index eca3f922fa2..3041b75006f 100644 --- a/src/screens/SendSheet.tsx +++ b/src/screens/SendSheet.tsx @@ -10,7 +10,7 @@ import { SendAssetForm, SendAssetList, SendContactList, SendHeader } from '../co import { SheetActionButton } from '../components/sheet'; import { getDefaultCheckboxes } from './SendConfirmationSheet'; import { WrappedAlert as Alert } from '@/helpers/alert'; -import { analytics } from '@/analytics'; +import { analytics, analyticsV2 } from '@/analytics'; import { PROFILES, useExperimentalFlag } from '@/config'; import { AssetTypes, NewTransaction, ParsedAddressAsset, TransactionStatus, UniqueAsset } from '@/entities'; import { isNativeAsset } from '@/handlers/assets'; @@ -70,6 +70,7 @@ import { ThemeContextProps, useTheme } from '@/theme'; import { StaticJsonRpcProvider } from '@ethersproject/providers'; import { Contact } from '@/redux/contacts'; import { useUserAssetsStore } from '@/state/assets/userAssets'; +import { useTimeoutEffect } from '@/hooks/useTimeout'; const sheetHeight = deviceUtils.dimensions.height - (IS_ANDROID ? 30 : 10); const statusBarHeight = IS_IOS ? safeAreaInsetValues.top : StatusBar.currentHeight; @@ -117,7 +118,7 @@ type OnSubmitProps = { export default function SendSheet() { const { goBack, navigate } = useNavigation(); - const { data: sortedAssets } = useSortedUserAssets(); + const { isLoading: isLoadingUserAssets, data: sortedAssets } = useSortedUserAssets(); const { gasFeeParamsBySpeed, gasLimit, @@ -883,6 +884,16 @@ export default function SendSheet() { isUniqueAsset, ]); + useEffect(() => { + if (isLoadingUserAssets || !sortedAssets) return; + const params = { screen: 'wallet' as const, no_icon: 0, no_price: 0, total_tokens: sortedAssets.length }; + for (const asset of sortedAssets) { + if (!asset.icon_url) params.no_icon += 1; + if (!asset.price?.relative_change_24h) params.no_price += 1; + } + analyticsV2.track(analyticsV2.event.tokenList, params); + }, [isLoadingUserAssets, sortedAssets]); + const sendContactListDataKey = useMemo(() => `${ensSuggestions?.[0]?.address || '_'}`, [ensSuggestions]); const isEmptyWallet = !sortedAssets?.length && !sendableUniqueTokens?.length; From 3d66ecb359f840678a35da111ea92c722af6eceb Mon Sep 17 00:00:00 2001 From: gregs Date: Thu, 5 Dec 2024 13:34:47 -0300 Subject: [PATCH 06/11] cleanup --- src/components/asset-list/RecyclerAssetList2/index.tsx | 1 - src/components/expanded-state/asset/ChartExpandedState.js | 1 - src/hooks/useWalletSectionsData.ts | 1 - src/screens/SendSheet.tsx | 1 - 4 files changed, 4 deletions(-) diff --git a/src/components/asset-list/RecyclerAssetList2/index.tsx b/src/components/asset-list/RecyclerAssetList2/index.tsx index 31d66491eae..779bce675da 100644 --- a/src/components/asset-list/RecyclerAssetList2/index.tsx +++ b/src/components/asset-list/RecyclerAssetList2/index.tsx @@ -18,7 +18,6 @@ import ContextMenuButton from '@/components/native-context-menu/contextMenu'; import { analytics } from '@/analytics'; import lang from 'i18n-js'; import { IS_ANDROID } from '@/env'; -import { useTimeout } from '@/hooks'; export type AssetListType = 'wallet' | 'ens-profile' | 'select-nft'; diff --git a/src/components/expanded-state/asset/ChartExpandedState.js b/src/components/expanded-state/asset/ChartExpandedState.js index e881d8f5ae5..3beddad8150 100644 --- a/src/components/expanded-state/asset/ChartExpandedState.js +++ b/src/components/expanded-state/asset/ChartExpandedState.js @@ -258,7 +258,6 @@ export default function ChartExpandedState({ asset }) { [nativeCurrency] ); - const mountedAt = useRef(Date.now()); useTimeoutEffect( ({ elapsedTime }) => { const { address, chainId, symbol, name, icon_url, price } = assetWithPrice; diff --git a/src/hooks/useWalletSectionsData.ts b/src/hooks/useWalletSectionsData.ts index 4f6f7a8937c..e558f9016f8 100644 --- a/src/hooks/useWalletSectionsData.ts +++ b/src/hooks/useWalletSectionsData.ts @@ -20,7 +20,6 @@ import { useUserAssetsStore } from '@/state/assets/userAssets'; import { analyticsV2 } from '@/analytics'; import { Claimable } from '@/resources/addys/claimables/types'; import { throttle } from 'lodash'; -import { useTimeoutEffect } from './useTimeout'; // user properties analytics for claimables that executes at max once every 2 min const throttledClaimablesAnalytics = throttle( diff --git a/src/screens/SendSheet.tsx b/src/screens/SendSheet.tsx index 3041b75006f..31110d9affa 100644 --- a/src/screens/SendSheet.tsx +++ b/src/screens/SendSheet.tsx @@ -70,7 +70,6 @@ import { ThemeContextProps, useTheme } from '@/theme'; import { StaticJsonRpcProvider } from '@ethersproject/providers'; import { Contact } from '@/redux/contacts'; import { useUserAssetsStore } from '@/state/assets/userAssets'; -import { useTimeoutEffect } from '@/hooks/useTimeout'; const sheetHeight = deviceUtils.dimensions.height - (IS_ANDROID ? 30 : 10); const statusBarHeight = IS_IOS ? safeAreaInsetValues.top : StatusBar.currentHeight; From dc99eb1acb0d04128317290236f5665ef92fdd4a Mon Sep 17 00:00:00 2001 From: gregs Date: Thu, 5 Dec 2024 13:37:28 -0300 Subject: [PATCH 07/11] a --- src/analytics/event.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/analytics/event.ts b/src/analytics/event.ts index 47a5abc0b35..8d257b2de04 100644 --- a/src/analytics/event.ts +++ b/src/analytics/event.ts @@ -704,6 +704,5 @@ export type EventProperties = { no_icon: number; no_price?: number; query?: string; // query is only sent for the swap screen - eventSentAfterMs?: number; }; }; From b00d02978c1768dfe4dee077528dd2f2951478db Mon Sep 17 00:00:00 2001 From: gregs Date: Mon, 9 Dec 2024 13:51:36 -0300 Subject: [PATCH 08/11] fix --- src/hooks/useTimeout.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hooks/useTimeout.ts b/src/hooks/useTimeout.ts index 2150f3c3d22..a7d6d44b505 100644 --- a/src/hooks/useTimeout.ts +++ b/src/hooks/useTimeout.ts @@ -38,6 +38,7 @@ export function useTimeoutEffect( }); }, timeout); return () => { + if (!timeoutRef.current) return; clearTimeout(timeoutRef.current); const elapsedTime = Date.now() - startedAt; if (elapsedTime < timeout) { From c6f844a86d72e3ca3c5207ef243040422bb86d8d Mon Sep 17 00:00:00 2001 From: gregs Date: Tue, 10 Dec 2024 14:26:31 -0300 Subject: [PATCH 09/11] fix --- src/screens/SendSheet.tsx | 2 +- src/screens/WalletScreen/index.tsx | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/screens/SendSheet.tsx b/src/screens/SendSheet.tsx index 31110d9affa..8c0bf695683 100644 --- a/src/screens/SendSheet.tsx +++ b/src/screens/SendSheet.tsx @@ -885,7 +885,7 @@ export default function SendSheet() { useEffect(() => { if (isLoadingUserAssets || !sortedAssets) return; - const params = { screen: 'wallet' as const, no_icon: 0, no_price: 0, total_tokens: sortedAssets.length }; + const params = { screen: 'send' as const, no_icon: 0, no_price: 0, total_tokens: sortedAssets.length }; for (const asset of sortedAssets) { if (!asset.icon_url) params.no_icon += 1; if (!asset.price?.relative_change_24h) params.no_price += 1; diff --git a/src/screens/WalletScreen/index.tsx b/src/screens/WalletScreen/index.tsx index 2e99229db52..5bc92d08eea 100644 --- a/src/screens/WalletScreen/index.tsx +++ b/src/screens/WalletScreen/index.tsx @@ -46,7 +46,12 @@ function WalletScreen() { const { wallets } = useWallets(); const walletReady = useSelector(({ appState: { walletReady } }: AppState) => walletReady); - const { isWalletEthZero, isLoadingUserAssets, isLoadingBalance, briefSectionsData: walletBriefSectionsData } = useWalletSectionsData(); + const { + isWalletEthZero, + isLoadingUserAssets, + isLoadingBalance, + briefSectionsData: walletBriefSectionsData, + } = useWalletSectionsData({ type: 'wallet' }); const trackWallets = useCallback(() => { const identify = Object.values(wallets || {}).reduce( From 0686f020a3e52d3e1e7deade57cde688d63fdfd0 Mon Sep 17 00:00:00 2001 From: gregs Date: Thu, 19 Dec 2024 17:03:25 -0300 Subject: [PATCH 10/11] track discovery screen --- .../discover/components/DiscoverSearch.tsx | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/screens/discover/components/DiscoverSearch.tsx b/src/screens/discover/components/DiscoverSearch.tsx index 1eacade9724..71a82a33076 100644 --- a/src/screens/discover/components/DiscoverSearch.tsx +++ b/src/screens/discover/components/DiscoverSearch.tsx @@ -7,7 +7,7 @@ import deviceUtils from '@/utils/deviceUtils'; import CurrencySelectionList from '@/components/CurrencySelectionList'; import { Row } from '@/components/layout'; import { useDiscoverScreenContext } from '../DiscoverScreenContext'; -import { analytics } from '@/analytics'; +import { analytics, analyticsV2 } from '@/analytics'; import { PROFILES, useExperimentalFlag } from '@/config'; import { useAccountSettings, useSearchCurrencyList, usePrevious, useHardwareBackOnFocus } from '@/hooks'; import { useNavigation } from '@/navigation'; @@ -25,6 +25,7 @@ import { useTheme } from '@/theme'; import { EnrichedExchangeAsset } from '@/components/ExchangeAssetList'; import { useBackendNetworksStore } from '@/state/backendNetworks/backendNetworks'; import { ChainId, Network } from '@/state/backendNetworks/types'; +import { useTimeoutEffect } from '@/hooks/useTimeout'; export const SearchContainer = styled(Row)({ height: '100%', @@ -270,6 +271,29 @@ export default function DiscoverSearch() { }); }, [sectionListRef, isSearching]); + useTimeoutEffect( + () => { + const assets = currencyList + .filter(a => a.key !== 'profiles') + .map(asset => asset.data) + .flat(); + if (assets.length === 0) return; + const params = { + screen: 'discover' as const, + no_icon: 0, + no_price: 0, + total_tokens: assets.length, + query: searchQueryForSearch, + }; + for (const asset of assets) { + if (!asset.icon_url) params.no_icon += 1; + if (!isNaN(asset.price?.value)) params.no_price += 1; + } + analyticsV2.track(analyticsV2.event.tokenList, params); + }, + { timeout: 3000, enabled: !isLoading } + ); + return ( From 5310111b0d62e790ffd470390e06e19479ece96e Mon Sep 17 00:00:00 2001 From: gregs Date: Fri, 20 Dec 2024 09:21:54 -0300 Subject: [PATCH 11/11] ops --- src/screens/SendSheet.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/screens/SendSheet.tsx b/src/screens/SendSheet.tsx index e38b69ae38c..5de228be886 100644 --- a/src/screens/SendSheet.tsx +++ b/src/screens/SendSheet.tsx @@ -117,6 +117,7 @@ type OnSubmitProps = { export default function SendSheet() { const { goBack, navigate } = useNavigation(); const sortedAssets = useUserAssetsStore(state => state.legacyUserAssets); + const isLoadingUserAssets = useUserAssetsStore(state => state.isLoadingUserAssets); const { gasFeeParamsBySpeed, gasLimit,