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.
* Remove `url` parameter from `metricsEvent`
The `url` parameter was used to override the `currentPath`, but it
never worked correctly. It was supposed to be used for setting the
`url` query parameter that was sent to Matomo, but `currentPath` was
always used even if it `url` was set and `currentPath` was empty.
Instead, `currentPath` is now always used. There was never a need to
provide an "override" for `currentPath` when it can be set directly.
The metrics provider does set `currentPath` automatically by default,
but this can be overwritten already by passing a second parameter to
`metricsEvent`.
There were two places this `url` parameter was being used: background
events, and path changes. Background events were submitted with no
`currentPath`, so because of the bug with the `url` parameter, the
metrics utility would crash upon each event. So those were never
actually sent. This commit will fix that crash.
The `currentPath` parameter was supplied as an empty string for the
path change events, so those never crashed. They just had the `url`
query string parameter set incorrectly (to an empty string). It should
now be correctly populated, which should mean we'll be capturing all
path changes now. Previously we were only capturing path changes to
pages that happened to include an event, because of this blank `url`
problem.
* Use `url` query parameter as fallback for generating `pv_id`
The `pv_id` parameter currently isn't generated correctly on Firefox,
as the generation assumes that the current URL starts with
`chrome-extension://`. The `url` query parameter is still unique for
each path, so it's probably good enough for generating an id for each
page.
This is just a temporary fix; it will be removed in a future PR, where
Firefox will be properly supported.
The MetaMetrics project ID can now be set via environment variable. It
has not been set yet in practice, so for now the old project IDs will
still be used. This is in preparation for migrating to a new project.
e2e tests will now reference the development MetaMetrics project
instead of the production one. The metrics endpoint should be stubbed
out during e2e tests anyway, but this seemed like a better default
regardless.
Previously the `getMessage` function would throw if a substitution was
falsey. Now it will accept any substitution, including `undefined`.
A substitution of `null` or `undefined` will still be reported to
Sentry and printed to the console as an error, but it will not
interrupt execution. Any `null` or `undefined` substitutions will be
rendered as empty strings.
Ideally we'd never pass in `null` or `undefined` as a substitution, but
in practice this sometimes just occurs breifly between renders, which
isn't a severe enough problem to justify crashing the UI.
The detection of React component substitutions has been updated as
well, to ensure that `null` values aren't counted as React
substitutions.
We were including the polyfill for the `Intl.RelativeTimeFormat` API,
but we weren't including any locale data. This polyfill doesn't work
without the locale data for whichever locale you're formatting.
The data for all locales we support is now included. The locale data
is loaded from disk as-needed (during app startup, and upon each change
in locale).
The `getMessage` function in `i18n-helper` was assuming that any
substitutions passed into the transaction function were used by the
corresponding localized message. However, some messages are
intentionally ignoring substitutions passed in. This was done to
simplify the UI logic, so the same substitutions could be passed in for
many different messages, even if some don't use them.
For example, `transactionCancelSuccess` is passed two substitutions but
only uses the second one. `transactionErrored` is passed in two, but
uses neither.
`getMessage` has been updated to no longer make that assumption. It
will now only throw an error if the localized message expects a
substitution that was not given. A given substitution that is unused
results in no error.
* update connected accounts appearance
* consolidate account alerts
* UnconnectedAccountAlert: use ConnectedAccountsList
* move switch account action out of menu in all views
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
The conversion of token amounts to fiat amounts was extracted from the
`TokenCell` component, and moved to a utility function. This will be
used elsewhere in an upcoming PR.
The `confirm-approve` page has been converted from a set of container/
component components to a functional component. The `withTokenTracker`
higher-order component has been deleted, as it was replaced by the
`useTokenTracker` hook.
The `TokenBalance` component now uses the new `useTokenTracker` hook
instead of the `withTokenTracker` higher-order component. The component
was converted from a split container/component to a functional
component so that the hook could be used.
The prop `withSymbol` was removed from a few call sites, as it was no
longer used. An empty string was substituted for any falsy `string` or
`symbol` because that's what the `withTokenTracker` higher-order
component did.
Each "message" requiring a user confirmation has a unique `type`
property. These `type` properties have all been added as enums, and the
enum is now used wherever the literal string was used previously.
A new page has been created for viewing assets. This replaces the old
`selectedToken` state, which previously would augment the home page
to show token-specific information.
The new asset page shows the standard token overview as seen previously
on the home page, plus a history filtered to show just transactions
relevant to that token.
The actions that were available in the old token list menu have been
moved to a "Token Options" menu that mirrors the "Account Options"
menu.
The `selectedTokenAddress` state has been removed, as it is no longer
being used for anything.
`getMetaMetricState` has been renamed to `getBackgroundMetaMetricState`
because its sole purpose is extracting data from the background state
to send metrics from the background. It's not really a selector, but
it was convenient for it to use the same selectors the UI uses to
extract background data, so I left it there for now.
A new Redux store has been added to track state related to browser history.
The most recent "overview" page (i.e. the home page or the asset page) is
currently being tracked, so that actions taken from the asset page can return
the user back to the asset page when the action has finished.
This changeset updates the `getOriginOfCurrentTab` selector and the container
for the ConnectedSites page to use `activeTab.origin` instead of parsing the
URL. The `activeTab` URL is parsed in `queryCurrentActiveTab` before the UI is
launched and any subsequent parsing of the URL is unnecessary.
See `queryCurrentActiveTab` in `ui.js:86` [1].
[1]:e7bb0876f5/app/scripts/ui.js (L86-L118)
What
- modify `ui/app/helpers/utils/transactions.util.js` and
`ui/lib/account-link.js` to strip trailing slashes
if they are present.
- added relevant tests not just for the new scenario,
but also the general scenarios for these functions,
as there previously was no test coverage for these
two functions.
Why
- Current behaviour, when user enters a block explorer URL
when configuring a custom RPC, and that block explorer URL
contains a trailing `/`.
- e.g. `https://block.explorer/`
- this results in a double-slash (`//`) in the transaction
and account URLs generated by MetaMask.
- e.g. `https://block.explorer/tx/0xabcd...`,
`https://block.explorer/account/0xabcd...`
- This needs to be handled using a router redirect
on the server of the block explorer,
and this changes would avoid that requirement.
The IDs for the `numberOfTokens` and `numberOfAccounts` Action
Dimensions were swapped. These are the correct IDs. We'll have to
consider that these are swapped when viewing any pre-v8.0.0 metrics.
The unconnected account alert can now be disabled. A "don't show this
again" checkbox has been added to the alert, which prevents that alert
from being shown in the future.
An alert settings page has been added to the settings as well. This
page allows the user to disable or enable any alert.
The `shift-list-item` component for displaying ShapeShift transactions
has been removed, along with three other components that were used
solely by that component (`copyButton`, `eth-balance`, and
`fiat-value`).
This component hasn't been used in some time, as ShapeShift
transactions no longer exist to display. The controller that ShapeShift
transactions originated from was removed in #8118, and it became
impossible to create new ShapeShift transactions from within MetaMask
in #6746
Previously all browser globals were allowed to be used anywhere by
ESLint because we had set the `env` property to `browser` in the ESLint
config. This has made it easy to accidentally use browser globals
(e.g. #8338), so it has been removed. Instead we now have a short list
of allowed globals.
All browser globals are now accessed as properties on `window`.
Unfortunately this change resulted in a few different confusing unit
test errors, as some of our unit tests setup assumed that a particular
global would be used via `window` or `global`. In particular,
`window.fetch` didn't work correctly because it wasn't patched by the
AbortController polyfill (only `global.fetch` was being patched).
The `jsdom-global` package we were using complicated matters by setting
all of the JSDOM `window` properties directly on `global`, overwriting
the `AbortController` for example.
The `helpers.js` test setup module has been simplified somewhat by
removing `jsdom-global` and constructing the JSDOM instance manually.
The JSDOM window is set on `window`, and a few properties are set on
`global` as well as needed by various dependencies. `node-fetch` and
the AbortController polyfill/patch now work as expected as well,
though `fetch` is only available on `window` now.
The token list would be stuck on "Loading" when there was at least one
token, but the balance of all tokens was zero. This bug was only
present on `develop`, and has not affected any published version of the
extension.
This was introduced in #8223, which removed what at the time seemed to
be an unnecessary update step. It turns out that the step was required
as a workaround to this bug with the token tracker.
The bug was fixed in https://github.com/MetaMask/eth-token-tracker/pull/33
and published in v2.0.0 of `@metamask/eth-token-tracker`.
The "i18n-provider" module has been replaced by a new `i18n.js` module
in the `contexts` directory which provides the `t` function via the new
React Context API.
The legacy context API is still used throughout the codebase, so a
legacy context provider has also been added as a shim until we migrate
away from the old API. The migration does require changing every single
place where the `t` function is used, so it is a non-trivial amount of
work. This shim allows us to tackle it one piece at a time without
breaking anything.
This was placed in a new `contexts` directory because it didn't seem
to belong in any existing categories. It certainly isn't a higher-order
component.
The translation helper function we use everywhere (`t`) would fallback
to the message `[${key}]` for any key not found in the set of localized
messages. Instead it how returns `undefined` in that case.
`[${key}]` isn't something you'd typically want to show to users, so
this fallback wasn't overly useful in practice. At best it served to
hide errors.
The falsey return value in the case where the message is missing makes
it easier to implement a fallback for that case. Such a fallback is
used in the `confirm-transaction-base` component, to restore the
fallback behavior accidentally changed in #8211
These two functions were not especially useful. `tOrDefault` was used
only by `tOrKey`, and `tOrKey` was only used in one place. All it did
was return the given `key` directly if it was falsey, so it was easily
replaced by a condition.
The method registry was being initialized with the global variable
`ethereumProvider` before that variable was set. As a result, the
method registry was falling back to an internally constructed provider
that used the wrong provider URL (an obsolete Infura API). This was
resulting in an error with the message "Project ID not found".
The method registry is now initialized lazily, when it's first needed.
This should be well after the initialization of `ethereumProvider`,
which occurs during the UI initialization.