diff --git a/package-lock.json b/package-lock.json index 84b5833a6..198e0b07c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "ethers": "^5.7.1", "flickity": "^2.3.0", "gatsby": "^4.10.1", + "gatsby-link": "^4.23.0", "gatsby-plugin-image": "^2.10.0", "gatsby-plugin-manifest": "^4.10.1", "gatsby-plugin-offline": "^5.10.1", diff --git a/package.json b/package.json index 071150577..2ebc08814 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ "/src/" ], "moduleNameMapper": { - "\\.(css|less|sass|scss|gif|ttf|eot|svg)$": "/src/__mocks__/files.ts" + "\\.(css|less|sass|scss|gif|ttf|eot|svg)$": "/src/__mocks__/files.ts", + "^gatsby-page-utils/(.*)$": "gatsby-page-utils/dist/$1" } }, "repository": { @@ -64,6 +65,7 @@ "ethers": "^5.7.1", "flickity": "^2.3.0", "gatsby": "^4.10.1", + "gatsby-link": "^4.23.0", "gatsby-plugin-image": "^2.10.0", "gatsby-plugin-manifest": "^4.10.1", "gatsby-plugin-offline": "^5.10.1", diff --git a/src/components/Category/CategoryBanner.tsx b/src/components/Category/CategoryBanner.tsx index b56d03330..748721409 100644 --- a/src/components/Category/CategoryBanner.tsx +++ b/src/components/Category/CategoryBanner.tsx @@ -4,10 +4,10 @@ import classNames from 'classnames' import Link from 'decentraland-gatsby/dist/components/Text/Link' import Markdown from 'decentraland-gatsby/dist/components/Text/Markdown' import Paragraph from 'decentraland-gatsby/dist/components/Text/Paragraph' -import { navigate } from 'decentraland-gatsby/dist/plugins/intl' import { HiringType, PoiType, ProposalType, isHiringType } from '../../entities/Proposal/types' import useFormatMessage from '../../hooks/useFormatMessage' +import { navigate } from '../../utils/locations' import AddPoi from '../Icon/ProposalCategories/AddPoi' import BanName from '../Icon/ProposalCategories/BanName' import Catalyst from '../Icon/ProposalCategories/Catalyst' diff --git a/src/components/Category/CategoryOption.tsx b/src/components/Category/CategoryOption.tsx index 276e3429b..95b8f8896 100644 --- a/src/components/Category/CategoryOption.tsx +++ b/src/components/Category/CategoryOption.tsx @@ -3,7 +3,6 @@ import React, { Fragment, useEffect, useMemo, useState } from 'react' import { useLocation } from '@reach/router' import classNames from 'classnames' import Paragraph from 'decentraland-gatsby/dist/components/Text/Paragraph' -import { navigate } from 'decentraland-gatsby/dist/plugins/intl' import isNumber from 'lodash/isNumber' import toSnakeCase from 'lodash/snakeCase' @@ -12,6 +11,7 @@ import { getNewGrantsCategoryIcon } from '../../entities/Grant/utils' import { ProposalType, toProposalType } from '../../entities/Proposal/types' import { CategoryIconVariant } from '../../helpers/styles' import useFormatMessage from '../../hooks/useFormatMessage' +import { navigate } from '../../utils/locations' import Arrow from '../Icon/Arrow' import All from '../Icon/ProposalCategories/All' import Grant from '../Icon/ProposalCategories/Grant' diff --git a/src/components/Category/CategoryPill.tsx b/src/components/Category/CategoryPill.tsx index 2a02a3119..71b272b02 100644 --- a/src/components/Category/CategoryPill.tsx +++ b/src/components/Category/CategoryPill.tsx @@ -1,11 +1,11 @@ import React from 'react' -import { Link } from '@reach/router' import classNames from 'classnames' import { Mobile, NotMobile } from 'decentraland-ui/dist/components/Media/Media' import { ProposalType } from '../../entities/Proposal/types' import locations from '../../utils/locations' +import Link from '../Common/Link' import Pill, { PillColor } from '../Common/Pill' const ColorsConfig: Record = { @@ -45,14 +45,14 @@ const CategoryPill = ({ className, proposalType, size = 'default', isLink }: Pro return ( <> - + {getProposalTypeShortLabel(proposalType)} - + {getProposalTypeLabel(proposalType)} diff --git a/src/components/Common/Link.css b/src/components/Common/Link.css new file mode 100644 index 000000000..8b496dae1 --- /dev/null +++ b/src/components/Common/Link.css @@ -0,0 +1,14 @@ +.Link { + font-size: inherit; + line-height: inherit; + color: var(--primary); +} + +.Link.Link--pointer { + cursor: pointer; +} + +.Link .icon { + font-size: 19px; + vertical-align: middle; +} diff --git a/src/components/Common/Link.tsx b/src/components/Common/Link.tsx new file mode 100644 index 000000000..4462b2264 --- /dev/null +++ b/src/components/Common/Link.tsx @@ -0,0 +1,38 @@ +import React, { useCallback, useMemo } from 'react' + +import classNames from 'classnames' + +import { isLocalLink, navigate } from '../../utils/locations' + +import './Link.css' + +export type LinkProps = React.AnchorHTMLAttributes + +export default React.memo(function Link({ target, rel, href, onClick, ...props }: LinkProps) { + const isLocal = useMemo(() => isLocalLink(href), [href]) + const linkTarget = useMemo(() => (!target && !isLocal ? '_blank' : target || undefined), [isLocal, target]) + const linkRel = useMemo(() => (!isLocal ? classNames(rel, 'noopener', 'noreferrer') : rel), [isLocal, rel]) + const onClickHandler = useCallback( + (e: React.MouseEvent) => { + if (onClick) { + onClick(e) + } + if (isLocal && href) { + e.preventDefault() + navigate(href) + } + }, + [href, isLocal, onClick] + ) + + return ( + + ) +}) diff --git a/src/components/Common/LinkWithTitle.tsx b/src/components/Common/LinkWithTitle.tsx index 4ab20c16a..0d5e52d89 100644 --- a/src/components/Common/LinkWithTitle.tsx +++ b/src/components/Common/LinkWithTitle.tsx @@ -19,6 +19,7 @@ const fetchTitle = async (url: string) => { return response.title || '' } catch (error) { console.error(error) + return '' } } diff --git a/src/components/Delegation/DelegatorCardProfile.tsx b/src/components/Delegation/DelegatorCardProfile.tsx index 99a95ce64..7d3b46d3b 100644 --- a/src/components/Delegation/DelegatorCardProfile.tsx +++ b/src/components/Delegation/DelegatorCardProfile.tsx @@ -1,10 +1,9 @@ import React from 'react' import { useIntl } from 'react-intl' -import { Link } from '@reach/router' - import useFormatMessage from '../../hooks/useFormatMessage' import locations from '../../utils/locations' +import Link from '../Common/Link' import ChevronRightCircleOutline from '../Icon/ChevronRightCircleOutline' import Username from '../User/Username' @@ -20,7 +19,7 @@ function DelegatorCardProfile({ address, vp }: Props) { const intl = useIntl() return ( - +
diff --git a/src/components/GrantRequest/GrantRequestSectionCard.tsx b/src/components/GrantRequest/GrantRequestSectionCard.tsx index ca5433b57..91e6e5470 100644 --- a/src/components/GrantRequest/GrantRequestSectionCard.tsx +++ b/src/components/GrantRequest/GrantRequestSectionCard.tsx @@ -1,9 +1,9 @@ import React from 'react' import Skeleton from 'react-loading-skeleton' -import { Link } from '@reach/router' import classNames from 'classnames' +import Link from '../Common/Link' import ExclamationCircle from '../Icon/ExclamationCircle' import './GrantRequestSectionCard.css' @@ -35,7 +35,7 @@ export const GrantRequestSectionCard = ({ error && 'GrantRequestSectionCard__Error', href && 'GrantRequestSectionCard__Hoverable' )} - to={href || ''} + href={href || ''} >
diff --git a/src/components/Grants/GrantBeneficiaryItem.tsx b/src/components/Grants/GrantBeneficiaryItem.tsx index 53cb47c89..c27621029 100644 --- a/src/components/Grants/GrantBeneficiaryItem.tsx +++ b/src/components/Grants/GrantBeneficiaryItem.tsx @@ -1,7 +1,6 @@ import React from 'react' import { useIntl } from 'react-intl' -import { Link } from '@reach/router' import Markdown from 'decentraland-gatsby/dist/components/Text/Markdown' import { Card } from 'decentraland-ui/dist/components/Card/Card' import { Mobile, NotMobile } from 'decentraland-ui/dist/components/Media/Media' @@ -12,6 +11,7 @@ import { isProposalInCliffPeriod } from '../../entities/Proposal/utils' import useFormatMessage from '../../hooks/useFormatMessage' import { abbreviateTimeDifference, formatDate } from '../../utils/date/Time' import locations from '../../utils/locations' +import Link from '../Common/Link' import ChevronRightCircleOutline from '../Icon/ChevronRightCircleOutline' import Username from '../User/Username' diff --git a/src/components/Grants/GrantCard/GrantCard.tsx b/src/components/Grants/GrantCard/GrantCard.tsx index fc0fd96b4..b3f0e84c5 100644 --- a/src/components/Grants/GrantCard/GrantCard.tsx +++ b/src/components/Grants/GrantCard/GrantCard.tsx @@ -1,11 +1,11 @@ import React, { useState } from 'react' -import { Link } from '@reach/router' import classNames from 'classnames' import { GrantWithUpdate } from '../../../entities/Proposal/types' import { isProposalInCliffPeriod } from '../../../entities/Proposal/utils' import locations from '../../../utils/locations' +import Link from '../../Common/Link' import ProposalUpdate from '../../Proposal/Update/ProposalUpdate' import CliffProgress from './CliffProgress' @@ -26,7 +26,7 @@ const GrantCard = ({ grant, hoverable = false }: Props) => { return ( hoverable && setExpanded(true)} onMouseLeave={() => hoverable && setExpanded(false)} className={classNames('GrantCard', hoverable && 'GrantCard__Expanded')} diff --git a/src/components/Grants/GrantsPastItem.tsx b/src/components/Grants/GrantsPastItem.tsx index 6c663fbcf..44cc45f4a 100644 --- a/src/components/Grants/GrantsPastItem.tsx +++ b/src/components/Grants/GrantsPastItem.tsx @@ -1,13 +1,12 @@ import React, { useCallback } from 'react' -import { navigate } from 'decentraland-gatsby/dist/plugins/intl' import { Table } from 'decentraland-ui/dist/components/Table/Table' import { ProposalGrantCategory } from '../../entities/Grant/types' import { Grant } from '../../entities/Proposal/types' import useFormatMessage from '../../hooks/useFormatMessage' import Time from '../../utils/date/Time' -import locations from '../../utils/locations' +import locations, { navigate } from '../../utils/locations' import ChevronRight from '../Icon/ChevronRight' import GrantPill from './GrantPill' diff --git a/src/components/Grants/RequestBanner.tsx b/src/components/Grants/RequestBanner.tsx index a652fefec..b5ffa3e31 100644 --- a/src/components/Grants/RequestBanner.tsx +++ b/src/components/Grants/RequestBanner.tsx @@ -1,11 +1,10 @@ import React from 'react' -import { navigate } from 'decentraland-gatsby/dist/plugins/intl/utils' import { Button } from 'decentraland-ui/dist/components/Button/Button' import { ProposalType } from '../../entities/Proposal/types' import useFormatMessage from '../../hooks/useFormatMessage' -import locations from '../../utils/locations' +import locations, { navigate } from '../../utils/locations' import './RequestBanner.css' diff --git a/src/components/Home/MainBanner.tsx b/src/components/Home/MainBanner.tsx index 7ece28655..b05a72436 100644 --- a/src/components/Home/MainBanner.tsx +++ b/src/components/Home/MainBanner.tsx @@ -1,10 +1,10 @@ import React, { useEffect, useState } from 'react' -import { Link } from '@reach/router' import { Button } from 'decentraland-ui/dist/components/Button/Button' import { DAO_DISCORD_URL, DOCS_URL } from '../../constants' import useFormatMessage from '../../hooks/useFormatMessage' +import Link from '../Common/Link' import CloseCircle from '../Icon/CloseCircle' import './MainBanner.css' @@ -40,10 +40,10 @@ const MainBanner = () => {

{t('page.home.main_banner.title')}

{t('page.home.main_banner.description')}

- -
diff --git a/src/components/Home/MetricsCard.tsx b/src/components/Home/MetricsCard.tsx index b4becc157..96a1429f0 100644 --- a/src/components/Home/MetricsCard.tsx +++ b/src/components/Home/MetricsCard.tsx @@ -1,8 +1,9 @@ import React from 'react' -import { Link } from '@reach/router' import { Card } from 'decentraland-ui/dist/components/Card/Card' +import Link from '../Common/Link' + import HomeLoader from './HomeLoader' import './MetricsCard.css' @@ -17,7 +18,7 @@ interface Props { const MetricsCard = ({ href, category, title, description, isLoading, loadingLabel }: Props) => { return ( - + {!isLoading && (

{category}

diff --git a/src/components/Home/OpenProposal.tsx b/src/components/Home/OpenProposal.tsx index 01b6190ac..8bd9dd69c 100644 --- a/src/components/Home/OpenProposal.tsx +++ b/src/components/Home/OpenProposal.tsx @@ -1,6 +1,5 @@ import React, { useMemo } from 'react' -import { Link } from '@reach/router' import useAuthContext from 'decentraland-gatsby/dist/context/Auth/useAuthContext' import { Mobile } from 'decentraland-ui/dist/components/Media/Media' import isEmpty from 'lodash/isEmpty' @@ -13,6 +12,7 @@ import useProposalVotes from '../../hooks/useProposalVotes' import Time from '../../utils/date/Time' import locations from '../../utils/locations' import CategoryPill from '../Category/CategoryPill' +import Link from '../Common/Link' import ChevronRight from '../Icon/ChevronRight' import Username from '../User/Username' @@ -51,7 +51,7 @@ const OpenProposal = ({ proposal }: Props) => { }) return ( - +
diff --git a/src/components/Layout/BurgerMenu/MobileNavigation.tsx b/src/components/Layout/BurgerMenu/MobileNavigation.tsx index a6e9213f4..b461ddb73 100644 --- a/src/components/Layout/BurgerMenu/MobileNavigation.tsx +++ b/src/components/Layout/BurgerMenu/MobileNavigation.tsx @@ -1,13 +1,12 @@ import React from 'react' import Link from 'decentraland-gatsby/dist/components/Text/Link' -import { navigate } from 'decentraland-gatsby/dist/plugins/intl' import prevent from 'decentraland-gatsby/dist/utils/react/prevent' import { Button } from 'decentraland-ui/dist/components/Button/Button' import { Header } from 'decentraland-ui/dist/components/Header/Header' import useFormatMessage from '../../../hooks/useFormatMessage' -import locations from '../../../utils/locations' +import locations, { navigate } from '../../../utils/locations' import { NavigationProps, NavigationTab } from '../Navigation' import './MobileNavigation.css' diff --git a/src/components/Layout/ContentLayout.tsx b/src/components/Layout/ContentLayout.tsx index 4fa8c7c17..2000df389 100644 --- a/src/components/Layout/ContentLayout.tsx +++ b/src/components/Layout/ContentLayout.tsx @@ -1,12 +1,11 @@ import React from 'react' import classNames from 'classnames' -import { navigate } from 'decentraland-gatsby/dist/plugins/intl' import { Back } from 'decentraland-ui/dist/components/Back/Back' import { Container } from 'decentraland-ui/dist/components/Container/Container' import usePreventNavigation from '../../hooks/usePreventNavigation' -import locations from '../../utils/locations' +import locations, { navigate } from '../../utils/locations' import './ContentLayout.css' diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index 1feeaade1..7f61eafcd 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -4,7 +4,6 @@ import { ChainId } from '@dcl/schemas/dist/dapps/chain-id' // import WalletSelectorModal from 'decentraland-gatsby/dist/components/Modal/WalletSelectorModal' // import WrongNetworkModal from 'decentraland-gatsby/dist/components/Modal/WrongNetworkModal' import useAuthContext from 'decentraland-gatsby/dist/context/Auth/useAuthContext' -import { DecentralandIntlContext } from 'decentraland-gatsby/dist/plugins/intl/types' import env from 'decentraland-gatsby/dist/utils/env' import { Footer } from 'decentraland-ui/dist/components/Footer/Footer' import { Locale } from 'decentraland-ui/dist/components/LanguageIcon/LanguageIcon' @@ -25,15 +24,10 @@ export function getSupportedChainIds(): ChainId[] { export type LayoutProps = Omit & { rightMenu: NavbarProps['rightMenu'] - pageContext?: { - intl?: DecentralandIntlContext - } children?: React.ReactNode } -export default function Layout({ children, pageContext, ...props }: LayoutProps) { - const locale = pageContext?.intl?.locale || 'en' - const locales = pageContext?.intl?.locales || ['en'] +export default function Layout({ children, ...props }: LayoutProps) { const [, state] = useAuthContext() const handleChangeLocal = function (_: React.SyntheticEvent, data: DropdownProps) { @@ -70,12 +64,7 @@ export default function Layout({ children, pageContext, ...props }: LayoutProps) onConnect={(providerType, chainId) => state.connect(providerType, chainId)} onClose={() => state.select(false)} /> */} -