From 79d9c18cb18004777e945fb032866001c8ab14f0 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 23 Aug 2023 11:36:03 -0500 Subject: [PATCH] UX: Multichain: Add address to account picker, change connection to copy button (#20520) * UX: Multichain: Add address to account picker, change connection to copy button * Fix for very long account names --- app/_locales/en/messages.json | 3 + builds.yml | 2 + .../__snapshots__/account-picker.test.js.snap | 52 ++++++----- .../account-picker/account-picker.js | 73 +++++++++++---- .../account-picker/account-picker.stories.js | 18 +++- .../account-picker/account-picker.test.js | 5 + .../multichain/account-picker/index.scss | 4 + .../__snapshots__/app-header.test.js.snap | 92 ++++++++++--------- .../multichain/app-header/app-header.js | 63 +++++++++---- .../multichain/app-header/app-header.test.js | 6 ++ 10 files changed, 216 insertions(+), 102 deletions(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index dbbb8911b..0c9e060a3 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -287,6 +287,9 @@ "address": { "message": "Address" }, + "addressCopied": { + "message": "Address copied!" + }, "advanced": { "message": "Advanced" }, diff --git a/builds.yml b/builds.yml index 74f60894d..e5cf577a2 100644 --- a/builds.yml +++ b/builds.yml @@ -237,6 +237,8 @@ env: - BLOCKAID_FILE_CDN # Blockaid public key for verifying signatures of data files downloaded from CDN - BLOCKAID_PUBLIC_KEY + # Determines if feature flagged Multichain UI should be used + - MULTICHAIN: '' ### # Meta variables diff --git a/ui/components/multichain/account-picker/__snapshots__/account-picker.test.js.snap b/ui/components/multichain/account-picker/__snapshots__/account-picker.test.js.snap index 79c8d6eff..e7570d155 100644 --- a/ui/components/multichain/account-picker/__snapshots__/account-picker.test.js.snap +++ b/ui/components/multichain/account-picker/__snapshots__/account-picker.test.js.snap @@ -10,30 +10,38 @@ exports[`AccountPicker renders properly 1`] = ` class="mm-box mm-text mm-text--inherit mm-text--ellipsis mm-box--display-flex mm-box--gap-2 mm-box--align-items-center mm-box--color-primary-inverse" >
- - +
+ + + Account 1 + + +
- - Account 1 - - diff --git a/ui/components/multichain/account-picker/account-picker.js b/ui/components/multichain/account-picker/account-picker.js index 8ac99e61e..a093d249a 100644 --- a/ui/components/multichain/account-picker/account-picker.js +++ b/ui/components/multichain/account-picker/account-picker.js @@ -1,7 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { useSelector } from 'react-redux'; +import { toChecksumHexAddress } from '@metamask/controller-utils'; import { + Box, Button, AvatarAccount, AvatarAccountVariant, @@ -14,13 +16,25 @@ import { BackgroundColor, BorderRadius, Display, + FlexDirection, FontWeight, IconColor, Size, + TextAlign, + TextColor, + TextVariant, } from '../../../helpers/constants/design-system'; +import { shortenAddress } from '../../../helpers/utils/util'; -export const AccountPicker = ({ address, name, onClick, disabled }) => { +export const AccountPicker = ({ + address, + name, + onClick, + disabled, + showAddress = false, +}) => { const useBlockie = useSelector((state) => state.metamask.useBlockie); + const shortenedAddress = shortenAddress(toChecksumHexAddress(address)); return ( ); }; @@ -76,4 +107,8 @@ AccountPicker.propTypes = { * Represents if the AccountPicker should be actionable */ disabled: PropTypes.bool.isRequired, + /** + * Represents if the account address should display + */ + showAddress: PropTypes.bool, }; diff --git a/ui/components/multichain/account-picker/account-picker.stories.js b/ui/components/multichain/account-picker/account-picker.stories.js index d82c2c490..3aaf03de6 100644 --- a/ui/components/multichain/account-picker/account-picker.stories.js +++ b/ui/components/multichain/account-picker/account-picker.stories.js @@ -21,7 +21,7 @@ export default { }, }, args: { - address: '"0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e"', + address: '0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e', name: 'Account 1', onClick: () => undefined, }, @@ -30,6 +30,12 @@ export default { export const DefaultStory = (args) => ; DefaultStory.storyName = 'Default'; +export const WithAddressStory = (args) => ; +WithAddressStory.storyName = 'With Address'; +WithAddressStory.args = { + showAddress: true, +}; + export const ChaosStory = (args) => (
( ); ChaosStory.storyName = 'Chaos'; ChaosStory.args = { name: CHAOS_ACCOUNT.name }; + +export const ChaosWithAddressStory = (args) => ( +
+ +
+); +ChaosWithAddressStory.storyName = 'Chaos with Address'; +ChaosWithAddressStory.args = { name: CHAOS_ACCOUNT.name, showAddress: true }; diff --git a/ui/components/multichain/account-picker/account-picker.test.js b/ui/components/multichain/account-picker/account-picker.test.js index efc5fb61c..a9614f454 100644 --- a/ui/components/multichain/account-picker/account-picker.test.js +++ b/ui/components/multichain/account-picker/account-picker.test.js @@ -45,4 +45,9 @@ describe('AccountPicker', () => { const { container } = render({}, { useBlockie: false }); expect(container.querySelector('svg')).toBeDefined(); }); + + it('should show the address in the account button for multichain', () => { + const { getByText } = render({ showAddress: true }); + expect(getByText('0x0DC...E7bc')).toBeInTheDocument(); + }); }); diff --git a/ui/components/multichain/account-picker/index.scss b/ui/components/multichain/account-picker/index.scss index 4640ac384..baa22226e 100644 --- a/ui/components/multichain/account-picker/index.scss +++ b/ui/components/multichain/account-picker/index.scss @@ -4,4 +4,8 @@ box-shadow: none; background: var(--color-background-default-hover); } + + &-container { + overflow: hidden; + } } diff --git a/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap b/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap index 656e0ecc8..27d8a85e7 100644 --- a/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap +++ b/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap @@ -235,57 +235,65 @@ exports[`App Header should match snapshot 1`] = ` class="mm-box mm-text mm-text--inherit mm-text--ellipsis mm-box--display-flex mm-box--gap-2 mm-box--align-items-center mm-box--color-primary-inverse" >
- - Test Account - -
{ const trackEvent = useContext(MetaMetricsContext); @@ -94,11 +98,17 @@ export const AppHeader = ({ location }) => { const currentNetwork = useSelector(getCurrentNetwork); const testNetworkBackgroundColor = useSelector(getTestNetworkBackgroundColor); + // Used for copy button + const currentAddress = useSelector(getSelectedAddress); + const checksummedCurrentAddress = toChecksumHexAddress(currentAddress); + const [copied, handleCopy] = useCopyToClipboard(MINUTE); + const popupStatus = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP; - const showStatus = - getEnvironmentType() === ENVIRONMENT_TYPE_POPUP && - origin && - origin !== browser.runtime.id; + const showConnectedStatus = + process.env.MULTICHAIN || + (getEnvironmentType() === ENVIRONMENT_TYPE_POPUP && + origin && + origin !== browser.runtime.id); const showProductTour = completedOnboarding && !onboardedInThisUISession && showProductTourPopup; const productTourDirection = document @@ -285,6 +295,7 @@ export const AppHeader = ({ location }) => { }); }} disabled={disableAccountPicker} + showAddress={process.env.MULTICHAIN} /> ) : null} { justifyContent={JustifyContent.flexEnd} > - {showStatus ? ( - - { - history.push(CONNECTED_ACCOUNTS_ROUTE); - trackEvent({ - event: MetaMetricsEventName.NavConnectedSitesOpened, - category: MetaMetricsEventCategory.Navigation, - }); - }} - /> - - ) : null}{' '} + {showConnectedStatus && + (process.env.MULTICHAIN ? ( + + handleCopy(checksummedCurrentAddress)} + iconName={ + copied ? IconName.CopySuccess : IconName.Copy + } + size={IconSize.Sm} + data-testid="app-header-copy-button" + /> + + ) : ( + + { + history.push(CONNECTED_ACCOUNTS_ROUTE); + trackEvent({ + event: + MetaMetricsEventName.NavConnectedSitesOpened, + category: MetaMetricsEventCategory.Navigation, + }); + }} + /> + + ))}{' '} { ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) custodianIcon && ( diff --git a/ui/components/multichain/app-header/app-header.test.js b/ui/components/multichain/app-header/app-header.test.js index be47b4320..a760bc3e6 100644 --- a/ui/components/multichain/app-header/app-header.test.js +++ b/ui/components/multichain/app-header/app-header.test.js @@ -31,4 +31,10 @@ describe('App Header', () => { const { getByTestId } = render({ send: { stage: SEND_STAGES.DRAFT } }); expect(getByTestId('account-menu-icon')).toBeEnabled(); }); + + it('should show the copy button for multichain', () => { + process.env.MULTICHAIN = 1; + const { getByTestId } = render({ send: { stage: SEND_STAGES.INACTIVE } }); + expect(getByTestId('app-header-copy-button')).toBeEnabled(); + }); });