Skip to content
Merged
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
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;
}