From a40cb29f1be845e66796e24a38b004c96cfe7184 Mon Sep 17 00:00:00 2001
From: Nick Gambino <35090461+gambinish@users.noreply.github.com>
Date: Thu, 7 Nov 2024 16:37:19 -0800
Subject: [PATCH] fix: Bug 28347 - Privacy mode tweaks (#28367) (#28372)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
Cherry pick of
https://github.com/MetaMask/metamask-extension/commit/82fdd64f5787ac4da20d2da6ddcd55787d136163
Original PR: https://github.com/MetaMask/metamask-extension/pull/28367
Privacy Mode should only effect PortfolioView and main account picker
popover. It should not impact other areas of the App like Send/Swap/Gas
because the toggle only exists on PortfolioView.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/28367?quickstart=1)
## **Related issues**
Fixes: https://github.com/MetaMask/metamask-extension/issues/28347
## **Manual testing steps**
You can toggle privacyMode with eyeball on main PortfolioView
Should respect privacyMode:
1. Go to PortfolioView, toggling eyeball should show/hide balances for
tokens as well as main balance
2. Go to AccountPicker from main Portfolio View, balances should
hide/show
3. Go to AccountPicker from asset detail view, balances should hide/show
Should _not_ respect privacyMode:
1. Go to AssetDetails, token balance should show on main page
2. Should not be respected on send/swap/gas screens
3. Balances should not be impacted elsewhere in the app. Please try to
verify this while reviewing.
## **Screenshots/Recordings**
https://github.com/user-attachments/assets/695fa68a-c9bb-4871-b03c-8c41c88b1344
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
## **Description**
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/28372?quickstart=1)
## **Related issues**
Fixes:
## **Manual testing steps**
1. Go to this page...
2.
3.
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
ui/components/app/assets/token-cell/token-cell.tsx | 5 +++--
ui/components/app/assets/token-list/token-list.tsx | 4 +++-
.../user-preferenced-currency-display.component.d.ts | 1 +
.../user-preferenced-currency-display.component.js | 3 +++
ui/components/app/wallet-overview/coin-overview.tsx | 6 +++---
.../multichain/account-list-item/account-list-item.js | 7 +++++++
.../multichain/account-list-menu/account-list-menu.tsx | 3 +++
.../ui/currency-display/currency-display.component.js | 5 ++---
ui/pages/routes/routes.component.js | 7 ++++++-
ui/pages/routes/routes.container.js | 3 ++-
10 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/ui/components/app/assets/token-cell/token-cell.tsx b/ui/components/app/assets/token-cell/token-cell.tsx
index 3a042de1ebb8..31bb388aa65b 100644
--- a/ui/components/app/assets/token-cell/token-cell.tsx
+++ b/ui/components/app/assets/token-cell/token-cell.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { useSelector } from 'react-redux';
-import { getTokenList, getPreferences } from '../../../../selectors';
+import { getTokenList } from '../../../../selectors';
import { useTokenFiatAmount } from '../../../../hooks/useTokenFiatAmount';
import { TokenListItem } from '../../../multichain';
import { isEqualCaseInsensitive } from '../../../../../shared/modules/string-utils';
@@ -12,6 +12,7 @@ type TokenCellProps = {
symbol: string;
string?: string;
image: string;
+ privacyMode?: boolean;
onClick?: (arg: string) => void;
};
@@ -20,10 +21,10 @@ export default function TokenCell({
image,
symbol,
string,
+ privacyMode = false,
onClick,
}: TokenCellProps) {
const tokenList = useSelector(getTokenList);
- const { privacyMode } = useSelector(getPreferences);
const tokenData = Object.values(tokenList).find(
(token) =>
isEqualCaseInsensitive(token.symbol, symbol) &&
diff --git a/ui/components/app/assets/token-list/token-list.tsx b/ui/components/app/assets/token-list/token-list.tsx
index 11190c68f267..f0b17d686026 100644
--- a/ui/components/app/assets/token-list/token-list.tsx
+++ b/ui/components/app/assets/token-list/token-list.tsx
@@ -30,7 +30,8 @@ export default function TokenList({
nativeToken,
}: TokenListProps) {
const t = useI18nContext();
- const { tokenSortConfig, tokenNetworkFilter } = useSelector(getPreferences);
+ const { tokenSortConfig, tokenNetworkFilter, privacyMode } =
+ useSelector(getPreferences);
const selectedAccount = useSelector(getSelectedAccount);
const conversionRate = useSelector(getConversionRate);
const nativeTokenWithBalance = useNativeTokenBalance();
@@ -88,6 +89,7 @@ export default function TokenList({
);
diff --git a/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.d.ts b/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.d.ts
index 4db61d568f4a..779309858a18 100644
--- a/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.d.ts
+++ b/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.d.ts
@@ -16,6 +16,7 @@ export type UserPrefrencedCurrencyDisplayProps = OverridingUnion<
showCurrencySuffix?: boolean;
shouldCheckShowNativeToken?: boolean;
isAggregatedFiatOverviewBalance?: boolean;
+ privacyMode?: boolean;
}
>;
diff --git a/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js b/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js
index 613b731d0a16..a466f7813672 100644
--- a/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js
+++ b/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js
@@ -28,6 +28,7 @@ export default function UserPreferencedCurrencyDisplay({
showNative,
showCurrencySuffix,
shouldCheckShowNativeToken,
+ privacyMode = false,
...restProps
}) {
// NOTE: When displaying currencies, we need the actual account to detect whether we're in a
@@ -83,6 +84,7 @@ export default function UserPreferencedCurrencyDisplay({
numberOfDecimals={numberOfDecimals}
prefixComponent={prefixComponent}
suffix={showCurrencySuffix && !showEthLogo && currency}
+ privacyMode={privacyMode}
/>
);
}
@@ -126,6 +128,7 @@ const UserPreferencedCurrencyDisplayPropTypes = {
textProps: PropTypes.object,
suffixProps: PropTypes.object,
shouldCheckShowNativeToken: PropTypes.bool,
+ privacyMode: PropTypes.bool,
};
UserPreferencedCurrencyDisplay.propTypes =
diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx
index 9f267c96a53d..93d9e1061428 100644
--- a/ui/components/app/wallet-overview/coin-overview.tsx
+++ b/ui/components/app/wallet-overview/coin-overview.tsx
@@ -132,7 +132,8 @@ export const CoinOverview = ({
const shouldShowPopover = useSelector(getShouldShowAggregatedBalancePopover);
const isTestnet = useSelector(getIsTestnet);
- const { showFiatInTestnets, privacyMode } = useSelector(getPreferences);
+ const { showFiatInTestnets, privacyMode, showNativeTokenAsMainBalance } =
+ useSelector(getPreferences);
const selectedAccount = useSelector(getSelectedAccount);
const shouldHideZeroBalanceTokens = useSelector(
@@ -143,8 +144,6 @@ export const CoinOverview = ({
shouldHideZeroBalanceTokens,
);
- const { showNativeTokenAsMainBalance } = useSelector(getPreferences);
-
const isEvm = useSelector(getMultichainIsEvm);
const isNotAggregatedFiatBalance =
showNativeTokenAsMainBalance || isTestnet || !isEvm;
@@ -281,6 +280,7 @@ export const CoinOverview = ({
isAggregatedFiatOverviewBalance={
!showNativeTokenAsMainBalance && !isTestnet
}
+ privacyMode={privacyMode}
/>
{
const t = useI18nContext();
const [accountOptionsMenuOpen, setAccountOptionsMenuOpen] = useState(false);
@@ -313,6 +314,7 @@ const AccountListItem = ({
type={PRIMARY}
showFiat={showFiat}
data-testid="first-currency-display"
+ privacyMode={privacyMode}
/>
@@ -360,6 +362,7 @@ const AccountListItem = ({
type={SECONDARY}
showNative
data-testid="second-currency-display"
+ privacyMode={privacyMode}
/>
@@ -507,6 +510,10 @@ AccountListItem.propTypes = {
* Determines if list item should be scrolled to when selected
*/
shouldScrollToWhenSelected: PropTypes.bool,
+ /**
+ * Determines if list balance should be obfuscated
+ */
+ privacyMode: PropTypes.bool,
};
AccountListItem.displayName = 'AccountListItem';
diff --git a/ui/components/multichain/account-list-menu/account-list-menu.tsx b/ui/components/multichain/account-list-menu/account-list-menu.tsx
index eff0d3cb8868..cfb49d246ca6 100644
--- a/ui/components/multichain/account-list-menu/account-list-menu.tsx
+++ b/ui/components/multichain/account-list-menu/account-list-menu.tsx
@@ -188,6 +188,7 @@ export const mergeAccounts = (
type AccountListMenuProps = {
onClose: () => void;
+ privacyMode?: boolean;
showAccountCreation?: boolean;
accountListItemProps?: object;
allowedAccountTypes?: KeyringAccountType[];
@@ -195,6 +196,7 @@ type AccountListMenuProps = {
export const AccountListMenu = ({
onClose,
+ privacyMode = false,
showAccountCreation = true,
accountListItemProps,
allowedAccountTypes = [
@@ -644,6 +646,7 @@ export const AccountListMenu = ({
isHidden={Boolean(account.hidden)}
currentTabOrigin={currentTabOrigin}
isActive={Boolean(account.active)}
+ privacyMode={privacyMode}
{...accountListItemProps}
/>
diff --git a/ui/components/ui/currency-display/currency-display.component.js b/ui/components/ui/currency-display/currency-display.component.js
index a0bb114409f6..7e2569ffaee3 100644
--- a/ui/components/ui/currency-display/currency-display.component.js
+++ b/ui/components/ui/currency-display/currency-display.component.js
@@ -1,10 +1,8 @@
import React from 'react';
-import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { useCurrencyDisplay } from '../../../hooks/useCurrencyDisplay';
import { EtherDenomination } from '../../../../shared/constants/common';
-import { getPreferences } from '../../../selectors';
import { SensitiveText, Box } from '../../component-library';
import {
AlignItems,
@@ -35,9 +33,9 @@ export default function CurrencyDisplay({
textProps = {},
suffixProps = {},
isAggregatedFiatOverviewBalance = false,
+ privacyMode = false,
...props
}) {
- const { privacyMode } = useSelector(getPreferences);
const [title, parts] = useCurrencyDisplay(value, {
account,
displayValue,
@@ -125,6 +123,7 @@ const CurrencyDisplayPropTypes = {
textProps: PropTypes.object,
suffixProps: PropTypes.object,
isAggregatedFiatOverviewBalance: PropTypes.bool,
+ privacyMode: PropTypes.bool,
};
CurrencyDisplay.propTypes = CurrencyDisplayPropTypes;
diff --git a/ui/pages/routes/routes.component.js b/ui/pages/routes/routes.component.js
index e26e17be9e23..83e707c30f85 100644
--- a/ui/pages/routes/routes.component.js
+++ b/ui/pages/routes/routes.component.js
@@ -138,6 +138,7 @@ export default class Routes extends Component {
history: PropTypes.object,
location: PropTypes.object,
autoLockTimeLimit: PropTypes.number,
+ privacyMode: PropTypes.bool,
pageChanged: PropTypes.func.isRequired,
browserEnvironmentOs: PropTypes.string,
browserEnvironmentBrowser: PropTypes.string,
@@ -417,6 +418,7 @@ export default class Routes extends Component {
switchedNetworkDetails,
clearSwitchedNetworkDetails,
clearEditedNetwork,
+ privacyMode,
///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
isShowKeyringSnapRemovalResultModal,
hideShowKeyringSnapRemovalResultModal,
@@ -494,7 +496,10 @@ export default class Routes extends Component {
///: END:ONLY_INCLUDE_IF
}
{isAccountMenuOpen ? (
- toggleAccountMenu()} />
+ toggleAccountMenu()}
+ privacyMode={privacyMode}
+ />
) : null}
{isNetworkMenuOpen ? (