Skip to content

Commit

Permalink
feature(metrics): receive funnel revamp (#3095)
Browse files Browse the repository at this point in the history
  • Loading branch information
banklesss authored Feb 28, 2024
1 parent 856d4b0 commit 42da67c
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 8 deletions.
1 change: 1 addition & 0 deletions apps/wallet-mobile/src/TxHistory/ActionsBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export const ActionsBanner = ({disabled = false}: {disabled: boolean}) => {
}

const handleOnLongPressReceive = () => {
track.receiveCopyAddressClicked({copy_address_location: 'Long Press wallet Address'})
copy(nextReceiveAddress)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {StyleSheet, useWindowDimensions, View} from 'react-native'
import LinearGradient from 'react-native-linear-gradient'

import {CopyButton, Text} from '../../../../components'
import {useMetrics} from '../../../../metrics/metricsManager'
import {isEmptyString} from '../../../../utils/utils'
import {useStrings} from '../useStrings'

Expand All @@ -16,10 +17,15 @@ type AddressDetailsProps = {
export const ShareDetailsCard = ({address, spendingHash, stakingHash}: AddressDetailsProps) => {
const strings = useStrings()
const {styles, colors} = useStyles()
const {track} = useMetrics()

const hasStakingHash = !isEmptyString(stakingHash)
const hasSpendingHash = !isEmptyString(spendingHash)

const handleAddressOnCopy = () => {
track.receiveCopyAddressClicked({copy_address_location: 'Tap Address Details'})
}

return (
<View style={styles.addressDetails}>
<LinearGradient
Expand All @@ -37,7 +43,7 @@ export const ShareDetailsCard = ({address, spendingHash, stakingHash}: AddressDe
<View style={styles.textRow}>
<Text style={styles.textAddressDetails}>{address}</Text>

<CopyButton value={address} />
<CopyButton value={address} onCopy={handleAddressOnCopy} />
</View>
</View>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Share from 'react-native-share'
import ViewShot, {captureRef} from 'react-native-view-shot'

import {Spacer, Text} from '../../../../components'
import {useMetrics} from '../../../../metrics/metricsManager'
import {CaptureShareQRCodeCard} from '../CaptureShareQRCodeCard/CaptureShareQRCodeCard'
import {useStrings} from '../useStrings'

Expand All @@ -22,11 +23,13 @@ type ShareQRCodeCardProps = {
export const ShareQRCodeCard = ({content, title, isCopying, onLongPress}: ShareQRCodeCardProps) => {
const strings = useStrings()
const {styles, colors} = useStyles()
const {track} = useMetrics()

const [isSharing, setIsSharing] = React.useState(false)
const ref: React.RefObject<ViewShot> = React.useRef(null)

const handleOnPressShare = () => {
track.receiveShareAddressClicked()
setIsSharing(true)
}
const message = `${strings.address} ${content}`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {useFocusEffect} from '@react-navigation/native'
import {useTheme} from '@yoroi/theme'
import _ from 'lodash'
import * as React from 'react'
Expand All @@ -7,6 +8,7 @@ import {SafeAreaView} from 'react-native-safe-area-context'
import Icon from '../../../assets/img/copy.png'
import {Button, Spacer} from '../../../components'
import {useCopy} from '../../../legacy/useCopy'
import {useMetrics} from '../../../metrics/metricsManager'
import {isEmptyString} from '../../../utils'
import {AddressDetailCard} from '../common/AddressDetailCard/AddressDetailCard'
import {useReceive} from '../common/ReceiveProvider'
Expand All @@ -19,10 +21,21 @@ export const DescribeSelectedAddressScreen = () => {
const {styles, colors} = useStyles()
const navigate = useNavigateTo()
const {selectedAddress} = useReceive()
const {track} = useMetrics()

const [isCopying, copy] = useCopy()
const hasAddress = !isEmptyString(selectedAddress)
const handleOnPressCopy = () => copy(selectedAddress)

const handleOnPressCopy = () => {
track.receiveCopyAddressClicked({copy_address_location: 'CTA Copy Address'})
copy(selectedAddress)
}

useFocusEffect(
React.useCallback(() => {
track.receivePageViewed()
}, [track]),
)

return (
<SafeAreaView style={styles.root} edges={['left', 'right', 'bottom']}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {useFocusEffect} from '@react-navigation/native'
import {useTheme} from '@yoroi/theme'
import * as React from 'react'
import {StyleSheet, Text, View} from 'react-native'
import Animated, {Layout} from 'react-native-reanimated'
import {SafeAreaView} from 'react-native-safe-area-context'

import {Button, Spacer, useModal} from '../../../components'
import {useMetrics} from '../../../metrics/metricsManager'
import {useSelectedWallet} from '../../../SelectedWallet'
import {BIP32_HD_GAP_LIMIT} from '../common/contants'
import {useReceive} from '../common/ReceiveProvider'
Expand All @@ -27,16 +29,19 @@ export const ListMultipleAddressesScreen = () => {
const {styles} = useStyles()
const wallet = useSelectedWallet()
const navigate = useNavigateTo()
const {track} = useMetrics()

const {addressDerivation} = useAddressDerivationManager()
const addresses = useReceiveAddressesStatus(addressDerivation)
const {selectedAddressChanged} = useReceive()

React.useEffect(() => {
wallet.generateNewReceiveAddressIfNeeded()
}, [wallet])

const {openModal} = useModal()
const {isShowingMultipleAddressInfo} = useMultipleAddressesInfo()

React.useEffect(() => {
isShowingMultipleAddressInfo && openModal(strings.multiplePresentation, <Modal />, modalHeight)
}, [isShowingMultipleAddressInfo, openModal, strings.multiplePresentation])
Expand All @@ -59,6 +64,17 @@ export const ListMultipleAddressesScreen = () => {
[navigate, selectedAddressChanged],
)

const handleOnGenerateNewReceiveAddress = () => {
track.receiveGenerateNewAddressClicked()
wallet.generateNewReceiveAddress()
}

useFocusEffect(
React.useCallback(() => {
track.receivePageListViewed()
}, [track]),
)

return (
<SafeAreaView style={styles.root} edges={['left', 'right', 'bottom']}>
{hasReachedGapLimit && (
Expand All @@ -82,7 +98,7 @@ export const ListMultipleAddressesScreen = () => {
shelleyTheme
title={strings.generateButton}
disabled={hasReachedGapLimit}
onPress={() => wallet.generateNewReceiveAddress()}
onPress={handleOnGenerateNewReceiveAddress}
style={styles.button}
/>
</Animated.View>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {useFocusEffect} from '@react-navigation/native'
import {configCardanoLegacyTransfer, linksCardanoModuleMaker} from '@yoroi/links'
import {useTheme} from '@yoroi/theme'
import * as React from 'react'
Expand All @@ -6,6 +7,7 @@ import {SafeAreaView} from 'react-native-safe-area-context'

import {Button, KeyboardAvoidingView, Spacer, TextInput, useModal} from '../../../components'
import {useCopy} from '../../../legacy/useCopy'
import {useMetrics} from '../../../metrics/metricsManager'
import {useSelectedWallet} from '../../../SelectedWallet'
import {isEmptyString} from '../../../utils'
import {editedFormatter} from '../../../yoroi-wallets/utils'
Expand All @@ -19,6 +21,7 @@ export const RequestSpecificAmountScreen = () => {
const strings = useStrings()
const {colors, styles} = useStyles()
const [amount, setAmount] = React.useState('')
const {track} = useMetrics()
const hasAmount = !isEmptyString(amount)

const {selectedAddress} = useReceive()
Expand All @@ -32,13 +35,20 @@ export const RequestSpecificAmountScreen = () => {
const handleOnGenerateLink = React.useCallback(() => {
Keyboard.dismiss()

track.receiveAmountGeneratedPageViewed({ada_amount: Number(amount)})
openModal(modalTitle, <Modal amount={amount} address={selectedAddress} />, modalHeight)
}, [openModal, modalTitle, amount, selectedAddress, modalHeight])
}, [track, amount, openModal, modalTitle, selectedAddress, modalHeight])

const handleOnChangeAmount = (amount: string) => {
setAmount(editedFormatter(amount))
}

useFocusEffect(
React.useCallback(() => {
track.receiveAmountPageViewed()
}, [track]),
)

return (
<SafeAreaView style={styles.root} edges={['left', 'right', 'bottom']}>
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
Expand Down
150 changes: 149 additions & 1 deletion apps/wallet-mobile/src/metrics/ampli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,28 @@ export interface NftGallerySearchActivatedProperties {
nft_search_term: string
}

export interface ReceiveAmountGeneratedPageViewedProperties {
/**
* The amount of ADA that the user will be exchanging.
*
* | Rule | Value |
* |---|---|
* | Type | number |
*/
ada_amount: number
}

export interface ReceiveCopyAddressClickedProperties {
/**
* Indicates the location of cop CTA
*
* | Rule | Value |
* |---|---|
* | Enum Values | CTA Copy Address, Tap Address Details, Long Press wallet Address |
*/
copy_address_location: 'CTA Copy Address' | 'Tap Address Details' | 'Long Press wallet Address'
}

export interface SendSelectAssetSelectedProperties {
/**
* Total numbers of assets to be send
Expand Down Expand Up @@ -743,10 +765,42 @@ export class NftGallerySearchActivated implements BaseEvent {
}
}

export class ReceiveAmountGeneratedPageViewed implements BaseEvent {
event_type = 'Receive Amount Generated Page Viewed'

constructor(public event_properties: ReceiveAmountGeneratedPageViewedProperties) {
this.event_properties = event_properties
}
}

export class ReceiveAmountPageViewed implements BaseEvent {
event_type = 'Receive Amount Page Viewed'
}

export class ReceiveCopyAddressClicked implements BaseEvent {
event_type = 'Receive Copy Address Clicked'

constructor(public event_properties: ReceiveCopyAddressClickedProperties) {
this.event_properties = event_properties
}
}

export class ReceiveGenerateNewAddressClicked implements BaseEvent {
event_type = 'Receive Generate New Address Clicked'
}

export class ReceivePageListViewed implements BaseEvent {
event_type = 'Receive Page List Viewed'
}

export class ReceivePageViewed implements BaseEvent {
event_type = 'Receive Page Viewed'
}

export class ReceiveShareAddressClicked implements BaseEvent {
event_type = 'Receive Share Address Clicked'
}

export class RestoreWalletDetailsSettled implements BaseEvent {
event_type = 'Restore Wallet Details Settled'
}
Expand Down Expand Up @@ -1237,12 +1291,91 @@ export class Ampli {
return this.track(new NftGallerySearchActivated(properties), options);
}

/**
* Receive Amount Generated Page Viewed
*
* [View in Tracking Plan](https://data.amplitude.com/emurgo/Yoroi/events/main/latest/Receive%20Amount%20Generated%20Page%20Viewed)
*
* When the bottom sheet or popup with a generated address with an specific amount is loaded
*
* @param properties The event's properties (e.g. ada_amount)
* @param options Amplitude event options.
*/
receiveAmountGeneratedPageViewed(
properties: ReceiveAmountGeneratedPageViewedProperties,
options?: EventOptions,
) {
return this.track(new ReceiveAmountGeneratedPageViewed(properties), options);
}

/**
* Receive Amount Page Viewed
*
* [View in Tracking Plan](https://data.amplitude.com/emurgo/Yoroi/events/main/latest/Receive%20Amount%20Page%20Viewed)
*
* When a user visit the page to insert specific amount of ADA that would be needed to generate a wallet address with that specific details.
*
* @param options Amplitude event options.
*/
receiveAmountPageViewed(
options?: EventOptions,
) {
return this.track(new ReceiveAmountPageViewed(), options);
}

/**
* Receive Copy Address Clicked
*
* [View in Tracking Plan](https://data.amplitude.com/emurgo/Yoroi/events/main/latest/Receive%20Copy%20Address%20Clicked)
*
* When a user click on the any CTA to copy their address
*
* @param properties The event's properties (e.g. copy_address_location)
* @param options Amplitude event options.
*/
receiveCopyAddressClicked(
properties: ReceiveCopyAddressClickedProperties,
options?: EventOptions,
) {
return this.track(new ReceiveCopyAddressClicked(properties), options);
}

/**
* Receive Generate New Address Clicked
*
* [View in Tracking Plan](https://data.amplitude.com/emurgo/Yoroi/events/main/latest/Receive%20Generate%20New%20Address%20Clicked)
*
* When a user click on the Generate new address button on the main receive page on the multiple address flow.
*
* @param options Amplitude event options.
*/
receiveGenerateNewAddressClicked(
options?: EventOptions,
) {
return this.track(new ReceiveGenerateNewAddressClicked(), options);
}

/**
* Receive Page List Viewed
*
* [View in Tracking Plan](https://data.amplitude.com/emurgo/Yoroi/events/main/latest/Receive%20Page%20List%20Viewed)
*
* When user has enabled multiple addresses and goes to the page where he can see the list of generated wallet addresses
*
* @param options Amplitude event options.
*/
receivePageListViewed(
options?: EventOptions,
) {
return this.track(new ReceivePageListViewed(), options);
}

/**
* Receive Page Viewed
*
* [View in Tracking Plan](https://data.amplitude.com/emurgo/Yoroi/events/main/latest/Receive%20Page%20Viewed)
*
* This event tracks when a user views the Receive page of the Wallet menu.
* When user loads the Receive funds screen, where user can see their wallet address with a QR Code
*
* @param options Amplitude event options.
*/
Expand All @@ -1252,6 +1385,21 @@ export class Ampli {
return this.track(new ReceivePageViewed(), options);
}

/**
* Receive Share Address Clicked
*
* [View in Tracking Plan](https://data.amplitude.com/emurgo/Yoroi/events/main/latest/Receive%20Share%20Address%20Clicked)
*
* When a user click on the link to share the address
*
* @param options Amplitude event options.
*/
receiveShareAddressClicked(
options?: EventOptions,
) {
return this.track(new ReceiveShareAddressClicked(), options);
}

/**
* Restore Wallet Details Settled
*
Expand Down
Loading

0 comments on commit 42da67c

Please sign in to comment.