Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix NFT sizes and add docs #130

Merged
merged 2 commits into from
Dec 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eighty-icons-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@web3-ui/components': minor
---

Fix NFT sizes
4 changes: 4 additions & 0 deletions packages/components/src/components/NFT/NFT.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ export const Audio = () => (
<NFT contractAddress='0x0eede4764cfdfcd5dac0e00b3b7f4778c0cc994e' tokenId='1' />
);

export const Big = () => (
<NFT contractAddress='0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D' tokenId='1' size='lg' />
);

export const Error = () => <NFT contractAddress='abcd' tokenId='1' />;
38 changes: 28 additions & 10 deletions packages/components/src/components/NFT/NFT.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,18 @@ import {
import fetch from 'cross-fetch';

export interface NFTProps {
/**
* The address of the NFT contract.
*/
contractAddress: string;
/**
* The id of the NFT.
*/
tokenId: string;
/**
* The size of the NFT card.
*/
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
}

export interface NFTData {
Expand All @@ -30,7 +40,7 @@ export interface NFTData {
/**
* Component to fetch and display NFT data
*/
export const NFT = ({ contractAddress, tokenId }: NFTProps) => {
export const NFT = ({ contractAddress, tokenId, size = 'xs' }: NFTProps) => {
const _isMounted = useRef(true);
const [nftData, setNftData] = React.useState<NFTData>();
const [errorMessage, setErrorMessage] = React.useState<string>();
Expand All @@ -54,8 +64,12 @@ export const NFT = ({ contractAddress, tokenId }: NFTProps) => {
animationUrl: data.animation_url,
});
}
} catch (error: any) {
setErrorMessage(error.message);
} catch (error) {
if (error instanceof Error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be good to create a helper for this as we're handling errors in quite a few places. What do you reckon? Can add a separate ticket for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. It seems like we're handling errors (and the typing of them) in a couple ways. I'll make an issue to figure out the best way to handle errors in our code, and use whatever helper function i make across the codebase

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maximebonhomme feel free to create that ticket. Good suggestion

setErrorMessage(error.message);
} else {
setErrorMessage('An unknown error occurred');
}
}
}, [contractAddress, tokenId]);

Expand All @@ -67,7 +81,7 @@ export const NFT = ({ contractAddress, tokenId }: NFTProps) => {
};
}, [contractAddress, tokenId]);

return <NFTCard data={nftData} errorMessage={errorMessage} />;
return <NFTCard data={nftData} errorMessage={errorMessage} size={size} />;
};

/**
Expand All @@ -76,9 +90,11 @@ export const NFT = ({ contractAddress, tokenId }: NFTProps) => {
export const NFTCard = ({
data,
errorMessage = '',
size,
}: {
data: NFTData | undefined | null;
errorMessage?: string | undefined;
size: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
}) => {
const name = data?.name;
const imageUrl = data?.imageUrl;
Expand All @@ -98,23 +114,25 @@ export const NFTCard = ({
}

return (
<Skeleton isLoaded={!!data} maxW='xs' h='md'>
<Box maxW='xs' borderRadius='lg' borderWidth='1px' overflow='hidden'>
<Skeleton isLoaded={!!data} maxW={size} h='md'>
<Box maxW={size} borderRadius='lg' borderWidth='1px' overflow='hidden'>
{animationUrl ? (
animationUrl.endsWith('.mp3') ? (
<VStack>
<Image src={imageUrl} alt={displayName} borderRadius='lg' />
<Image src={imageUrl} alt={displayName} borderRadius='lg' w={size} />
<audio src={animationUrl} controls autoPlay muted style={{ borderRadius: '7px' }} />
</VStack>
) : (
<video src={animationUrl} controls autoPlay muted />
<Flex w={size} h={size} bg='black' justifyContent='center'>
<video src={animationUrl} controls autoPlay muted />
</Flex>
)
) : (
<Image src={imageUrl} alt={displayName} borderRadius='lg' />
<Image src={imageUrl} alt={displayName} borderRadius='lg' w={size} />
)}
<Box p='6'>
<Flex alignItems='center' justifyContent='space-between' pb='2'>
<Heading as='h3' size='sm'>
<Heading as='h3' size='sm' style={{ overflowWrap: 'anywhere' }}>
{displayName}
</Heading>
{assetContractSymbol && <Tag size='sm'>{assetContractSymbol}</Tag>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default {
};

export const nftsOwnedByAnAccount = () => (
<NFTGallery address='0x1A16c87927570239FECD343ad2654fD81682725e' />
<NFTGallery address='0x1A16c87927570239FECD343ad2654fD81682725e' gridWidth={2} />
);

export const nftsOwnedByAnENS = () => {
Expand Down
15 changes: 10 additions & 5 deletions packages/components/src/components/NFTGallery/NFTGallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ import { NFTCard } from '../NFT';

export interface NFTGalleryProps {
/**
* The owner of the NFTs
* The owner of the NFTs. Can be a wallet address, or an ENS name. If the address is an ENS
* name, then you must also provide the provider.
*/
address: string;
/**
* The number of columns in the grid
*/
gridWidth?: number;
/**
* A Web3Provider. Only needed if the address will be an ENS name.
*/
web3Provider?: ethers.providers.Web3Provider;
}

Expand Down Expand Up @@ -45,16 +49,16 @@ export const NFTGallery = ({ address, gridWidth = 4, web3Provider }: NFTGalleryP
resolvedAddress = await web3Provider.resolveName(address);
}
fetch(`https://api.opensea.io/api/v1/assets?owner=${resolvedAddress}`)
.then((res) => {
.then(res => {
if (!res.ok) {
throw Error(
`OpenSea request failed with status: ${res.status}. Make sure you are on mainnet.`
);
}
return res.json();
})
.then((data) => setNfts(data.assets))
.catch((err) => setErrorMessage(err.message));
.then(data => setNfts(data.assets))
.catch(err => setErrorMessage(err.message));
}
exec();
}, [address, web3Provider]);
Expand All @@ -69,7 +73,7 @@ export const NFTGallery = ({ address, gridWidth = 4, web3Provider }: NFTGalleryP
</Alert>
)}
<Grid templateColumns={`repeat(${gridWidth}, 1fr)`} gap={6}>
{nfts.map((nft) => (
{nfts.map(nft => (
<NFTCard
key={`${nft.asset_contract.symbol}-${nft.token_id}`}
data={{
Expand All @@ -79,6 +83,7 @@ export const NFTGallery = ({ address, gridWidth = 4, web3Provider }: NFTGalleryP
assetContractName: nft.asset_contract.name,
assetContractSymbol: nft.asset_contract.symbol,
}}
size='xs'
/>
))}
</Grid>
Expand Down