diff --git a/package-lock.json b/package-lock.json
index 9d883a303..964c55366 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,6 +18,7 @@
"autoprefixer": "^10.4.4",
"chart.js": "^3.8.2",
"classnames": "^2.3.2",
+ "clipboard-copy": "^4.0.1",
"core-js": "^3.21.1",
"decentraland-gatsby": "^5.67.2",
"decentraland-ui": "^3.102.0",
diff --git a/package.json b/package.json
index 698b1ff6a..8f2be9615 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,7 @@
"autoprefixer": "^10.4.4",
"chart.js": "^3.8.2",
"classnames": "^2.3.2",
+ "clipboard-copy": "^4.0.1",
"core-js": "^3.21.1",
"decentraland-gatsby": "^5.67.2",
"decentraland-ui": "^3.102.0",
diff --git a/src/components/Error/ErrorMessage.tsx b/src/components/Error/ErrorMessage.tsx
index 8524a0b76..4c6825b38 100644
--- a/src/components/Error/ErrorMessage.tsx
+++ b/src/components/Error/ErrorMessage.tsx
@@ -1,10 +1,10 @@
-import React, { useCallback, useState } from 'react'
+import React, { useState } from 'react'
import classNames from 'classnames'
import Markdown from 'decentraland-gatsby/dist/components/Text/Markdown'
-import useClipboardCopy from 'decentraland-gatsby/dist/hooks/useClipboardCopy'
import { Button } from 'decentraland-ui/dist/components/Button/Button'
+import useClipboardCopy from '../../hooks/useClipboardCopy'
import useFormatMessage from '../../hooks/useFormatMessage'
import Time from '../../utils/date/Time'
import Link from '../Common/Link'
@@ -19,17 +19,13 @@ interface Props {
export default function ErrorMessage({ label, errorMessage }: Props) {
const t = useFormatMessage()
- const [copied, state] = useClipboardCopy(Time.Second)
+ const { copiedValue, handleCopy } = useClipboardCopy(Time.Second)
const [open, setOpen] = useState(false)
const toggleHandler = () => {
setOpen(!open)
}
- const handleCopy = useCallback(() => {
- state.copy(errorMessage)
- }, [errorMessage, state])
-
return (
@@ -42,8 +38,13 @@ export default function ErrorMessage({ label, errorMessage }: Props) {
{errorMessage}
-
{t('error.message.call_for_action')}
diff --git a/src/components/Modal/SuccessModal.tsx b/src/components/Modal/SuccessModal.tsx
index a1835849d..cd9ce1068 100644
--- a/src/components/Modal/SuccessModal.tsx
+++ b/src/components/Modal/SuccessModal.tsx
@@ -1,19 +1,18 @@
import React, { useCallback } from 'react'
import classNames from 'classnames'
-import useClipboardCopy from 'decentraland-gatsby/dist/hooks/useClipboardCopy'
import { Button } from 'decentraland-ui/dist/components/Button/Button'
import { Close } from 'decentraland-ui/dist/components/Close/Close'
import { Header } from 'decentraland-ui/dist/components/Header/Header'
import { Modal, ModalProps } from 'decentraland-ui/dist/components/Modal/Modal'
import { JOIN_DISCORD_URL } from '../../entities/Proposal/utils'
+import useClipboardCopy from '../../hooks/useClipboardCopy'
import useFormatMessage from '../../hooks/useFormatMessage'
import Time from '../../utils/date/Time'
import Text from '../Common/Text/Text'
import './ProposalModal.css'
-import './SuccessModal.css'
export type SuccessModalProps = Omit
& {
onDismiss: (e: React.MouseEvent) => void
@@ -33,12 +32,12 @@ export function SuccessModal({
...props
}: SuccessModalProps) {
const t = useFormatMessage()
- const [copied, state] = useClipboardCopy(Time.Second)
- const handleCopy = useCallback(() => {
+ const { copiedValue, handleCopy } = useClipboardCopy(Time.Second)
+ const handleCopyClick = useCallback(() => {
if (linkToCopy) {
- state.copy(linkToCopy)
+ handleCopy(linkToCopy)
}
- }, [linkToCopy, state])
+ }, [linkToCopy, handleCopy])
return (
- {copied ? t('modal.success.link_copied_label') : t('modal.success.copy_link_label')}
+ {copiedValue ? t('modal.success.link_copied_label') : t('modal.success.copy_link_label')}
)}
diff --git a/src/hooks/useClipboardCopy.ts b/src/hooks/useClipboardCopy.ts
new file mode 100644
index 000000000..a4db0b881
--- /dev/null
+++ b/src/hooks/useClipboardCopy.ts
@@ -0,0 +1,34 @@
+import { useCallback, useEffect, useState } from 'react'
+
+import clipboardCopy from 'clipboard-copy'
+
+export default function useClipboardCopy(timeout?: number) {
+ const [copiedValue, setCopiedValue] = useState
(null)
+
+ const handleCopy = useCallback((value: unknown) => {
+ const copiedValue = String(value ?? '')
+ clipboardCopy(copiedValue)
+ setCopiedValue(copiedValue)
+ }, [])
+
+ const clear = useCallback(() => setCopiedValue(null), [])
+
+ useEffect(() => {
+ let copyTimeout: null | ReturnType = null
+ if (copiedValue && timeout && timeout > 0) {
+ copyTimeout = setTimeout(() => clear(), timeout)
+ }
+
+ return () => {
+ if (copyTimeout) {
+ clearTimeout(copyTimeout)
+ }
+ }
+ }, [clear, copiedValue, timeout])
+
+ return {
+ copiedValue,
+ handleCopy,
+ clear,
+ }
+}
diff --git a/src/hooks/useForumConnect.ts b/src/hooks/useForumConnect.ts
index 44fa040aa..1acc68fc6 100644
--- a/src/hooks/useForumConnect.ts
+++ b/src/hooks/useForumConnect.ts
@@ -2,7 +2,6 @@ import { useCallback, useEffect, useState } from 'react'
import useAuthContext from 'decentraland-gatsby/dist/context/Auth/useAuthContext'
import useTrackContext from 'decentraland-gatsby/dist/context/Track/useTrackContext'
-import useClipboardCopy from 'decentraland-gatsby/dist/hooks/useClipboardCopy'
import useSign from 'decentraland-gatsby/dist/hooks/useSign'
import { Governance } from '../clients/Governance'
@@ -13,6 +12,7 @@ import { DISCOURSE_API } from '../entities/User/utils'
import { openUrl } from '../helpers'
import Time from '../utils/date/Time'
+import useClipboardCopy from './useClipboardCopy'
import useTimer from './useTimer'
export const THREAD_URL = `${DISCOURSE_API}${
@@ -25,7 +25,7 @@ export default function useForumConnect() {
const [user, userState] = useAuthContext()
const track = useTrackContext()
const [sign, signState] = useSign(user, userState.provider)
- const [copied, clipboardState] = useClipboardCopy(Time.Second)
+ const { handleCopy } = useClipboardCopy(Time.Second)
const [signatureResolution, setSignatureResolution] = useState<{
resolve: (value: unknown) => void
reject: (reason?: unknown) => void
@@ -80,9 +80,9 @@ export default function useForumConnect() {
const copyMessageToClipboard = useCallback(() => {
const { message, signature } = sign
if (message && signature) {
- clipboardState.copy(`${message}\nSignature: ${signature}`)
+ handleCopy(`${message}\nSignature: ${signature}`)
}
- }, [clipboardState, sign])
+ }, [handleCopy, sign])
const openThread = () => {
openUrl(THREAD_URL)