From 5562f67763d444f9bf7d6ce96104b7ca85fb3c61 Mon Sep 17 00:00:00 2001 From: Nidhi Kumari Date: Wed, 11 Oct 2023 21:43:59 +0530 Subject: [PATCH] UX Multichain: Added Footer to the home screen (#20751) This PR is to add the footer * Fixes [#1244](https://github.com/MetaMask/MetaMask-planning/issues/1244) ## Screenshots/Screencaps ![Screenshot 2023-09-06 at 2 49 23 PM](https://github.com/MetaMask/metamask-extension/assets/39872794/08ddbcd4-4973-4885-879b-be10899616d6) https://github.com/MetaMask/metamask-extension/assets/39872794/00e8de3d-7e24-4e03-b96c-41ea56e4a7fe ## Manual Testing Steps ## Pre-merge author checklist - [x] I've clearly explained: - [x] What problem this PR is solving - [x] How this problem was solved - [x] How reviewers can test my changes - [x] Sufficient automated test coverage has been added ## Pre-merge reviewer checklist - [ ] Manual testing (e.g. pull and build branch, run in browser, test code being changed) - [ ] PR is linked to the appropriate GitHub issue - [ ] **IF** this PR fixes a bug in the release milestone, add this PR to the release milestone If further QA is required (e.g. new feature, complex testing steps, large refactor), add the `Extension QA Board` label. In this case, a QA Engineer approval will be be required. --------- Co-authored-by: David Walsh --- .../app/multiple-notifications/index.scss | 5 + .../multiple-notifications.component.js | 3 + .../__snapshots__/app-footer.test.js.snap | 60 ++++ .../multichain/app-footer/app-footer.js | 273 ++++++++++-------- .../multichain/app-footer/app-footer.scss | 37 ++- .../multichain/app-footer/app-footer.test.js | 25 ++ ui/css/itcss/components/newui-sections.scss | 1 - ui/pages/routes/routes.component.js | 21 ++ 8 files changed, 298 insertions(+), 127 deletions(-) create mode 100644 ui/components/multichain/app-footer/__snapshots__/app-footer.test.js.snap create mode 100644 ui/components/multichain/app-footer/app-footer.test.js diff --git a/ui/components/app/multiple-notifications/index.scss b/ui/components/app/multiple-notifications/index.scss index af939b884c64..100857d0fe01 100644 --- a/ui/components/app/multiple-notifications/index.scss +++ b/ui/components/app/multiple-notifications/index.scss @@ -59,6 +59,11 @@ visibility: hidden; } + /* accommodates for the home "Wallet" / "Connections" footer */ + &.home-notification-wrapper--multichain > div { + bottom: 88px; + } + > div:first-of-type { visibility: visible; } diff --git a/ui/components/app/multiple-notifications/multiple-notifications.component.js b/ui/components/app/multiple-notifications/multiple-notifications.component.js index 96abbf4a2bf4..d2ca8e7be25d 100644 --- a/ui/components/app/multiple-notifications/multiple-notifications.component.js +++ b/ui/components/app/multiple-notifications/multiple-notifications.component.js @@ -31,6 +31,9 @@ export default class MultipleNotifications extends PureComponent { className={classnames(...classNames, { 'home-notification-wrapper--show-all': showAll, 'home-notification-wrapper--show-first': !showAll, + 'home-notification-wrapper--multichain': Boolean( + process.env.MULTICHAIN, + ), })} > {childrenToRender} diff --git a/ui/components/multichain/app-footer/__snapshots__/app-footer.test.js.snap b/ui/components/multichain/app-footer/__snapshots__/app-footer.test.js.snap new file mode 100644 index 000000000000..1cdeceae3c5a --- /dev/null +++ b/ui/components/multichain/app-footer/__snapshots__/app-footer.test.js.snap @@ -0,0 +1,60 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`App Footer should match snapshot 1`] = ` +
+ +
+`; diff --git a/ui/components/multichain/app-footer/app-footer.js b/ui/components/multichain/app-footer/app-footer.js index fe536945d5de..eac46c72666c 100644 --- a/ui/components/multichain/app-footer/app-footer.js +++ b/ui/components/multichain/app-footer/app-footer.js @@ -1,10 +1,7 @@ import React from 'react'; -import { useLocation } from 'react-router-dom'; +import { useHistory, useLocation } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; -import { - CONNECTED_ROUTE, - DEFAULT_ROUTE, -} from '../../../helpers/constants/routes'; +import { CONNECTIONS, DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import { AvatarFavicon, AvatarNetwork, @@ -46,11 +43,11 @@ export const AppFooter = () => { const t = useI18nContext(); const location = useLocation(); const dispatch = useDispatch(); + const history = useHistory(); - const walletRoute = `#${DEFAULT_ROUTE}`; - const connectedRoute = `#${CONNECTED_ROUTE}`; const activeWallet = location.pathname === DEFAULT_ROUTE; - const activeConnections = location.pathname === CONNECTED_ROUTE; + const activeConnections = location.pathname === CONNECTIONS; + const isUnlocked = useSelector((state) => state.metamask.isUnlocked); const selectedAddress = useSelector(getSelectedAddress); @@ -67,124 +64,152 @@ export const AppFooter = () => { const currentChain = useSelector(getCurrentNetwork); return ( - - - - - {t('wallet')} - - - - dispatch(showSelectActionModal())} - /> - - - {connectedSite ? ( - - + {isUnlocked ? ( + <> + + - } + alignItems={AlignItems.center} + justifyContent={JustifyContent.spaceBetween} + backgroundColor={BackgroundColor.backgroundDefault} + flexDirection={FlexDirection.Row} + padding={2} + paddingLeft={4} + paddingRight={4} + gap={2} > - - + { + e.preventDefault(); + history.push(DEFAULT_ROUTE); + }} + className="app-footer__button" + width={BlockSize.OneThird} + padding={2} + display={Display.Flex} + flexDirection={FlexDirection.Column} + alignItems={AlignItems.center} + tabIndex={0} + > + + + {t('wallet')} + + + + dispatch(showSelectActionModal())} + /> + + { + e.preventDefault(); + history.push(CONNECTIONS); + }} + className="app-footer__button" + width={BlockSize.OneThird} + padding={2} + display={Display.Flex} + flexDirection={FlexDirection.Column} + alignItems={AlignItems.center} + tabIndex={0} + > + {connectedSite ? ( + + + } + > + + + + ) : ( + + )} + + {t('connections')} + + + - ) : ( - - )} - - {t('connections')} - - - + + ) : null} + ); }; diff --git a/ui/components/multichain/app-footer/app-footer.scss b/ui/components/multichain/app-footer/app-footer.scss index c36d1a046659..dac248d579e4 100644 --- a/ui/components/multichain/app-footer/app-footer.scss +++ b/ui/components/multichain/app-footer/app-footer.scss @@ -1,8 +1,41 @@ .app-footer { + $height-screen-sm-max: 100%; + $width-screen-sm-min: 85vw; + $width-screen-md-min: 80vw; + $width-screen-lg-min: 62vw; + bottom: 0; position: sticky; + z-index: 55; // we are applying same z-index for header as well + min-height: 64px; + flex-flow: column nowrap; + + &__contents { + height: 64px; + box-shadow: var(--shadow-size-md) var(--color-shadow-default); + + @include screen-sm-max { + height: $height-screen-sm-max; + } + + @include screen-sm-min { + width: $width-screen-sm-min; + margin-bottom: 10vh; // same as main container + } + + @include screen-md-min { + width: $width-screen-md-min; + } + + @include screen-lg-min { + width: $width-screen-lg-min; + } + } - &__button { - cursor: pointer; + &__actions-button { + &:hover, + &:focus { + background-color: var(--color-primary-default); + } } } diff --git a/ui/components/multichain/app-footer/app-footer.test.js b/ui/components/multichain/app-footer/app-footer.test.js new file mode 100644 index 000000000000..d6b3e82a5146 --- /dev/null +++ b/ui/components/multichain/app-footer/app-footer.test.js @@ -0,0 +1,25 @@ +import React from 'react'; +import configureStore from '../../../store/store'; +import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import mockState from '../../../../test/data/mock-state.json'; +import { AppFooter } from '.'; + +const store = configureStore({ + ...mockState, + activeTab: { + origin: 'https://remix.ethereum.org', + }, +}); + +describe('App Footer', () => { + it('should match snapshot', () => { + const { container } = renderWithProvider(, store); + expect(container).toMatchSnapshot(); + }); + + it('should render correctly', () => { + const { queryByTestId } = renderWithProvider(, store); + + expect(queryByTestId('app-footer')).toBeDefined(); + }); +}); diff --git a/ui/css/itcss/components/newui-sections.scss b/ui/css/itcss/components/newui-sections.scss index f0462fd5d091..1226492d64fd 100644 --- a/ui/css/itcss/components/newui-sections.scss +++ b/ui/css/itcss/components/newui-sections.scss @@ -58,7 +58,6 @@ .main-container { width: 85vw; - margin-bottom: 10vh; min-height: 90vh; box-shadow: var(--shadow-size-xs) var(--color-shadow-default); } diff --git a/ui/pages/routes/routes.component.js b/ui/pages/routes/routes.component.js index deb2f0986835..1a5c525d5661 100644 --- a/ui/pages/routes/routes.component.js +++ b/ui/pages/routes/routes.component.js @@ -35,6 +35,7 @@ import { ImportNftsModal, ImportTokensModal, SelectActionModal, + AppFooter, } from '../../components/multichain'; import UnlockPage from '../unlock-page'; import Alerts from '../../components/app/alerts'; @@ -478,6 +479,25 @@ export default class Routes extends Component { return isHandlingPermissionsRequest || isHandlingAddEthereumChainRequest; } + showFooter() { + if (Boolean(process.env.MULTICHAIN) === false) { + return false; + } + + const { location } = this.props; + const isHomePage = Boolean( + matchPath(location.pathname, { path: DEFAULT_ROUTE, exact: true }), + ); + const isConnectionsPage = Boolean( + matchPath(location.pathname, { path: CONNECTIONS, exact: true }), + ); + const isAssetPage = Boolean( + matchPath(location.pathname, { path: ASSET_ROUTE, exact: false }), + ); + + return isAssetPage || isHomePage || isConnectionsPage; + } + showOnboardingHeader() { const { location } = this.props; @@ -619,6 +639,7 @@ export default class Routes extends Component { {!isLoading && isNetworkLoading ? : null} {this.renderRoutes()} + {this.showFooter() && } {isUnlocked ? : null} );