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

feat: desaturate & opacity for unapproved tokens #52

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
4 changes: 3 additions & 1 deletion src/components/TokenImg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function TokenImg({ token, ...rest }: TokenImgProps) {
return <img src={src} alt={alt} key={alt} onError={onError} {...rest} />
}

export default styled(TokenImg)<{ size?: number }>`
export default styled(TokenImg)<{ size?: number; unapproved?: boolean }>`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call this approved do the name doesn't include a boolean modifier

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chose to use unapproved so that the default tokenImg isn't unapproved and shows in full saturation; you'd have to explicitly set a tokenImg as unapproved

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm reading the code correctly, it looks like approvalState is this enum:

export enum ApprovalState {
  UNKNOWN = 'UNKNOWN',
  NOT_APPROVED = 'NOT_APPROVED',
  PENDING = 'PENDING',
  APPROVED = 'APPROVED',
}

Would you not get the desired behavior if you just pass down approval state to the style, then make the decision about saturation there?

like:

   ${({ approvalState }) => approvalState === ApprovalState.NOT_APPROVED && 'filter: grayscale(100%) opacity(60%)'}

// radial-gradient calculates distance from the corner, not the edge: divide by sqrt(2)
background: radial-gradient(
${({ theme }) => theme.module} calc(100% / ${Math.sqrt(2)} - 1.5px),
Expand All @@ -52,4 +52,6 @@ export default styled(TokenImg)<{ size?: number }>`
border-radius: 100%;
height: ${({ size }) => size || 1}em;
width: ${({ size }) => size || 1}em;

${({ unapproved }) => unapproved && 'filter: grayscale(100%) opacity(60%)'}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use 'saturate(0) opacity(0.4)' instead (I may have the opacity value wrong, but this is what is already in the code). Desaturation is the stated goal, so saturate is more semantic than grayscale.

`
5 changes: 3 additions & 2 deletions src/components/TokenSelect/TokenButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ interface TokenButtonProps {
value?: Currency
collapsed: boolean
disabled?: boolean
isUnapprovedToken?: boolean
onClick: () => void
}

export default function TokenButton({ value, collapsed, disabled, onClick }: TokenButtonProps) {
export default function TokenButton({ value, collapsed, disabled, isUnapprovedToken, onClick }: TokenButtonProps) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same - use approved: boolean or approval: ApprovalState.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whatever you use here should be passed directly to TokenImg.

const buttonBackgroundColor = useMemo(() => (value ? 'interactive' : 'accent'), [value])
const contentColor = useMemo(() => (value || disabled ? 'onInteractive' : 'onAccent'), [value, disabled])

Expand Down Expand Up @@ -85,7 +86,7 @@ export default function TokenButton({ value, collapsed, disabled, onClick }: Tok
>
{value ? (
<>
<TokenImg token={value} size={1.2} />
<TokenImg token={value} size={1.2} unapproved={isUnapprovedToken} />
{value.symbol}
</>
) : (
Expand Down
22 changes: 21 additions & 1 deletion src/components/TokenSelect/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { t, Trans } from '@lingui/macro'
import { Currency } from '@uniswap/sdk-core'
import { useIsPendingApproval } from 'components/Swap/SwapButton/useApprovalData'
import { useSwapInfo } from 'hooks/swap'
import { ApproveOrPermitState, useApproveOrPermit } from 'hooks/swap/useSwapApproval'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useCurrencyBalances } from 'hooks/useCurrencyBalance'
import useNativeCurrency from 'hooks/useNativeCurrency'
import useTokenList, { useIsTokenListLoaded, useQueryTokens } from 'hooks/useTokenList'
import { ElementRef, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Field } from 'state/swap'
import styled from 'styled-components/macro'
import { ThemedText } from 'theme'

Expand Down Expand Up @@ -137,9 +141,25 @@ export default memo(function TokenSelect({ value, collapsed, disabled, onSelect
},
[onSelect, setOpen]
)

const {
[Field.INPUT]: { currency, amount: amountIn },
trade,
slippage,
} = useSwapInfo()
const isInputToken = value && currency?.equals(value)
const { approvalState } = useApproveOrPermit(trade.trade, slippage.allowed, useIsPendingApproval, amountIn)
const isUnapprovedToken = isInputToken && approvalState !== ApproveOrPermitState.APPROVED

return (
<>
<TokenButton value={value} collapsed={collapsed} disabled={disabled} onClick={onOpen} />
<TokenButton
value={value}
collapsed={collapsed}
disabled={disabled}
isUnapprovedToken={isUnapprovedToken}
onClick={onOpen}
/>
{open && <TokenSelectDialog value={value} onSelect={selectAndClose} onClose={() => setOpen(false)} />}
</>
)
Expand Down