fix: nft asset sizing / aspect ratio bug (and make collection nfts fit in square too) (#5180)

* init wip

* init
This commit is contained in:
lynn 2022-11-14 22:10:38 -05:00 committed by GitHub
parent 72a8270084
commit ad84da10c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 150 deletions

@ -16,7 +16,7 @@ import {
import { body, bodySmall, buttonTextSmall, subhead, subheadSmall } from 'nft/css/common.css'
import { themeVars } from 'nft/css/sprinkles.css'
import { useIsMobile } from 'nft/hooks'
import { GenieAsset, Rarity, TokenType, UniformHeight, UniformHeights, WalletAsset } from 'nft/types'
import { GenieAsset, Rarity, TokenType, WalletAsset } from 'nft/types'
import { isAudio, isVideo } from 'nft/utils'
import { fallbackProvider, putCommas } from 'nft/utils'
import { floorFormatter } from 'nft/utils/numbers'
@ -230,19 +230,15 @@ const ImageContainer = ({ children }: { children: ReactNode }) => (
)
/* -------- CARD IMAGE -------- */
interface ImageProps {
uniformHeight?: UniformHeight
setUniformHeight?: (height: UniformHeight) => void
}
const Image = ({ uniformHeight, setUniformHeight }: ImageProps) => {
const Image = () => {
const { hovered, asset } = useCardContext()
const [noContent, setNoContent] = useState(!asset.smallImageUrl && !asset.imageUrl)
const [loaded, setLoaded] = useState(false)
const isMobile = useIsMobile()
if (noContent) {
return <NoContentContainer uniformHeight={uniformHeight ?? UniformHeights.unset} />
return <NoContentContainer />
}
return (
@ -251,7 +247,7 @@ const Image = ({ uniformHeight, setUniformHeight }: ImageProps) => {
as={'img'}
width="full"
style={{
aspectRatio: uniformHeight === UniformHeights.notUniform ? '1' : 'auto',
aspectRatio: '1',
transition: 'transform 0.4s ease 0s',
}}
src={asset.imageUrl || asset.smallImageUrl}
@ -259,15 +255,6 @@ const Image = ({ uniformHeight, setUniformHeight }: ImageProps) => {
draggable={false}
onError={() => setNoContent(true)}
onLoad={(e) => {
if (setUniformHeight) {
if (uniformHeight === UniformHeights.unset) {
setUniformHeight(e.currentTarget.clientHeight)
} else if (uniformHeight !== UniformHeights.notUniform && e.currentTarget.clientHeight !== uniformHeight) {
if (!uniformHeight || Math.abs(uniformHeight - e.currentTarget.clientHeight) > 1) {
setUniformHeight(UniformHeights.notUniform)
}
}
}
setLoaded(true)
}}
className={clsx(hovered && !isMobile && styles.cardImageHover, !loaded && styles.loadingBackground)}
@ -277,13 +264,11 @@ const Image = ({ uniformHeight, setUniformHeight }: ImageProps) => {
}
interface MediaProps {
uniformHeight?: UniformHeight
setUniformHeight?: (u: UniformHeight) => void
shouldPlay: boolean
setCurrentTokenPlayingMedia: (tokenId: string | undefined) => void
}
const Video = ({ uniformHeight, setUniformHeight, shouldPlay, setCurrentTokenPlayingMedia }: MediaProps) => {
const Video = ({ shouldPlay, setCurrentTokenPlayingMedia }: MediaProps) => {
const vidRef = useRef<HTMLVideoElement>(null)
const { hovered, asset } = useCardContext()
const [noContent, setNoContent] = useState(!asset.smallImageUrl && !asset.imageUrl)
@ -297,7 +282,7 @@ const Video = ({ uniformHeight, setUniformHeight, shouldPlay, setCurrentTokenPla
}
if (noContent) {
return <NoContentContainer uniformHeight={UniformHeights.notUniform} />
return <NoContentContainer />
}
return (
@ -317,10 +302,6 @@ const Video = ({ uniformHeight, setUniformHeight, shouldPlay, setCurrentTokenPla
draggable={false}
onError={() => setNoContent(true)}
onLoad={() => {
if (setUniformHeight && uniformHeight !== UniformHeights.notUniform) {
setUniformHeight(UniformHeights.notUniform)
}
setImageLoaded(true)
}}
visibility={shouldPlay ? 'hidden' : 'visible'}
@ -380,7 +361,7 @@ const Video = ({ uniformHeight, setUniformHeight, shouldPlay, setCurrentTokenPla
)
}
const Audio = ({ uniformHeight, setUniformHeight, shouldPlay, setCurrentTokenPlayingMedia }: MediaProps) => {
const Audio = ({ shouldPlay, setCurrentTokenPlayingMedia }: MediaProps) => {
const audRef = useRef<HTMLAudioElement>(null)
const { hovered, asset } = useCardContext()
const [noContent, setNoContent] = useState(!asset.smallImageUrl && !asset.imageUrl)
@ -394,7 +375,7 @@ const Audio = ({ uniformHeight, setUniformHeight, shouldPlay, setCurrentTokenPla
}
if (noContent) {
return <NoContentContainer uniformHeight={uniformHeight ?? UniformHeights.unset} />
return <NoContentContainer />
}
return (
@ -405,7 +386,7 @@ const Audio = ({ uniformHeight, setUniformHeight, shouldPlay, setCurrentTokenPla
alt={asset.name || asset.tokenId}
width="full"
style={{
aspectRatio: uniformHeight === UniformHeights.notUniform ? '1' : 'auto',
aspectRatio: '1',
transition: 'transform 0.4s ease 0s',
}}
src={asset.imageUrl || asset.smallImageUrl}
@ -413,18 +394,6 @@ const Audio = ({ uniformHeight, setUniformHeight, shouldPlay, setCurrentTokenPla
draggable={false}
onError={() => setNoContent(true)}
onLoad={(e) => {
if (setUniformHeight) {
if (uniformHeight === UniformHeights.unset) {
setUniformHeight(e.currentTarget.clientHeight)
} else if (
uniformHeight !== UniformHeights.notUniform &&
e.currentTarget.clientHeight !== uniformHeight
) {
if (!uniformHeight || Math.abs(uniformHeight - e.currentTarget.clientHeight) > 1) {
setUniformHeight(UniformHeights.notUniform)
}
}
}
setImageLoaded(true)
}}
className={clsx(hovered && !isMobile && styles.cardImageHover, !imageLoaded && styles.loadingBackground)}
@ -764,56 +733,31 @@ const Pool = () => {
)
}
interface NoContentContainerProps {
uniformHeight: UniformHeight
}
const NoContentContainer = ({ uniformHeight }: NoContentContainerProps) => (
const NoContentContainer = () => (
<>
{uniformHeight !== UniformHeights.unset && uniformHeight !== UniformHeights.notUniform ? (
<Box
position="relative"
width="full"
style={{
paddingTop: '100%',
background: `linear-gradient(90deg, ${themeVars.colors.backgroundSurface} 0%, ${themeVars.colors.backgroundInteractive} 95.83%)`,
}}
>
<Box
display="flex"
width="full"
style={{
height: `${uniformHeight as number}px`,
background: `linear-gradient(270deg, ${themeVars.colors.backgroundOutline} 0%, ${themeVars.colors.backgroundSurface} 100%)`,
}}
position="absolute"
textAlign="center"
left="1/2"
top="1/2"
style={{ transform: 'translate3d(-50%, -50%, 0)' }}
fontWeight="normal"
color="gray500"
className={body}
justifyContent="center"
alignItems="center"
textAlign="center"
>
Content not
<br />
available yet
</Box>
) : (
<Box
position="relative"
width="full"
style={{
paddingTop: '100%',
background: `linear-gradient(90deg, ${themeVars.colors.backgroundSurface} 0%, ${themeVars.colors.backgroundInteractive} 95.83%)`,
}}
>
<Box
position="absolute"
textAlign="center"
left="1/2"
top="1/2"
style={{ transform: 'translate3d(-50%, -50%, 0)' }}
fontWeight="normal"
color="gray500"
className={body}
>
Content not
<br />
available yet
</Box>
</Box>
)}
</Box>
</>
)

@ -1,7 +1,7 @@
import { sendAnalyticsEvent, useTrace } from '@uniswap/analytics'
import { EventName, PageName } from '@uniswap/analytics-events'
import { useBag } from 'nft/hooks'
import { GenieAsset, Markets, UniformHeight } from 'nft/types'
import { GenieAsset, Markets } from 'nft/types'
import { formatWeiToDecimal, rarityProviderLogo } from 'nft/utils'
import { useCallback, useMemo } from 'react'
@ -12,8 +12,6 @@ import * as Card from './Card'
interface CollectionAssetProps {
asset: GenieAsset
isMobile: boolean
uniformHeight: UniformHeight
setUniformHeight: (u: UniformHeight) => void
mediaShouldBePlaying: boolean
setCurrentTokenPlayingMedia: (tokenId: string | undefined) => void
rarityVerified?: boolean
@ -22,8 +20,6 @@ interface CollectionAssetProps {
export const CollectionAsset = ({
asset,
isMobile,
uniformHeight,
setUniformHeight,
mediaShouldBePlaying,
setCurrentTokenPlayingMedia,
rarityVerified,
@ -94,21 +90,11 @@ export const CollectionAsset = ({
/>
)}
{assetMediaType === AssetMediaType.Image ? (
<Card.Image uniformHeight={uniformHeight} setUniformHeight={setUniformHeight} />
<Card.Image />
) : assetMediaType === AssetMediaType.Video ? (
<Card.Video
uniformHeight={uniformHeight}
setUniformHeight={setUniformHeight}
shouldPlay={mediaShouldBePlaying}
setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia}
/>
<Card.Video shouldPlay={mediaShouldBePlaying} setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia} />
) : (
<Card.Audio
uniformHeight={uniformHeight}
setUniformHeight={setUniformHeight}
shouldPlay={mediaShouldBePlaying}
setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia}
/>
<Card.Audio shouldPlay={mediaShouldBePlaying} setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia} />
)}
</Card.ImageContainer>
<Card.DetailsContainer>

@ -34,7 +34,7 @@ import {
} from 'nft/hooks'
import { useIsCollectionLoading } from 'nft/hooks/useIsCollectionLoading'
import { usePriceRange } from 'nft/hooks/usePriceRange'
import { DropDownOption, GenieCollection, Markets, TokenType, UniformHeight, UniformHeights } from 'nft/types'
import { DropDownOption, GenieCollection, Markets, TokenType } from 'nft/types'
import { getRarityStatus } from 'nft/utils/asset'
import { pluralize } from 'nft/utils/roundAndPluralize'
import { scrollToTop } from 'nft/utils/scrollToTop'
@ -159,10 +159,10 @@ const MarketNameWrapper = styled(Row)`
gap: 8px;
`
const loadingAssets = (height?: number) => (
const loadingAssets = () => (
<>
{Array.from(Array(ASSET_PAGE_SIZE), (_, index) => (
<CollectionAssetLoading key={index} height={height} />
<CollectionAssetLoading key={index} />
))}
</>
)
@ -287,7 +287,6 @@ export const CollectionNfts = ({ contractAddress, collectionStats, rarityVerifie
const { assets: collectionNfts, loadNext, hasNext, isLoadingNext } = useLazyLoadAssetsQuery(assetQueryParams)
const [uniformHeight, setUniformHeight] = useState<UniformHeight>(UniformHeights.unset)
const [currentTokenPlayingMedia, setCurrentTokenPlayingMedia] = useState<string | undefined>()
const [isFiltersExpanded, setFiltersExpanded] = useFiltersExpanded()
const oldStateRef = useRef<CollectionFilters | null>(null)
@ -309,7 +308,6 @@ export const CollectionNfts = ({ contractAddress, collectionStats, rarityVerifie
)
useEffect(() => {
setUniformHeight(UniformHeights.unset)
setSweepOpen(false)
return () => {
useCollectionFilters.setState(initialCollectionFilterState)
@ -323,14 +321,12 @@ export const CollectionNfts = ({ contractAddress, collectionStats, rarityVerifie
key={asset.address + asset.tokenId}
asset={asset}
isMobile={isMobile}
uniformHeight={uniformHeight}
setUniformHeight={setUniformHeight}
mediaShouldBePlaying={asset.tokenId === currentTokenPlayingMedia}
setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia}
rarityVerified={rarityVerified}
/>
))
}, [collectionNfts, currentTokenPlayingMedia, isMobile, rarityVerified, uniformHeight])
}, [collectionNfts, currentTokenPlayingMedia, isMobile, rarityVerified])
const hasNfts = collectionNfts && collectionNfts.length > 0
const hasErc1155s = hasNfts && collectionNfts[0] && collectionNfts[0].tokenType === TokenType.ERC1155
@ -506,7 +502,7 @@ export const CollectionNfts = ({ contractAddress, collectionStats, rarityVerifie
<InfiniteScroll
next={() => loadNext(ASSET_PAGE_SIZE)}
hasMore={hasNext}
loader={hasNext && hasNfts ? loadingAssets(uniformHeight) : null}
loader={hasNext && hasNfts ? loadingAssets() : null}
dataLength={collectionNfts?.length ?? 0}
style={{ overflow: 'unset' }}
className={hasNfts || isLoadingNext ? styles.assetList : undefined}

@ -20,14 +20,7 @@ import {
} from 'nft/hooks'
import { ScreenBreakpointsPaddings } from 'nft/pages/collection/index.css'
import { OSCollectionsFetcher } from 'nft/queries'
import {
ProfilePageStateType,
TokenType,
UniformHeight,
UniformHeights,
WalletAsset,
WalletCollection,
} from 'nft/types'
import { ProfilePageStateType, TokenType, WalletAsset, WalletCollection } from 'nft/types'
import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'
import InfiniteScroll from 'react-infinite-scroll-component'
import { useQuery } from 'react-query'
@ -94,7 +87,6 @@ export const ProfilePage = () => {
const [isFiltersExpanded, setFiltersExpanded] = useFiltersExpanded()
const isMobile = useIsMobile()
const [currentTokenPlayingMedia, setCurrentTokenPlayingMedia] = useState<string | undefined>()
const [uniformHeight, setUniformHeight] = useState<UniformHeight>(UniformHeights.unset)
const handleSellModeClick = useCallback(() => {
resetSellAssets()
@ -193,8 +185,6 @@ export const ProfilePage = () => {
isSellMode={isSellMode}
mediaShouldBePlaying={asset.tokenId === currentTokenPlayingMedia}
setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia}
uniformHeight={uniformHeight}
setUniformHeight={setUniformHeight}
/>
</div>
))

@ -7,7 +7,6 @@ import { bodySmall } from 'nft/css/common.css'
import { themeVars } from 'nft/css/sprinkles.css'
import { useBag, useIsMobile, useSellAsset } from 'nft/hooks'
import { TokenType, WalletAsset } from 'nft/types'
import { UniformHeight } from 'nft/types'
import { useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
const NFT_DETAILS_HREF = (asset: WalletAsset) =>
@ -18,38 +17,20 @@ interface ViewMyNftsAssetProps {
isSellMode: boolean
mediaShouldBePlaying: boolean
setCurrentTokenPlayingMedia: (tokenId: string | undefined) => void
uniformHeight: UniformHeight
setUniformHeight: (u: UniformHeight) => void
}
const getNftDisplayComponent = (
assetMediaType: AssetMediaType,
mediaShouldBePlaying: boolean,
setCurrentTokenPlayingMedia: (tokenId: string | undefined) => void,
uniformHeight: UniformHeight,
setUniformHeight: (u: UniformHeight) => void
setCurrentTokenPlayingMedia: (tokenId: string | undefined) => void
) => {
switch (assetMediaType) {
case AssetMediaType.Image:
return <Card.Image uniformHeight={uniformHeight} setUniformHeight={setUniformHeight} />
return <Card.Image />
case AssetMediaType.Video:
return (
<Card.Video
uniformHeight={uniformHeight}
setUniformHeight={setUniformHeight}
shouldPlay={mediaShouldBePlaying}
setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia}
/>
)
return <Card.Video shouldPlay={mediaShouldBePlaying} setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia} />
case AssetMediaType.Audio:
return (
<Card.Audio
uniformHeight={uniformHeight}
setUniformHeight={setUniformHeight}
shouldPlay={mediaShouldBePlaying}
setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia}
/>
)
return <Card.Audio shouldPlay={mediaShouldBePlaying} setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia} />
}
}
@ -58,8 +39,6 @@ export const ViewMyNftsAsset = ({
isSellMode,
mediaShouldBePlaying,
setCurrentTokenPlayingMedia,
uniformHeight,
setUniformHeight,
}: ViewMyNftsAssetProps) => {
const sellAssets = useSellAsset((state) => state.sellAssets)
const selectSellAsset = useSellAsset((state) => state.selectSellAsset)
@ -119,13 +98,7 @@ export const ViewMyNftsAsset = ({
isDisabled={isDisabled}
>
<Card.ImageContainer>
{getNftDisplayComponent(
assetMediaType,
mediaShouldBePlaying,
setCurrentTokenPlayingMedia,
uniformHeight,
setUniformHeight
)}
{getNftDisplayComponent(assetMediaType, mediaShouldBePlaying, setCurrentTokenPlayingMedia)}
</Card.ImageContainer>
<Card.DetailsContainer>
<Card.ProfileNftDetails asset={asset} isSellMode={isSellMode} />