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 ? (