diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 11294aa50824..e8d26a536c16 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -806,6 +806,9 @@ "connectAccountOrCreate": { "message": "Connect account or create new" }, + "connectAccounts": { + "message": "Connect accounts" + }, "connectCustodialAccountMenu": { "message": "Connect Custodial Account" }, @@ -2810,6 +2813,12 @@ "noAddressForName": { "message": "No address has been set for this name." }, + "noConnectedAccountDescription": { + "message": "Select an account you want to use on this site to continue." + }, + "noConnectedAccountTitle": { + "message": "MetaMask isn’t connected to this site" + }, "noConversionDateAvailable": { "message": "No currency conversion date available" }, diff --git a/ui/components/multichain/app-header/app-header.js b/ui/components/multichain/app-header/app-header.js index 4c3580eef2f5..8da8f544ed12 100644 --- a/ui/components/multichain/app-header/app-header.js +++ b/ui/components/multichain/app-header/app-header.js @@ -14,6 +14,7 @@ import { BUILD_QUOTE_ROUTE, CONFIRM_TRANSACTION_ROUTE, CONNECTED_ACCOUNTS_ROUTE, + CONNECTIONS, DEFAULT_ROUTE, SWAPS_ROUTE, } from '../../../helpers/constants/routes'; @@ -75,7 +76,7 @@ import { SEND_STAGES, getSendStage } from '../../../ducks/send'; import Tooltip from '../../ui/tooltip'; import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard'; import { MINUTE } from '../../../../shared/constants/time'; -import { shortenAddress } from '../../../helpers/utils/util'; +import { getURLHost, shortenAddress } from '../../../helpers/utils/util'; export const AppHeader = ({ location }) => { const trackEvent = useContext(MetaMetricsContext); @@ -173,6 +174,11 @@ export const AppHeader = ({ location }) => { }); }, [chainId, dispatch, trackEvent]); + const handleConnectionsRoute = () => { + const hostName = getURLHost(origin); + + history.push(`${CONNECTIONS}/${encodeURIComponent(hostName)}`); + }; // This is required to ensure send and confirmation screens // look as desired const headerBottomMargin = !popupStatus && disableNetworkPicker ? 4 : 0; @@ -364,11 +370,16 @@ export const AppHeader = ({ location }) => { { - history.push(CONNECTED_ACCOUNTS_ROUTE); - trackEvent({ - event: MetaMetricsEventName.NavConnectedSitesOpened, - category: MetaMetricsEventCategory.Navigation, - }); + if (process.env.MULTICHAIN) { + handleConnectionsRoute(); + } else { + history.push(CONNECTED_ACCOUNTS_ROUTE); + trackEvent({ + event: + MetaMetricsEventName.NavConnectedSitesOpened, + category: MetaMetricsEventCategory.Navigation, + }); + } }} /> diff --git a/ui/components/multichain/pages/connections/components/__snapshots__/no-connections.test.tsx.snap b/ui/components/multichain/pages/connections/components/__snapshots__/no-connections.test.tsx.snap new file mode 100644 index 000000000000..90139835245a --- /dev/null +++ b/ui/components/multichain/pages/connections/components/__snapshots__/no-connections.test.tsx.snap @@ -0,0 +1,20 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`No Connections Content should render correctly 1`] = ` +
+
+

+ MetaMask isn’t connected to this site +

+

+ Select an account you want to use on this site to continue. +

+
+
+`; diff --git a/ui/components/multichain/pages/connections/components/no-connection.tsx b/ui/components/multichain/pages/connections/components/no-connection.tsx new file mode 100644 index 000000000000..3f5e812274da --- /dev/null +++ b/ui/components/multichain/pages/connections/components/no-connection.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { + AlignItems, + Display, + FlexDirection, + JustifyContent, + TextAlign, + TextVariant, +} from '../../../../../helpers/constants/design-system'; +import { useI18nContext } from '../../../../../hooks/useI18nContext'; +import { Box, Text } from '../../../../component-library'; + +export const NoConnectionContent = () => { + const t = useI18nContext(); + return ( + + + {t('noConnectedAccountTitle')} + + + + {t('noConnectedAccountDescription')} + + + ); +}; diff --git a/ui/components/multichain/pages/connections/components/no-connections.test.tsx b/ui/components/multichain/pages/connections/components/no-connections.test.tsx new file mode 100644 index 000000000000..220a773d660b --- /dev/null +++ b/ui/components/multichain/pages/connections/components/no-connections.test.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { renderWithProvider } from '../../../../../../test/jest'; +import {NoConnectionContent} from './no-connection'; + +describe('No Connections Content', () => { + const render = () => { + + return renderWithProvider( + + ); + }; + it('should render correctly', () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); +}); \ No newline at end of file diff --git a/ui/components/multichain/pages/connections/connections.js b/ui/components/multichain/pages/connections/connections.js deleted file mode 100644 index 78232d739663..000000000000 --- a/ui/components/multichain/pages/connections/connections.js +++ /dev/null @@ -1,5 +0,0 @@ -import React from 'react'; - -export const Connections = () => { - return
; -}; diff --git a/ui/components/multichain/pages/connections/connections.tsx b/ui/components/multichain/pages/connections/connections.tsx new file mode 100644 index 000000000000..6d96d7f69c97 --- /dev/null +++ b/ui/components/multichain/pages/connections/connections.tsx @@ -0,0 +1,103 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import { useHistory } from 'react-router-dom'; +import { + AlignItems, + BackgroundColor, + Display, + IconColor, + JustifyContent, + TextAlign, + TextVariant, +} from '../../../../helpers/constants/design-system'; +import { DEFAULT_ROUTE } from '../../../../helpers/constants/routes'; +import { getURLHost } from '../../../../helpers/utils/util'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; +import { + getConnectedSitesList, + getOriginOfCurrentTab, +} from '../../../../selectors'; +import { + AvatarFavicon, + AvatarFaviconSize, + Box, + ButtonIcon, + ButtonIconSize, + ButtonPrimary, + ButtonPrimarySize, + Icon, + IconName, + IconSize, + Text, +} from '../../../component-library'; +import { Content, Footer, Header, Page } from '../page'; +import { NoConnectionContent } from './components/no-connection'; + +export const Connections = () => { + const t = useI18nContext(); + const history = useHistory(); + const activeTabOrigin = useSelector(getOriginOfCurrentTab); + const subjectMetadata: { [key: string]: any } = useSelector( + getConnectedSitesList, + ); + const connectedSubjectsMetadata = subjectMetadata[activeTabOrigin]; + return ( + +
history.push(DEFAULT_ROUTE)} + size={ButtonIconSize.Sm} + /> + } + > + + {connectedSubjectsMetadata?.iconUrl ? ( + + ) : ( + + )} + + {getURLHost(activeTabOrigin)} + + +
+ + {/* TODO: Replace null When accounts connected - create a separate component - Separate Ticket */} + + {connectedSubjectsMetadata ? null : } + +
+ {/* TODO: When accounts connected - Two Separate Buttons - Separate Ticket */} + + + {t('connectAccounts')} + +
+
+ ); +}; diff --git a/ui/components/multichain/pages/connections/index.scss b/ui/components/multichain/pages/connections/index.scss new file mode 100644 index 000000000000..0452f92353aa --- /dev/null +++ b/ui/components/multichain/pages/connections/index.scss @@ -0,0 +1,5 @@ +.connections-page { + &__no-site-connected-content { + height: 100%; //Box Props doesn't have height as a utility prop + } +} diff --git a/ui/components/multichain/pages/index.scss b/ui/components/multichain/pages/index.scss index 5bc43557f0bf..f867526ce960 100644 --- a/ui/components/multichain/pages/index.scss +++ b/ui/components/multichain/pages/index.scss @@ -1,3 +1,4 @@ @import 'page/'; @import 'send/'; +@import 'connections/'; @import 'permissions-page/permissions-page'; diff --git a/ui/pages/routes/routes.component.js b/ui/pages/routes/routes.component.js index 57090aea3550..6d2ea1c5e423 100644 --- a/ui/pages/routes/routes.component.js +++ b/ui/pages/routes/routes.component.js @@ -378,7 +378,10 @@ export default class Routes extends Component { ///: END:ONLY_INCLUDE_IF } {process.env.MULTICHAIN && ( - + )} {process.env.MULTICHAIN && ( @@ -484,6 +487,17 @@ export default class Routes extends Component { return true; } + const isConnectionsPage = Boolean( + matchPath(location.pathname, { + path: CONNECTIONS, + exact: false, + }), + ); + + if (isConnectionsPage) { + return true; + } + if (windowType === ENVIRONMENT_TYPE_POPUP && this.onConfirmPage()) { return true; }