Skip to content

Commit

Permalink
base implementation of ownership
Browse files Browse the repository at this point in the history
  • Loading branch information
storywithoutend committed Sep 8, 2023
1 parent 2938f61 commit 645b344
Show file tree
Hide file tree
Showing 67 changed files with 3,328 additions and 873 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"@ensdomains/ens-validation": "^0.1.0",
"@ensdomains/ensjs": "3.0.0-alpha.66",
"@ensdomains/eth-ens-namehash": "^2.0.15",
"@ensdomains/thorin": "0.6.42",
"@ensdomains/thorin": "0.6.43",
"@ethersproject/abi": "^5.6.4",
"@ethersproject/abstract-provider": "^5.7.0",
"@ethersproject/abstract-signer": "^5.7.0",
Expand Down
18 changes: 10 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 34 additions & 1 deletion public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@
"understand": "I understand",
"feedback": "Feedback",
"enterEmail": "Enter your email",
"migrate": "Migrate"
"migrate": "Migrate",
"setToSelf": "Set to self",
"editRoles": "Edit roles",
"setReminder": "Set reminder"
},
"unit": {
"years_one": "{{count}} year",
Expand Down Expand Up @@ -99,6 +102,7 @@
"notOwned": "Not Owned",
"manager": "Manager",
"all": "All Names",
"copy": "Copy name",
"yourPrimaryName": "Your primary name",
"expiresInYears_one": "Expires in {{count}} year",
"expiresInYears_other": "Expires in {{count}} years",
Expand Down Expand Up @@ -346,5 +350,34 @@
"testnetFaucet": {
"explanation": "Each address on goerli can claim {{ amount }}ETH to test out the ENS manager app, as well as all the new contracts.",
"note": "It may take a few minutes to show up in your wallet."
},
"roles": {
"owner": {
"title": "owner",
"description": "The address that owns this name."
},
"dns-owner": {
"title": "DNS owner",
"description": "The address that owns this name."
},
"parent-owner": {
"title": "Parent owner",
"description": "The address that owns the parent of this name."
},
"manager": {
"title": "manager",
"description": "An address or contract that can change the profile, settings, and profile managers."
},
"profile-editor": {
"title": "Profile editor",
"description": "An address that can change the profile."
},
"eth-record": {
"title": "ETH record",
"description": "The address that this name points to."
}
},
"dns": {
"refresh": "Refresh DNS"
}
}
34 changes: 33 additions & 1 deletion public/locales/en/profile.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,39 @@
"name": "Records"
},
"ownership": {
"name": "Ownership"
"name": "Ownership",
"sections": {
"roles": {
"title": "Roles",
"addresses_one": "{{count}} address",
"addresses_other": "{{count}} addresses"
},
"expiry": {
"panel": {
"expiry": {
"title": "Name expires"
},
"grace-period": {
"title": "Grace period ends",
"tooltip": {
"content": "A 90 day grace window after expiration, when the name can still be extended but not re-registered."
}
},
"registration": {
"title": "Registered"
},
"parent-expiry": {
"title": "Parent name expires"
},
"parent-grace-period": {
"title": "Parent grace period ends"
}
}
},
"contract": {
"warning": "Some apps may show the contract address as the owner. This doesn't affect your ownership."
}
}
},
"subnames": {
"name": "Subnames"
Expand Down
68 changes: 68 additions & 0 deletions public/locales/en/transactionFlow.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,21 @@
"customLabel": "Custom resolver",
"customPlaceholder": "Enter custom resolver address"
},
"editRoles": {
"views": {
"main": {
"title": "Edit roles"
},
"editRole": {
"title": "Change {{role}}",
"views": {
"intro": {
"current": "Current {{role}}"
}
}
}
}
},
"extendNames": {
"title_one": "Extend Name",
"title_other": "Extend {{count}} Names",
Expand Down Expand Up @@ -310,6 +325,59 @@
"title": "Remove Primary Name",
"description": "This name will no longer appear as the name for this address. However, transactions to this name will still resolve to this address unless you remove the ETH record."
},
"sendName": {
"views": {
"error": {
"title": "Cannot send name",
"description": "You do not have permission to send this name."
},
"search": {
"placeholder": "ENS name or Ethereum address",
"views": {
"error": {
"message": "Something went wrong. Please try again."
},
"intro": {
"message": "Search for an ENS name or ETH address"
},
"noResults": {
"message": "No results found"
}
}
},
"summary": {
"title": "Send name",
"fields": {
"name": {
"label": "Name",
"expires": "Expires {{date}}"
},
"recipient": "Recipient",
"options": {
"label": "Options",
"title": "Reset profile",
"description": "Remove all profile records. This costs additional gas."
},
"summary": {
"title": "Summary of changes",
"updates": {
"role": "Update {{role}} role to {{address}}",
"eth-record": "Update ETH record to {{address}}"
},
"remove": {
"profile": "Remove profile records"
}
}
}
},
"confirmation": {
"title": "Sending name",
"description": "Sending this name transfers ownership to the recipient, giving them your control.",
"warning": "You will lose the ability to modify, receive payments, or use it as your primary name.",
"learnMore": "Learn about sending names"
}
}
},
"syncManager": {
"title": "Sync manager",
"description": "Syncing the manager will make you the new manager of this name. The current manager <strong>({{manager}})</strong> will no longer be able to make changes.",
Expand Down
116 changes: 116 additions & 0 deletions src/components/@atoms/ExpandableSection/ExpandableSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { PropsWithChildren, useRef, useState } from 'react'
import { TransitionState, useTransition } from 'react-transition-state'
import styled, { css } from 'styled-components'

import { DownChevronSVG, Typography } from '@ensdomains/thorin'

const Container = styled.div(
({ theme }) => css`
width: 100%;
border: 1px solid ${theme.colors.border};
border-radius: ${theme.radii.large};
`,
)

const Header = styled.button(
({ theme }) => css`
display: flex;
justify-content: space-between;
align-items: center;
padding: ${theme.space['4']};
width: 100%;
`,
)

const IconWrapper = styled.div<{ $open: boolean }>(
({ theme, $open }) => css`
display: flex;
color: ${theme.colors.grey};
transition: transform 0.3s ease-in-out, color 0.3s ease-in-out;
${$open &&
css`
transform: rotate(180deg);
color: ${theme.colors.text};
`}
`,
)

const Body = styled.div<{ $state: TransitionState; $height: number }>(
({ theme, $state, $height }) => css`
overflow: hidden;
width: 100%;
padding: 0 ${theme.space['4']};
transition: opacity 0.5s ease-in-out, height 0.5s ease-in-out;
box-sizing: border-box;
${$state === 'exited' &&
css`
visibility: hidden;
height: 0;
opacity: 0;
`}
${($state === 'preEnter' || $state === 'exiting') &&
css`
visibility: visible;
opacity: 0;
height: 0;
`}
${($state === 'entering' || $state === 'preExit') &&
css`
visibility: visible;
opacity: 1;
height: ${$height}px;
`}
${$state === 'entered' &&
css`
visibility: visible;
opacity: 1;
height: initial;
`}
`,
)

const Content = styled.div(
({ theme }) => css`
padding: ${theme.space['4']} 0;
border-top: 1px solid ${theme.colors.border};
`,
)

type Props = {
title: string
}

export const ExpandableSection = ({ title, children }: PropsWithChildren<Props>) => {
const ref = useRef<HTMLDivElement>(null)

const [height, setHeight] = useState(0)
const [state, toggle] = useTransition({
timeout: 300,
preEnter: true,
preExit: true,
onChange: ({ state: _state }) => {
if (_state === 'preEnter' || _state === 'preExit') {
const _heigth = ref.current?.getBoundingClientRect().height || 0
setHeight(_heigth)
}
},
})

const open = ['entered', 'entering', 'preEnter'].includes(state)

return (
<Container>
<Header type="button" onClick={() => toggle()}>
<Typography>{title}</Typography>
<IconWrapper $open={open}>
<DownChevronSVG />
</IconWrapper>
</Header>
<Body $state={state} $height={height}>
<Content ref={ref}>{children}</Content>
</Body>
</Container>
)
}
22 changes: 22 additions & 0 deletions src/components/@atoms/PseudoActionButton/PseudoActionButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentProps, useEffect, useState } from 'react'

import { Button } from '@ensdomains/thorin'

type Props = ComponentProps<typeof Button>

export const PseudoActionButton = ({ loading, onClick, ...props }: Props) => {
const [pseudoLoading, setPseudoLoading] = useState(false)
useEffect(() => {
if (pseudoLoading) setTimeout(() => setPseudoLoading(false), 5000)
}, [pseudoLoading, setPseudoLoading])
return (
<Button
{...props}
loading={loading || pseudoLoading}
onClick={(e) => {
setPseudoLoading(true)
onClick?.(e)
}}
/>
)
}
Loading

0 comments on commit 645b344

Please sign in to comment.