Skip to content

Commit

Permalink
fix: Actions on receive address is confusing (#2999)
Browse files Browse the repository at this point in the history
* fix: issue 305

* fix: add clearTimeout

* fix: AddressQrCodeWithCopyZone

* fix: CopyQrCode

---------

Co-authored-by: Chen Yu <[email protected]>
  • Loading branch information
devchenyan and Keith-CY authored Jan 10, 2024
1 parent 5f9f767 commit 8c0d834
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 112 deletions.
107 changes: 59 additions & 48 deletions packages/neuron-ui/src/components/Receive/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo, useCallback } from 'react'
import React, { useMemo, useCallback, useState, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useState as useGlobalState } from 'states'
import Dialog from 'widgets/Dialog'
Expand All @@ -7,50 +7,82 @@ import Button from 'widgets/Button'
import CopyZone from 'widgets/CopyZone'
import QRCode from 'widgets/QRCode'
import Tooltip from 'widgets/Tooltip'
import { AddressTransform, Download, Copy, Attention } from 'widgets/Icons/icon'
import { AddressTransform, Download, Copy, Attention, SuccessNoBorder } from 'widgets/Icons/icon'
import VerifyHardwareAddress from './VerifyHardwareAddress'
import styles from './receive.module.scss'
import { useCopyAndDownloadQrCode, useSwitchAddress } from './hooks'

type AddressTransformWithCopyZoneProps = {
showAddress: string
isInShortFormat: boolean
className?: string
onClick: () => void
}

export const AddressTransformWithCopyZone = ({
export const AddressQrCodeWithCopyZone = ({
showAddress,
isInShortFormat,
onClick,
className,
}: AddressTransformWithCopyZoneProps) => {
const [t] = useTranslation()
const transformLabel = t(
isInShortFormat ? 'receive.turn-into-full-version-format' : 'receive.turn-into-deprecated-format'
)

const [isCopySuccess, setIsCopySuccess] = useState(false)
const timer = useRef<ReturnType<typeof setTimeout>>()
const { ref, onCopyQrCode, onDownloadQrCode, showCopySuccess } = useCopyAndDownloadQrCode()

const stopPropagation = useCallback((e: React.SyntheticEvent) => {
e.stopPropagation()
}, [])
const onCopy = useCallback(() => {
onCopyQrCode()
setIsCopySuccess(true)

clearTimeout(timer.current!)
timer.current = setTimeout(() => {
setIsCopySuccess(false)
}, 1000)
}, [showAddress, setIsCopySuccess, timer])

return (
<div className={className}>
<CopyZone content={showAddress} className={styles.showAddress}>
{showAddress}
</CopyZone>
<button
type="button"
className={styles.addressToggle}
onClick={onClick}
title={transformLabel}
onFocus={stopPropagation}
onMouseOver={stopPropagation}
onMouseUp={stopPropagation}
>
<AddressTransform />
{transformLabel}
</button>
<div className={styles.addressRoot}>
<div className={styles.qrCode} data-copy-success-text={t('common.copied')}>
<QRCode value={showAddress} size={128} includeMargin ref={ref} />
<div className={styles.actions}>
<Button type="text" className={styles.actionBtn} onClick={onDownloadQrCode}>
<Download />
</Button>
{isCopySuccess ? (
<Button type="text">
<SuccessNoBorder />
</Button>
) : (
<Button type="text" className={styles.actionBtn} onClick={onCopy}>
<Copy />
</Button>
)}
</div>
{showCopySuccess && <Toast content={t('common.copied')} />}
</div>

<div className={styles.copyAddress}>
<CopyZone content={showAddress} className={styles.showAddress}>
{showAddress}
</CopyZone>
<button
type="button"
className={styles.addressToggle}
onClick={onClick}
title={transformLabel}
onFocus={stopPropagation}
onMouseOver={stopPropagation}
onMouseUp={stopPropagation}
>
<AddressTransform />
{transformLabel}
</button>
</div>
</div>
)
}
Expand All @@ -73,7 +105,6 @@ const Receive = ({ onClose, address }: { onClose?: () => void; address?: string
}

const { isInShortFormat, setIsInShortFormat, address: showAddress } = useSwitchAddress(accountAddress)
const { ref, onCopyQrCode, onDownloadQrCode, showCopySuccess } = useCopyAndDownloadQrCode()

return (
<Dialog
Expand All @@ -90,35 +121,15 @@ const Receive = ({ onClose, address }: { onClose?: () => void; address?: string
showFooter={false}
className={styles.dialog}
>
<div className={styles.addressRoot}>
<div className={styles.qrCode} data-copy-success-text={t('common.copied')}>
<QRCode value={showAddress} size={128} includeMargin ref={ref} />
</div>

<div className={styles.actions}>
<Button type="text" onClick={onDownloadQrCode}>
<Tooltip tip={t('receive.save-qr-code')} placement="top">
<Download />
</Tooltip>
</Button>
<Button type="text" onClick={onCopyQrCode}>
<Tooltip tip={t('receive.copy-address')} placement="top">
<Copy />
</Tooltip>
</Button>
</div>
<div className={styles.copyAddress}>
<AddressTransformWithCopyZone
showAddress={showAddress}
isInShortFormat={isInShortFormat}
onClick={() => setIsInShortFormat(is => !is)}
/>
</div>
<div>
<AddressQrCodeWithCopyZone
showAddress={showAddress}
isInShortFormat={isInShortFormat}
onClick={() => setIsInShortFormat(is => !is)}
/>

{isSingleAddress && <VerifyHardwareAddress address={accountAddress} wallet={wallet} onClose={onClose} />}
</div>

{showCopySuccess && <Toast content={t('common.copied')} />}
</Dialog>
)
}
Expand Down
36 changes: 27 additions & 9 deletions packages/neuron-ui/src/components/Receive/receive.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,41 @@
margin: 4px 0;

.actions {
position: absolute;
width: 128px;
height: 128px;
top: 0;
left: 46px;
display: flex;
justify-content: center;
gap: 16px;
margin-top: 8px;
align-items: center;
gap: 24px;
&:hover {
background: rgba(0, 0, 0, 0.5);
& > button {
display: flex;
align-items: center;
justify-content: center;
}
}
& > button {
display: none;
min-width: 0;
width: 24px;
height: 24px;
border-radius: 50%;
color: var(--primary-color);
background: var(--tag-green-bg-color);
& {
svg {
width: 12px;
g,
path {
fill: var(--primary-color);
}
svg {
width: 12px;
}
}

.actionBtn {
svg {
g,
path {
fill: var(--primary-color);
}
}
}
Expand Down Expand Up @@ -94,6 +111,7 @@

.copyAddress {
width: 424px;
margin-top: 16px;
}

.showAddress {
Expand Down
45 changes: 8 additions & 37 deletions packages/neuron-ui/src/components/SUDTReceiveDialog/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import React, { useCallback, useRef, useState } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { addressToScript, bech32Address, AddressPrefix } from '@nervosnetwork/ckb-sdk-utils'
import SUDTAvatar from 'widgets/SUDTAvatar'
import { AddressTransformWithCopyZone } from 'components/Receive'
import QRCode, { copyCanvas, downloadCanvas } from 'widgets/QRCode'
import { AddressQrCodeWithCopyZone } from 'components/Receive'
import Dialog from 'widgets/Dialog'
import Button from 'widgets/Button'
import Alert from 'widgets/Alert'

import { CONSTANTS } from 'utils'
Expand Down Expand Up @@ -37,24 +35,6 @@ const SUDTReceiveDialog = ({ data, onClose }: { data: DataProps; onClose?: () =>
const [t] = useTranslation()
const [isInShortFormat, setIsInShortFormat] = useState(false)
const { address, accountName, tokenName, symbol } = data
const ref = useRef<HTMLDivElement | null>(null)
const onDownloadQrCode = useCallback(() => {
const canvasElement = ref.current?.querySelector('canvas')
if (canvasElement) {
downloadCanvas(canvasElement)
}
}, [ref])
const [showCopySuccess, setShowCopySuccess] = useState(false)
const onCopyQrCode = useCallback(() => {
setShowCopySuccess(false)
const canvasElement = ref.current?.querySelector('canvas')
if (canvasElement) {
copyCanvas(canvasElement)
setTimeout(() => {
setShowCopySuccess(true)
}, 1)
}
}, [ref])

const displayedAddr = isInShortFormat ? toShortAddr(address) : address

Expand Down Expand Up @@ -82,21 +62,12 @@ const SUDTReceiveDialog = ({ data, onClose }: { data: DataProps; onClose?: () =>
</div>
</div>
</div>
<div className={styles.qrCode} data-copy-success={showCopySuccess} data-copy-success-text={t('common.copied')}>
<QRCode value={displayedAddr} size={128} includeMargin ref={ref} />
</div>
<div className={styles.copyContainer}>
<AddressTransformWithCopyZone
className={styles.copyTransformWrapper}
showAddress={displayedAddr}
isInShortFormat={isInShortFormat}
onClick={() => setIsInShortFormat(is => !is)}
/>
</div>
<div className={styles.actions}>
<Button type="default" label={t('receive.copy-qr-code')} onClick={onCopyQrCode} />
<Button type="confirm" label={t('receive.save-qr-code')} onClick={onDownloadQrCode} />
</div>

<AddressQrCodeWithCopyZone
showAddress={displayedAddr}
isInShortFormat={isInShortFormat}
onClick={() => setIsInShortFormat(is => !is)}
/>
</div>
</Dialog>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

.container {
width: 680px;
padding-bottom: 24px;
}

.info {
Expand Down Expand Up @@ -75,18 +76,6 @@
}
}

.copyContainer {
text-align: center;
display: flex;
width: 100%;
justify-content: center;
margin-top: 16px;

.copyTransformWrapper {
width: 452px;
}
}

.qrCode {
position: relative;
@keyframes fade-away {
Expand Down Expand Up @@ -125,9 +114,3 @@
}
}
}

.actions {
margin: 16px 0 24px;
@include dialog-footer;
column-gap: 24px;
}

2 comments on commit 8c0d834

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

Packaging for test is done in 7469686608

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

Packaging for test is done in 7469685931

Please sign in to comment.