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 (
)} 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)