Commit 774368f3 authored by eddie's avatar eddie Committed by GitHub

feat: page wallet connect txn completed (#6655)

* feat: add page to wallet_connect_txn_completed event

* feat: unit test

* fix: test
parent f83f15d3
...@@ -9,6 +9,7 @@ import { Connection, ConnectionType } from 'connection/types' ...@@ -9,6 +9,7 @@ import { Connection, ConnectionType } from 'connection/types'
import useEagerlyConnect from 'hooks/useEagerlyConnect' import useEagerlyConnect from 'hooks/useEagerlyConnect'
import useOrderedConnections from 'hooks/useOrderedConnections' import useOrderedConnections from 'hooks/useOrderedConnections'
import { Provider } from 'react-redux' import { Provider } from 'react-redux'
import { HashRouter } from 'react-router-dom'
import store from 'state' import store from 'state'
import { mocked } from 'test-utils/mocked' import { mocked } from 'test-utils/mocked'
...@@ -36,9 +37,11 @@ function last<T>(array: T[]): T { ...@@ -36,9 +37,11 @@ function last<T>(array: T[]): T {
} }
const UI = ( const UI = (
<Provider store={store}> <HashRouter>
<Web3Provider>{null}</Web3Provider> <Provider store={store}>
</Provider> <Web3Provider>{null}</Web3Provider>
</Provider>
</HashRouter>
) )
describe('Web3Provider', () => { describe('Web3Provider', () => {
......
...@@ -11,7 +11,9 @@ import useEagerlyConnect from 'hooks/useEagerlyConnect' ...@@ -11,7 +11,9 @@ import useEagerlyConnect from 'hooks/useEagerlyConnect'
import useOrderedConnections from 'hooks/useOrderedConnections' import useOrderedConnections from 'hooks/useOrderedConnections'
import usePrevious from 'hooks/usePrevious' import usePrevious from 'hooks/usePrevious'
import { ReactNode, useEffect, useMemo } from 'react' import { ReactNode, useEffect, useMemo } from 'react'
import { useLocation } from 'react-router-dom'
import { useConnectedWallets } from 'state/wallets/hooks' import { useConnectedWallets } from 'state/wallets/hooks'
import { getCurrentPageFromLocation } from 'utils/urlRoutes'
export default function Web3Provider({ children }: { children: ReactNode }) { export default function Web3Provider({ children }: { children: ReactNode }) {
useEagerlyConnect() useEagerlyConnect()
...@@ -31,6 +33,8 @@ export default function Web3Provider({ children }: { children: ReactNode }) { ...@@ -31,6 +33,8 @@ export default function Web3Provider({ children }: { children: ReactNode }) {
/** A component to run hooks under the Web3ReactProvider context. */ /** A component to run hooks under the Web3ReactProvider context. */
function Updater() { function Updater() {
const { account, chainId, connector, provider } = useWeb3React() const { account, chainId, connector, provider } = useWeb3React()
const { pathname } = useLocation()
const currentPage = getCurrentPageFromLocation(pathname)
// Trace RPC calls (for debugging). // Trace RPC calls (for debugging).
const networkProvider = isSupportedChain(chainId) ? RPC_PROVIDERS[chainId] : undefined const networkProvider = isSupportedChain(chainId) ? RPC_PROVIDERS[chainId] : undefined
...@@ -76,11 +80,22 @@ function Updater() { ...@@ -76,11 +80,22 @@ function Updater() {
wallet_type: walletType, wallet_type: walletType,
is_reconnect: isReconnect, is_reconnect: isReconnect,
peer_wallet_agent: peerWalletAgent, peer_wallet_agent: peerWalletAgent,
page: currentPage,
}) })
addConnectedWallet({ account, walletType }) addConnectedWallet({ account, walletType })
} }
}, [account, addConnectedWallet, chainId, connectedWallets, connector, getConnection, previousAccount, provider]) }, [
account,
addConnectedWallet,
currentPage,
chainId,
connectedWallets,
connector,
getConnection,
previousAccount,
provider,
])
return null return null
} }
......
...@@ -4,8 +4,10 @@ import { Connection } from 'connection/types' ...@@ -4,8 +4,10 @@ import { Connection } from 'connection/types'
import { atom } from 'jotai' import { atom } from 'jotai'
import { useAtomValue, useUpdateAtom } from 'jotai/utils' import { useAtomValue, useUpdateAtom } from 'jotai/utils'
import { useCallback } from 'react' import { useCallback } from 'react'
import { useLocation } from 'react-router-dom'
import { useAppDispatch } from 'state/hooks' import { useAppDispatch } from 'state/hooks'
import { updateSelectedWallet } from 'state/user/reducer' import { updateSelectedWallet } from 'state/user/reducer'
import { getCurrentPageFromLocation } from 'utils/urlRoutes'
import { didUserReject } from './utils' import { didUserReject } from './utils'
...@@ -25,6 +27,8 @@ const activationStateAtom = atom<ActivationState>(IDLE_ACTIVATION_STATE) ...@@ -25,6 +27,8 @@ const activationStateAtom = atom<ActivationState>(IDLE_ACTIVATION_STATE)
function useTryActivation() { function useTryActivation() {
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const setActivationState = useUpdateAtom(activationStateAtom) const setActivationState = useUpdateAtom(activationStateAtom)
const { pathname } = useLocation()
const currentPage = getCurrentPageFromLocation(pathname)
return useCallback( return useCallback(
async (connection: Connection, onSuccess: () => void) => { async (connection: Connection, onSuccess: () => void) => {
...@@ -60,11 +64,12 @@ function useTryActivation() { ...@@ -60,11 +64,12 @@ function useTryActivation() {
sendAnalyticsEvent(InterfaceEventName.WALLET_CONNECT_TXN_COMPLETED, { sendAnalyticsEvent(InterfaceEventName.WALLET_CONNECT_TXN_COMPLETED, {
result: WalletConnectionResult.FAILED, result: WalletConnectionResult.FAILED,
wallet_type: connection.getName(), wallet_type: connection.getName(),
page: currentPage,
}) })
setActivationState({ status: ActivationStatus.ERROR, connection, error }) setActivationState({ status: ActivationStatus.ERROR, connection, error })
} }
}, },
[dispatch, setActivationState] [currentPage, dispatch, setActivationState]
) )
} }
......
import { getDeviceId, sendAnalyticsEvent, Trace, user } from '@uniswap/analytics' import { getDeviceId, sendAnalyticsEvent, Trace, user } from '@uniswap/analytics'
import { CustomUserProperties, getBrowser, InterfacePageName, SharedEventName } from '@uniswap/analytics-events' import { CustomUserProperties, getBrowser, SharedEventName } from '@uniswap/analytics-events'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import Loader from 'components/Icons/LoadingSpinner' import Loader from 'components/Icons/LoadingSpinner'
import TopLevelModals from 'components/TopLevelModals' import TopLevelModals from 'components/TopLevelModals'
...@@ -19,6 +19,7 @@ import { Z_INDEX } from 'theme/zIndex' ...@@ -19,6 +19,7 @@ import { Z_INDEX } from 'theme/zIndex'
import { STATSIG_DUMMY_KEY } from 'tracing' import { STATSIG_DUMMY_KEY } from 'tracing'
import { getEnvName } from 'utils/env' import { getEnvName } from 'utils/env'
import { retry } from 'utils/retry' import { retry } from 'utils/retry'
import { getCurrentPageFromLocation } from 'utils/urlRoutes'
import { getCLS, getFCP, getFID, getLCP, Metric } from 'web-vitals' import { getCLS, getFCP, getFID, getLCP, Metric } from 'web-vitals'
import { useAnalyticsReporter } from '../components/analytics' import { useAnalyticsReporter } from '../components/analytics'
...@@ -93,30 +94,6 @@ const HeaderWrapper = styled.div<{ transparent?: boolean }>` ...@@ -93,30 +94,6 @@ const HeaderWrapper = styled.div<{ transparent?: boolean }>`
z-index: ${Z_INDEX.dropdown}; z-index: ${Z_INDEX.dropdown};
` `
function getCurrentPageFromLocation(locationPathname: string): InterfacePageName | undefined {
switch (true) {
case locationPathname.startsWith('/swap'):
return InterfacePageName.SWAP_PAGE
case locationPathname.startsWith('/vote'):
return InterfacePageName.VOTE_PAGE
case locationPathname.startsWith('/pools'):
case locationPathname.startsWith('/pool'):
return InterfacePageName.POOL_PAGE
case locationPathname.startsWith('/tokens'):
return InterfacePageName.TOKENS_PAGE
case locationPathname.startsWith('/nfts/profile'):
return InterfacePageName.NFT_PROFILE_PAGE
case locationPathname.startsWith('/nfts/asset'):
return InterfacePageName.NFT_DETAILS_PAGE
case locationPathname.startsWith('/nfts/collection'):
return InterfacePageName.NFT_COLLECTION_PAGE
case locationPathname.startsWith('/nfts'):
return InterfacePageName.NFT_EXPLORE_PAGE
default:
return undefined
}
}
// this is the same svg defined in assets/images/blue-loader.svg // this is the same svg defined in assets/images/blue-loader.svg
// it is defined here because the remote asset may not have had time to load when this file is executing // it is defined here because the remote asset may not have had time to load when this file is executing
const LazyLoadSpinner = () => ( const LazyLoadSpinner = () => (
......
import { InterfacePageName } from '@uniswap/analytics-events'
import { getCurrentPageFromLocation } from './urlRoutes'
describe('getCurrentPageFromLocation', () => {
it('should return SWAP_PAGE when location pathname starts with "/swap"', () => {
const result = getCurrentPageFromLocation('/swap/123')
expect(result).toBe(InterfacePageName.SWAP_PAGE)
})
it('should return VOTE_PAGE when location pathname starts with "/vote"', () => {
const result = getCurrentPageFromLocation('/vote/456')
expect(result).toBe(InterfacePageName.VOTE_PAGE)
})
it('should return POOL_PAGE when location pathname starts with "/pools" or "/pool"', () => {
let result = getCurrentPageFromLocation('/pools/789')
expect(result).toBe(InterfacePageName.POOL_PAGE)
result = getCurrentPageFromLocation('/pool/abc')
expect(result).toBe(InterfacePageName.POOL_PAGE)
})
it('should return TOKENS_PAGE when location pathname starts with "/tokens"', () => {
const result = getCurrentPageFromLocation('/tokens/xyz')
expect(result).toBe(InterfacePageName.TOKENS_PAGE)
})
it('should return NFT_PROFILE_PAGE when location pathname starts with "/nfts/profile"', () => {
const result = getCurrentPageFromLocation('/nfts/profile/def')
expect(result).toBe(InterfacePageName.NFT_PROFILE_PAGE)
})
it('should return NFT_DETAILS_PAGE when location pathname starts with "/nfts/asset"', () => {
const result = getCurrentPageFromLocation('/nfts/asset/ghi')
expect(result).toBe(InterfacePageName.NFT_DETAILS_PAGE)
})
it('should return NFT_COLLECTION_PAGE when location pathname starts with "/nfts/collection"', () => {
const result = getCurrentPageFromLocation('/nfts/collection/jkl')
expect(result).toBe(InterfacePageName.NFT_COLLECTION_PAGE)
})
it('should return NFT_EXPLORE_PAGE when location pathname starts with "/nfts"', () => {
const result = getCurrentPageFromLocation('/nfts/mno')
expect(result).toBe(InterfacePageName.NFT_EXPLORE_PAGE)
})
it('should return undefined for unknown location pathnames', () => {
const result = getCurrentPageFromLocation('/unknown')
expect(result).toBeUndefined()
})
})
import { InterfacePageName } from '@uniswap/analytics-events'
export function getCurrentPageFromLocation(locationPathname: string): InterfacePageName | undefined {
switch (true) {
case locationPathname.startsWith('/swap'):
return InterfacePageName.SWAP_PAGE
case locationPathname.startsWith('/vote'):
return InterfacePageName.VOTE_PAGE
case locationPathname.startsWith('/pools'):
case locationPathname.startsWith('/pool'):
return InterfacePageName.POOL_PAGE
case locationPathname.startsWith('/tokens'):
return InterfacePageName.TOKENS_PAGE
case locationPathname.startsWith('/nfts/profile'):
return InterfacePageName.NFT_PROFILE_PAGE
case locationPathname.startsWith('/nfts/asset'):
return InterfacePageName.NFT_DETAILS_PAGE
case locationPathname.startsWith('/nfts/collection'):
return InterfacePageName.NFT_COLLECTION_PAGE
case locationPathname.startsWith('/nfts'):
return InterfacePageName.NFT_EXPLORE_PAGE
default:
return undefined
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment