Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FET-1689: Name Renew Deeplink Params #907

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions e2e/specs/stateless/extendNames.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ test('should be able to extend multiple names on the address page', async ({
await page.waitForLoadState('networkidle')

await expect(page.getByText('Your "Extend names" transaction was successful')).toBeVisible({
timeout: 10000,
timeout: 15000,
})
await subgraph.sync()

Expand Down Expand Up @@ -624,7 +624,7 @@ test('should be able to extend a single wrapped name using deep link', async ({
const homePage = makePageObject('HomePage')
await homePage.goto()
await login.connect()
await page.goto(`/${name}?renew`)
await page.goto(`/${name}?renew=123`)

const timestamp = await profilePage.getExpiryTimestamp()

Expand Down Expand Up @@ -670,7 +670,7 @@ test('should not be able to extend a name which is not registered', async ({
const homePage = makePageObject('HomePage')
await homePage.goto()
await login.connect()
await page.goto(`/${name}?renew`)
await page.goto(`/${name}?renew=123`)
await expect(page.getByRole('heading', { name: `Register ${name}` })).toBeVisible()
})

Expand All @@ -681,6 +681,6 @@ test('renew deep link should redirect to registration when not logged in', async
const name = 'this-name-does-not-exist.eth'
const homePage = makePageObject('HomePage')
await homePage.goto()
await page.goto(`/${name}?renew`)
await page.goto(`/${name}?renew=123`)
await expect(page.getByRole('heading', { name: `Register ${name}` })).toBeVisible()
})
26 changes: 1 addition & 25 deletions src/components/ProfileSnippet.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { useSearchParams } from 'next/navigation'
import { useEffect, useMemo } from 'react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
import { useAccount } from 'wagmi'

import { Button, mq, NametagSVG, Tag, Typography } from '@ensdomains/thorin'

import FastForwardSVG from '@app/assets/FastForward.svg'
import VerifiedPersonSVG from '@app/assets/VerifiedPerson.svg'
import { useAbilities } from '@app/hooks/abilities/useAbilities'
import { useBeautifiedName } from '@app/hooks/useBeautifiedName'
import { useNameDetails } from '@app/hooks/useNameDetails'
import { useRouterWithHistory } from '@app/hooks/useRouterWithHistory'

import { useTransactionFlow } from '../transaction-flow/TransactionFlowProvider'
Expand Down Expand Up @@ -195,8 +192,6 @@ export const ProfileSnippet = ({
const { usePreparedDataInput } = useTransactionFlow()
const showExtendNamesInput = usePreparedDataInput('ExtendNames')
const abilities = useAbilities({ name })
const details = useNameDetails({ name })
const { isConnected } = useAccount()

const beautifiedName = useBeautifiedName(name)

Expand All @@ -206,27 +201,8 @@ export const ProfileSnippet = ({
const location = getTextRecord?.('location')?.value
const recordName = getTextRecord?.('name')?.value

const searchParams = useSearchParams()

const renew = (searchParams.get('renew') ?? null) !== null
const available = details.registrationStatus === 'available'

const { canSelfExtend, canEdit } = abilities.data ?? {}

useEffect(() => {
if (renew && !isConnected) {
return router.push(`/${name}/register`)
}

if (renew && !available) {
showExtendNamesInput(`extend-names-${name}`, {
names: [name],
isSelf: canSelfExtend,
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isConnected, available, renew, name, canSelfExtend])

const ActionButton = useMemo(() => {
if (button === 'extend')
return (
Expand Down
67 changes: 66 additions & 1 deletion src/components/pages/profile/[name]/Profile.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useConnectModal } from '@rainbow-me/rainbowkit'
import Head from 'next/head'
import { useEffect, useMemo } from 'react'
import { useSearchParams } from 'next/navigation'
import { useEffect, useMemo, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
import { match } from 'ts-pattern'
Expand All @@ -16,6 +18,7 @@ import { useProtectedRoute } from '@app/hooks/useProtectedRoute'
import { useQueryParameterState } from '@app/hooks/useQueryParameterState'
import { useRouterWithHistory } from '@app/hooks/useRouterWithHistory'
import { Content, ContentWarning } from '@app/layouts/Content'
import { useTransactionFlow } from '@app/transaction-flow/TransactionFlowProvider'
import { OG_IMAGE_URL } from '@app/utils/constants'
import { shouldRedirect } from '@app/utils/shouldRedirect'
import { formatFullExpiry, makeEtherscanLink } from '@app/utils/utils'
Expand Down Expand Up @@ -104,6 +107,67 @@ export const NameAvailableBanner = ({
)
}

function useRenew(name: string) {
const parseNumericString = (time: string | null) => {
if (!time) return

if (typeof +time === 'number' && !Number.isNaN(+time)) {
return +time
}
}

const [opened, setOpened] = useState<boolean>(false)
const router = useRouterWithHistory()

const { registrationStatus, isLoading } = useNameDetails({ name })
const abilities = useAbilities({ name })
const searchParams = useSearchParams()
const { isConnected, isDisconnected } = useAccount()
const { usePreparedDataInput } = useTransactionFlow()
const { openConnectModal } = useConnectModal()
const showExtendNamesInput = usePreparedDataInput('ExtendNames')

const { data: { canSelfExtend } = {} } = abilities
const isAvailableName = registrationStatus === 'available'
const renewSeconds = parseNumericString(searchParams.get('renew'))

useEffect(() => {
if (opened || !renewSeconds || isLoading) return

if (isAvailableName) {
setOpened(true)
router.push(`/${name}/register`)
return
}

if (!isAvailableName && isDisconnected) {
setOpened(true)
openConnectModal?.()
return
}

if (!isAvailableName && isConnected) {
setOpened(true)
showExtendNamesInput(`extend-names-${name}`, {
names: [name],
isSelf: canSelfExtend,
seconds: renewSeconds,
})
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
isAvailableName,
isLoading,
isConnected,
isDisconnected,
name,
canSelfExtend,
renewSeconds,
opened,
])
}

const ProfileContent = ({ isSelf, isLoading: parentIsLoading, name }: Props) => {
const router = useRouterWithHistory()
const { t } = useTranslation('profile')
Expand Down Expand Up @@ -181,6 +245,7 @@ const ProfileContent = ({ isSelf, isLoading: parentIsLoading, name }: Props) =>

const abilities = useAbilities({ name: normalisedName })

useRenew(normalisedName)
// hook for redirecting to the correct profile url
// profile.decryptedName fetches labels from NW/subgraph
// normalisedName fetches labels from localStorage
Expand Down
9 changes: 7 additions & 2 deletions src/transaction-flow/input/ExtendNames/ExtendNames-flow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ const NamesList = ({ names }: NamesListProps) => {

type Data = {
names: string[]
seconds?: number
isSelf?: boolean
}

Expand All @@ -169,7 +170,11 @@ export type Props = {

const minSeconds = ONE_DAY

const ExtendNames = ({ data: { names, isSelf }, dispatch, onDismiss }: Props) => {
const ExtendNames = ({
data: { seconds: defaultSeconds = ONE_YEAR, names, isSelf },
dispatch,
onDismiss,
}: Props) => {
const { t } = useTranslation(['transactionFlow', 'common'])
const { data: ethPrice } = useEthPrice()

Expand All @@ -195,7 +200,7 @@ const ExtendNames = ({ data: { names, isSelf }, dispatch, onDismiss }: Props) =>
const decrementView = () => (viewIdx <= 0 ? onDismiss() : setViewIdx(viewIdx - 1))
const view = flow[viewIdx]

const [seconds, setSeconds] = useState(ONE_YEAR)
const [seconds, setSeconds] = useState(Math.max(defaultSeconds, ONE_YEAR))
const [durationType, setDurationType] = useState<'years' | 'date'>('years')

const years = secondsToYears(seconds)
Expand Down
Loading