fix: address copy button on http sites (#165)

* fix: receive address copy button not working

* fix: handle new addresses and mobile devices

this also re-adds the previous functionality and uses document.execCommand as a fallback
This commit is contained in:
neb_b 2022-03-09 11:58:49 -05:00 committed by GitHub
parent 13f0ac3803
commit 34f8d2dc2b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,5 +1,5 @@
import React from 'react'
import { useState, useEffect } from 'react'
import { useState, useEffect, useRef } from 'react'
import { BitcoinQR } from './BitcoinQR'
import { useLocation } from 'react-router-dom'
import * as rb from 'react-bootstrap'
@ -12,6 +12,7 @@ import Sprite from './Sprite'
export default function Receive({ currentWallet }) {
const location = useLocation()
const settings = useSettings()
const addressCopyFallbackInputRef = useRef()
const [validated, setValidated] = useState(false)
const [alert, setAlert] = useState(null)
const [isLoading, setIsLoading] = useState(false)
@ -57,6 +58,24 @@ export default function Receive({ currentWallet }) {
return () => clearTimeout(timer)
}, [addressCopiedFlag])
const copyToClipboard = (text, fallbackInputField) => {
const copyToClipboardFallback = (inputField) =>
new Promise((resolve, reject) => {
inputField.select()
const success = document.execCommand && document.execCommand('copy')
inputField.blur()
success ? resolve(success) : reject(new Error('Could not copy address.'))
})
// `navigator.clipboard` might not be available, e.g. on sites served over plain `http`.
if (!navigator.clipboard) {
return copyToClipboardFallback(fallbackInputField)
}
// might not work on iOS.
return navigator.clipboard.writeText(text).catch(() => copyToClipboardFallback(fallbackInputField))
}
const onSubmit = (e) => {
e.preventDefault()
@ -87,13 +106,12 @@ export default function Receive({ currentWallet }) {
data-bs-toggle="tooltip"
data-bs-placement="left"
onClick={() => {
// might not work on iOS.
navigator.clipboard.writeText(address).then(
copyToClipboard(address, addressCopyFallbackInputRef.current).then(
() => {
setAddressCopiedFlag(addressCopiedFlag + 1)
},
() => {
setAlert({ variant: 'warning', message: 'Could not copy address.' })
(e) => {
setAlert({ variant: 'warning', message: e.message })
}
)
}}
@ -107,6 +125,18 @@ export default function Receive({ currentWallet }) {
'Copy'
)}
</rb.Button>
<input
readOnly
aria-hidden
ref={addressCopyFallbackInputRef}
value={address}
style={{
position: 'absolute',
left: '-9999px',
top: '-9999px',
}}
/>
</div>
</rb.Card.Body>
</rb.Card>