1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-25 04:40:18 +02:00
metamask-extension/ui/app/contexts/metametrics.js
Mark Stacey 1419c14fb6
Use pathname instead of URL for currentPath metrics parameter (#9158)
The `currentPath` parameter passed to our metrics utility had been
passed the full URL rather than just the path, contrary to what the
name would imply. We only used the path portion, so passing the full
URL did lead to complications.

Now just the `pathname` is passed in, rather than the full URL. This
simplifies the metrics logic, and it incidentally fixes two bugs.

The main bug fixed is regarding Firefox metrics. Previously we had
assumed the `currentPath` would start with `chrome-extension://`, which
of course was not true on Firefox. This lead to us incorrectly parsing
the `currentPath`, so path tracking was broken for Firefox events.
This broken parsing is now bypassed entirely, so metrics should now
work the same on Firefox as on Chrome.

The second bug was that we were incorrectly setting the tracking URL
for background events during tests. As a result, we were incorrectly
detecting ourselves as an internal site that had referred the user to
us. But this was not of major concern, since it only affected test
metrics (which get sent to the development Matomo project).

Lastly, this change let us discard the `pathname` parameter used in
the `overrides` parameter of the `metricsEvent` function. Now that
`currentPath` is equivalent to `pathname`, the `pathname` parameter is
redundant.
2020-08-07 15:32:46 -03:00

132 lines
3.8 KiB
JavaScript

import React, { Component, createContext, useEffect, useCallback, useState } from 'react'
import { useSelector } from 'react-redux'
import PropTypes from 'prop-types'
import { useHistory } from 'react-router-dom'
import { captureException } from '@sentry/browser'
import {
getCurrentNetworkId,
getAccountType,
getNumberOfAccounts,
getNumberOfTokens,
} from '../selectors/selectors'
import { getSendToken } from '../selectors/send'
import {
txDataSelector,
} from '../selectors/confirm-transaction'
import { getEnvironmentType } from '../../../app/scripts/lib/util'
import {
sendMetaMetricsEvent,
sendCountIsTrackable,
} from '../helpers/utils/metametrics.util'
export const MetaMetricsContext = createContext(() => {
captureException(
Error(`MetaMetrics context function was called from a react node that is not a descendant of a MetaMetrics context provider`),
)
})
export function MetaMetricsProvider ({ children }) {
const txData = useSelector(txDataSelector) || {}
const network = useSelector(getCurrentNetworkId)
const environmentType = getEnvironmentType()
const activeCurrency = useSelector(getSendToken)?.symbol
const accountType = useSelector(getAccountType)
const confirmTransactionOrigin = txData.origin
const metaMetricsId = useSelector((state) => state.metamask.metaMetricsId)
const participateInMetaMetrics = useSelector((state) => state.metamask.participateInMetaMetrics)
const metaMetricsSendCount = useSelector((state) => state.metamask.metaMetricsSendCount)
const numberOfTokens = useSelector(getNumberOfTokens)
const numberOfAccounts = useSelector(getNumberOfAccounts)
const history = useHistory()
const [state, setState] = useState(() => ({
currentPath: (new URL(window.location.href)).pathname,
previousPath: '',
}))
const { previousPath, currentPath } = state
useEffect(() => {
const unlisten = history.listen(() => setState((prevState) => ({
currentPath: (new URL(window.location.href)).pathname,
previousPath: prevState.currentPath,
})))
// remove this listener if the component is no longer mounted
return unlisten
}, [history])
const metricsEvent = useCallback((config = {}, overrides = {}) => {
const { eventOpts = {} } = config
const { name = '' } = eventOpts
const { currentPath: overrideCurrentPath = '' } = overrides
const isSendFlow = Boolean(name.match(/^send|^confirm/) || overrideCurrentPath.match(/send|confirm/))
if (participateInMetaMetrics || config.isOptIn) {
return sendMetaMetricsEvent({
network,
environmentType,
activeCurrency,
accountType,
confirmTransactionOrigin,
metaMetricsId,
numberOfTokens,
numberOfAccounts,
version: global.platform.getVersion(),
...config,
previousPath,
currentPath,
excludeMetaMetricsId: isSendFlow && !sendCountIsTrackable(metaMetricsSendCount + 1),
...overrides,
})
}
}, [
network,
environmentType,
activeCurrency,
accountType,
confirmTransactionOrigin,
participateInMetaMetrics,
previousPath,
metaMetricsId,
numberOfTokens,
numberOfAccounts,
currentPath,
metaMetricsSendCount,
])
return (
<MetaMetricsContext.Provider value={metricsEvent}>
{children}
</MetaMetricsContext.Provider>
)
}
MetaMetricsProvider.propTypes = { children: PropTypes.node }
export class LegacyMetaMetricsProvider extends Component {
static propTypes = {
children: PropTypes.node,
}
static defaultProps = {
children: undefined,
}
static contextType = MetaMetricsContext
static childContextTypes = {
metricsEvent: PropTypes.func,
}
getChildContext () {
return {
metricsEvent: this.context,
}
}
render () {
return this.props.children
}
}