mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-26 13:17:15 -05:00
60 lines
1.6 KiB
TypeScript
60 lines
1.6 KiB
TypeScript
import * as React from "react";
|
|
|
|
const COPY_SUCCESS_DURATION_MS = 2000;
|
|
|
|
/** `copySuccess` stays `true` for a short while after a copy so a confirmation can be flashed; `reset` clears it. */
|
|
export function useCopyToClipboard(): {
|
|
copyToClipboard: (value: string) => void;
|
|
copySuccess: boolean;
|
|
reset: () => void;
|
|
} {
|
|
const { copySuccess, flashCopySuccess, reset } = useCopySuccessFlash();
|
|
|
|
const copyToClipboard = (value: string) => {
|
|
if (!value) return;
|
|
|
|
navigator.clipboard.writeText(value).then(flashCopySuccess, () => {});
|
|
};
|
|
|
|
return { copyToClipboard, copySuccess, reset };
|
|
}
|
|
|
|
/** Like {@link useCopyToClipboard} for a png. Takes a promise since Safari only allows the write during the click that started it. */
|
|
export function useCopyPngToClipboard(): {
|
|
copyPngToClipboard: (png: Promise<Blob>) => Promise<void>;
|
|
copySuccess: boolean;
|
|
} {
|
|
const { copySuccess, flashCopySuccess } = useCopySuccessFlash();
|
|
|
|
const copyPngToClipboard = async (png: Promise<Blob>) => {
|
|
try {
|
|
await navigator.clipboard.write([
|
|
new ClipboardItem({ "image/png": png }),
|
|
]);
|
|
flashCopySuccess();
|
|
} catch {}
|
|
};
|
|
|
|
return { copyPngToClipboard, copySuccess };
|
|
}
|
|
|
|
function useCopySuccessFlash() {
|
|
const [copySuccess, setCopySuccess] = React.useState(false);
|
|
|
|
React.useEffect(() => {
|
|
if (!copySuccess) return;
|
|
|
|
const timeout = setTimeout(
|
|
() => setCopySuccess(false),
|
|
COPY_SUCCESS_DURATION_MS,
|
|
);
|
|
return () => clearTimeout(timeout);
|
|
}, [copySuccess]);
|
|
|
|
return {
|
|
copySuccess,
|
|
flashCopySuccess: () => setCopySuccess(true),
|
|
reset: () => setCopySuccess(false),
|
|
};
|
|
}
|