mirror of
https://github.com/luxfhe/example-poker.git
synced 2026-10-30 18:13:22 +00:00
137 lines
4.0 KiB
TypeScript
137 lines
4.0 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import Link from "next/link";
|
|
import { CopyToClipboard } from "react-copy-to-clipboard";
|
|
import { Address as AddressType, getAddress, isAddress } from "viem";
|
|
import { hardhat } from "viem/chains";
|
|
import { useEnsAvatar, useEnsName } from "wagmi";
|
|
import { CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline";
|
|
import { BlockieAvatar } from "~~/components/scaffold-eth";
|
|
import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
|
|
import { getBlockExplorerAddressLink } from "~~/utils/scaffold-eth";
|
|
|
|
type AddressProps = {
|
|
address?: AddressType;
|
|
disableAddressLink?: boolean;
|
|
format?: "short" | "long";
|
|
size?: "xs" | "sm" | "base" | "lg" | "xl" | "2xl" | "3xl";
|
|
};
|
|
|
|
const blockieSizeMap = {
|
|
xs: 6,
|
|
sm: 7,
|
|
base: 8,
|
|
lg: 9,
|
|
xl: 10,
|
|
"2xl": 12,
|
|
"3xl": 15,
|
|
};
|
|
|
|
/**
|
|
* Displays an address (or ENS) with a Blockie image and option to copy address.
|
|
*/
|
|
export const Address = ({ address, disableAddressLink, format, size = "base" }: AddressProps) => {
|
|
const [ens, setEns] = useState<string | null>();
|
|
const [ensAvatar, setEnsAvatar] = useState<string | null>();
|
|
const [addressCopied, setAddressCopied] = useState(false);
|
|
const checkSumAddress = address ? getAddress(address) : undefined;
|
|
|
|
const { targetNetwork } = useTargetNetwork();
|
|
|
|
const { data: fetchedEns } = useEnsName({
|
|
address: checkSumAddress,
|
|
enabled: isAddress(checkSumAddress ?? ""),
|
|
chainId: 1,
|
|
});
|
|
const { data: fetchedEnsAvatar } = useEnsAvatar({
|
|
name: fetchedEns,
|
|
enabled: Boolean(fetchedEns),
|
|
chainId: 1,
|
|
cacheTime: 30_000,
|
|
});
|
|
|
|
// We need to apply this pattern to avoid Hydration errors.
|
|
useEffect(() => {
|
|
setEns(fetchedEns);
|
|
}, [fetchedEns]);
|
|
|
|
useEffect(() => {
|
|
setEnsAvatar(fetchedEnsAvatar);
|
|
}, [fetchedEnsAvatar]);
|
|
|
|
// Skeleton UI
|
|
if (!checkSumAddress) {
|
|
return (
|
|
<div className="animate-pulse flex space-x-4">
|
|
<div className="rounded-md bg-slate-300 h-6 w-6"></div>
|
|
<div className="flex items-center space-y-6">
|
|
<div className="h-2 w-28 bg-slate-300 rounded"></div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!isAddress(checkSumAddress)) {
|
|
return <span className="text-error">Wrong address</span>;
|
|
}
|
|
|
|
const blockExplorerAddressLink = getBlockExplorerAddressLink(targetNetwork, checkSumAddress);
|
|
let displayAddress = checkSumAddress?.slice(0, 6) + "..." + checkSumAddress?.slice(-4);
|
|
|
|
if (ens) {
|
|
displayAddress = ens;
|
|
} else if (format === "long") {
|
|
displayAddress = checkSumAddress;
|
|
}
|
|
|
|
return (
|
|
<div className="flex items-center">
|
|
<div className="flex-shrink-0">
|
|
<BlockieAvatar
|
|
address={checkSumAddress}
|
|
ensImage={ensAvatar}
|
|
size={(blockieSizeMap[size] * 24) / blockieSizeMap["base"]}
|
|
/>
|
|
</div>
|
|
{disableAddressLink ? (
|
|
<span className={`ml-1.5 text-${size} font-normal`}>{displayAddress}</span>
|
|
) : targetNetwork.id === hardhat.id ? (
|
|
<span className={`ml-1.5 text-${size} font-normal`}>
|
|
<Link href={blockExplorerAddressLink}>{displayAddress}</Link>
|
|
</span>
|
|
) : (
|
|
<a
|
|
className={`ml-1.5 text-${size} font-normal`}
|
|
target="_blank"
|
|
href={blockExplorerAddressLink}
|
|
rel="noopener noreferrer"
|
|
>
|
|
{displayAddress}
|
|
</a>
|
|
)}
|
|
{addressCopied ? (
|
|
<CheckCircleIcon
|
|
className="ml-1.5 text-xl font-normal text-sky-600 h-5 w-5 cursor-pointer"
|
|
aria-hidden="true"
|
|
/>
|
|
) : (
|
|
<CopyToClipboard
|
|
text={checkSumAddress}
|
|
onCopy={() => {
|
|
setAddressCopied(true);
|
|
setTimeout(() => {
|
|
setAddressCopied(false);
|
|
}, 800);
|
|
}}
|
|
>
|
|
<DocumentDuplicateIcon
|
|
className="ml-1.5 text-xl font-normal text-sky-600 h-5 w-5 cursor-pointer"
|
|
aria-hidden="true"
|
|
/>
|
|
</CopyToClipboard>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|