Commit 53f4fb9e authored by aballerr's avatar aballerr Committed by GitHub

chore: Merging Loading states 2 (#4708)

* adding in remaining loading styles
Co-authored-by: default avatarAlex Ball <alexball@UNISWAP-MAC-038.local>
parent bb1ccb7f
import { style } from '@vanilla-extract/css'
import { buttonTextMedium } from 'nft/css/common.css'
import { loadingAsset } from 'nft/css/loading.css'
import { sprinkles, vars } from 'nft/css/sprinkles.css'
export const baseActivitySwitcherToggle = style([
......@@ -40,3 +41,11 @@ export const selectedActivitySwitcherToggle = style([
},
},
])
export const styledLoading = style([
loadingAsset,
{
width: 58,
height: 20,
},
])
import { Box } from 'nft/components/Box'
import { Row } from 'nft/components/Flex'
import { useIsCollectionLoading } from 'nft/hooks'
import * as styles from './ActivitySwitcher.css'
......@@ -10,22 +11,31 @@ export const ActivitySwitcher = ({
showActivity: boolean
toggleActivity: () => void
}) => {
const isLoading = useIsCollectionLoading((state) => state.isCollectionStatsLoading)
const loadingVals = new Array(2).fill(<div className={styles.styledLoading} />)
return (
<Row gap="24" marginBottom="28">
<Box
as="button"
className={showActivity ? styles.activitySwitcherToggle : styles.selectedActivitySwitcherToggle}
onClick={() => showActivity && toggleActivity()}
>
Items
</Box>
<Box
as="button"
className={!showActivity ? styles.activitySwitcherToggle : styles.selectedActivitySwitcherToggle}
onClick={() => !showActivity && toggleActivity()}
>
Activity
</Box>
{isLoading ? (
loadingVals
) : (
<>
<Box
as="button"
className={showActivity ? styles.activitySwitcherToggle : styles.selectedActivitySwitcherToggle}
onClick={() => showActivity && toggleActivity()}
>
Items
</Box>
<Box
as="button"
className={!showActivity ? styles.activitySwitcherToggle : styles.selectedActivitySwitcherToggle}
onClick={() => !showActivity && toggleActivity()}
>
Activity
</Box>
</>
)}
</Row>
)
}
......@@ -17,6 +17,7 @@ import {
useFiltersExpanded,
useIsMobile,
} from 'nft/hooks'
import { useIsCollectionLoading } from 'nft/hooks/useIsCollectionLoading'
import { AssetsFetcher } from 'nft/queries'
import { DropDownOption, GenieCollection, UniformHeight, UniformHeights } from 'nft/types'
import { getRarityStatus } from 'nft/utils/asset'
......@@ -46,6 +47,7 @@ export const CollectionNfts = ({ contractAddress, collectionStats, rarityVerifie
const setMarketCount = useCollectionFilters((state) => state.setMarketCount)
const setSortBy = useCollectionFilters((state) => state.setSortBy)
const buyNow = useCollectionFilters((state) => state.buyNow)
const setIsCollectionNftsLoading = useIsCollectionLoading((state) => state.setIsCollectionNftsLoading)
const debouncedMinPrice = useDebounce(minPrice, 500)
const debouncedMaxPrice = useDebounce(maxPrice, 500)
......@@ -115,6 +117,10 @@ export const CollectionNfts = ({ contractAddress, collectionStats, rarityVerifie
}
)
useEffect(() => {
setIsCollectionNftsLoading(isLoading)
}, [isLoading, setIsCollectionNftsLoading])
const [uniformHeight, setUniformHeight] = useState<UniformHeight>(UniformHeights.unset)
const [currentTokenPlayingMedia, setCurrentTokenPlayingMedia] = useState<string | undefined>()
const [isFiltersExpanded, setFiltersExpanded] = useFiltersExpanded()
......
import { style } from '@vanilla-extract/css'
import { loadingAsset } from 'nft/css/loading.css'
import { sprinkles } from 'nft/css/sprinkles.css'
export const filterButtonLoading = style([
loadingAsset,
sprinkles({
border: 'none',
}),
])
import clsx from 'clsx'
import { Box } from 'nft/components/Box'
import * as styles from 'nft/components/collection/CollectionSearch.css'
import { useIsCollectionLoading } from 'nft/hooks'
import { useCollectionFilters } from 'nft/hooks/useCollectionFilters'
import { FormEvent } from 'react'
export const CollectionSearch = () => {
const setSearchByNameText = useCollectionFilters((state) => state.setSearch)
const searchByNameText = useCollectionFilters((state) => state.search)
const iscollectionStatsLoading = useIsCollectionLoading((state) => state.isCollectionStatsLoading)
return (
<Box
......@@ -19,7 +23,8 @@ export const CollectionSearch = () => {
height="44"
color={{ placeholder: 'textSecondary', default: 'textPrimary' }}
value={searchByNameText}
placeholder={'Search by name'}
placeholder={iscollectionStatsLoading ? '' : 'Search by name'}
className={clsx(iscollectionStatsLoading && styles.filterButtonLoading)}
onChange={(e: FormEvent<HTMLInputElement>) => {
setSearchByNameText(e.currentTarget.value)
}}
......
import { style } from '@vanilla-extract/css'
import { body, bodySmall } from 'nft/css/common.css'
import { loadingAsset, loadingBlock } from 'nft/css/loading.css'
import { breakpoints, sprinkles } from '../../css/sprinkles.css'
......@@ -113,3 +114,54 @@ export const statsValue = style([
lineHeight: '24px',
},
])
export const statsValueLoading = style([
loadingAsset,
sprinkles({
width: '60',
height: '20',
marginTop: '8',
}),
])
export const statsLabelLoading = style([
loadingAsset,
sprinkles({
width: '60',
height: '16',
}),
])
export const descriptionLoading = style([
loadingAsset,
{
maxWidth: 'min(calc(100% - 112px), 600px)',
},
])
export const collectionImageIsLoadingBackground = style([
collectionImage,
sprinkles({
backgroundColor: 'backgroundSurface',
}),
])
export const collectionImageIsLoading = style([
loadingBlock,
collectionImage,
sprinkles({
borderStyle: 'solid',
borderWidth: '4px',
borderColor: 'backgroundSurface',
}),
])
export const nameTextLoading = style([
loadingAsset,
sprinkles({
height: '32',
}),
{
width: 236,
},
])
......@@ -4,6 +4,7 @@ import { Column, Row } from 'nft/components/Flex'
import { Marquee } from 'nft/components/layout/Marquee'
import { headlineMedium } from 'nft/css/common.css'
import { themeVars } from 'nft/css/sprinkles.css'
import { useIsCollectionLoading } from 'nft/hooks/useIsCollectionLoading'
import { GenieCollection } from 'nft/types'
import { ethNumberStandardFormatter } from 'nft/utils/currency'
import { putCommas } from 'nft/utils/putCommas'
......@@ -124,14 +125,13 @@ const CollectionName = ({
collectionSocialsIsOpen: boolean
toggleCollectionSocials: () => void
}) => {
const isCollectionStatsLoading = useIsCollectionLoading((state) => state.isCollectionStatsLoading)
const nameClass = isCollectionStatsLoading ? styles.nameTextLoading : clsx(headlineMedium, styles.nameText)
return (
<Row justifyContent="space-between">
<Row minWidth="0">
<Box
marginRight={!isVerified ? '12' : '0'}
className={clsx(isMobile ? headlineMedium : headlineMedium, styles.nameText)}
style={{ lineHeight: '32px' }}
>
<Box marginRight={!isVerified ? '12' : '0'} className={nameClass}>
{name}
</Box>
{isVerified && <VerifiedIcon style={{ width: '32px', height: '32px' }} />}
......@@ -144,7 +144,7 @@ const CollectionName = ({
height="32"
>
{collectionStats.discordUrl ? (
<SocialsIcon href={collectionStats.discordUrl}>
<SocialsIcon href={collectionStats.discordUrl ?? ''}>
<DiscordIcon
fill={themeVars.colors.textSecondary}
color={themeVars.colors.textSecondary}
......@@ -170,7 +170,7 @@ const CollectionName = ({
</SocialsIcon>
) : null}
{collectionStats.externalUrl ? (
<SocialsIcon href={collectionStats.externalUrl}>
<SocialsIcon href={collectionStats.externalUrl ?? ''}>
<ExternalIcon fill={themeVars.colors.textSecondary} width="26px" height="26px" />
</SocialsIcon>
) : null}
......@@ -196,6 +196,7 @@ const CollectionDescription = ({ description }: { description: string }) => {
const [readMore, toggleReadMore] = useReducer((state) => !state, false)
const baseRef = useRef<HTMLDivElement>(null)
const descriptionRef = useRef<HTMLDivElement>(null)
const isCollectionStatsLoading = useIsCollectionLoading((state) => state.isCollectionStatsLoading)
useEffect(() => {
if (
......@@ -209,7 +210,9 @@ const CollectionDescription = ({ description }: { description: string }) => {
setShowReadMore(true)
}, [descriptionRef, baseRef])
return (
return isCollectionStatsLoading ? (
<Box marginTop={{ sm: '12', md: '16' }} className={styles.descriptionLoading}></Box>
) : (
<Box ref={baseRef} marginTop={{ sm: '12', md: '16' }} style={{ maxWidth: '680px' }}>
<Box
ref={descriptionRef}
......@@ -228,29 +231,44 @@ const CollectionDescription = ({ description }: { description: string }) => {
)
}
const StatsItem = ({ children, label, isMobile }: { children: ReactNode; label: string; isMobile: boolean }) => (
<Box display="flex" flexDirection={isMobile ? 'row' : 'column'} alignItems="baseline" gap="2" height="min">
<Box as="span" className={styles.statsLabel}>
{`${label}${isMobile ? ': ' : ''}`}
const StatsItem = ({ children, label, isMobile }: { children: ReactNode; label: string; isMobile: boolean }) => {
return (
<Box display="flex" flexDirection={isMobile ? 'row' : 'column'} alignItems="baseline" gap="2" height="min">
<Box as="span" className={styles.statsLabel}>
{`${label}${isMobile ? ': ' : ''}`}
</Box>
<span className={styles.statsValue}>{children}</span>
</Box>
<span className={styles.statsValue}>{children}</span>
</Box>
)
)
}
const StatsRow = ({ stats, isMobile, ...props }: { stats: GenieCollection; isMobile?: boolean } & BoxProps) => {
const numOwnersStr = stats.stats ? putCommas(stats.stats.num_owners) : 0
const totalSupplyStr = stats.stats ? putCommas(stats.stats.total_supply) : 0
const totalListingsStr = stats.stats ? putCommas(stats.stats.total_listings) : 0
const isCollectionStatsLoading = useIsCollectionLoading((state) => state.isCollectionStatsLoading)
// round daily volume & floorPrice to 3 decimals or less
const totalVolumeStr = ethNumberStandardFormatter(stats.stats?.total_volume)
const floorPriceStr = ethNumberStandardFormatter(stats.floorPrice)
const statsLoadingSkeleton = new Array(5).fill(
<>
<Box display="flex" flexDirection={isMobile ? 'row' : 'column'} alignItems="baseline" gap="2" height="min">
<div className={styles.statsLabelLoading} />
<span className={styles.statsValueLoading} />
</Box>
</>
)
return (
<Row gap={{ sm: '20', md: '60' }} {...props}>
<StatsItem label="Items" isMobile={isMobile ?? false}>
{totalSupplyStr}
</StatsItem>
{isCollectionStatsLoading && statsLoadingSkeleton}
{totalSupplyStr ? (
<StatsItem label="Items" isMobile={isMobile ?? false}>
{totalSupplyStr}
</StatsItem>
) : null}
{numOwnersStr ? (
<StatsItem label="Owners" isMobile={isMobile ?? false}>
{numOwnersStr}
......@@ -277,10 +295,7 @@ const StatsRow = ({ stats, isMobile, ...props }: { stats: GenieCollection; isMob
export const CollectionStats = ({ stats, isMobile }: { stats: GenieCollection; isMobile: boolean }) => {
const [collectionSocialsIsOpen, toggleCollectionSocials] = useReducer((state) => !state, false)
if (!stats) {
return <div>Loading CollectionStats...</div>
}
const isCollectionStatsLoading = useIsCollectionLoading((state) => state.isCollectionStatsLoading)
return (
<Box
......@@ -291,11 +306,14 @@ export const CollectionStats = ({ stats, isMobile }: { stats: GenieCollection; i
flexDirection="column"
width="full"
>
{isCollectionStatsLoading && (
<Box as="div" borderRadius="round" position="absolute" className={styles.collectionImageIsLoadingBackground} />
)}
<Box
as="img"
as={isCollectionStatsLoading ? 'div' : 'img'}
borderRadius="round"
position="absolute"
className={styles.collectionImage}
className={isCollectionStatsLoading ? styles.collectionImageIsLoading : styles.collectionImage}
src={stats.isFoundation && !stats.imageUrl ? '/nft/svgs/marketplaces/foundation.svg' : stats.imageUrl}
/>
<Box className={styles.statsText}>
......@@ -309,7 +327,9 @@ export const CollectionStats = ({ stats, isMobile }: { stats: GenieCollection; i
/>
{!isMobile && (
<>
{stats.description && <CollectionDescription description={stats.description} />}
{(stats.description || isCollectionStatsLoading) && (
<CollectionDescription description={stats.description} />
)}
<StatsRow stats={stats} marginTop="20" />
</>
)}
......
import { style } from '@vanilla-extract/css'
import { loadingAsset } from 'nft/css/loading.css'
import { sprinkles, themeVars, vars } from 'nft/css/sprinkles.css'
export const filterButton = sprinkles({
......@@ -21,3 +22,11 @@ export const filterBadge = style([
top: '-3px',
},
])
export const filterButtonLoading = style([
loadingAsset,
sprinkles({
height: '44',
width: '100',
}),
])
......@@ -3,7 +3,7 @@ import { Box } from 'nft/components/Box'
import * as styles from 'nft/components/collection/FilterButton.css'
import { Row } from 'nft/components/Flex'
import { FilterIcon } from 'nft/components/icons'
import { useCollectionFilters, useWalletCollections } from 'nft/hooks'
import { useCollectionFilters, useIsCollectionLoading, useWalletCollections } from 'nft/hooks'
import { putCommas } from 'nft/utils/putCommas'
import { useLocation } from 'react-router-dom'
......@@ -32,13 +32,18 @@ export const FilterButton = ({
const collectionFilters = useWalletCollections((state) => state.collectionFilters)
const { pathname } = useLocation()
const isSellPage = pathname.startsWith('/nfts/sell')
const isCollectionNftsLoading = useIsCollectionLoading((state) => state.isCollectionNftsLoading)
const showFilterBadge = isSellPage
? collectionFilters.length > 0
: minPrice || maxPrice || minRarity || maxRarity || traits.length || markets.length || buyNow
return (
<Box
className={clsx(styles.filterButton, !isFiltersExpanded && styles.filterButtonExpanded)}
className={
isCollectionNftsLoading
? styles.filterButtonLoading
: clsx(styles.filterButton, !isFiltersExpanded && styles.filterButtonExpanded)
}
borderRadius="12"
fontSize="16"
cursor="pointer"
......@@ -52,14 +57,20 @@ export const FilterButton = ({
height="44"
whiteSpace="nowrap"
>
{showFilterBadge && (
<Row className={styles.filterBadge} color={isFiltersExpanded ? 'grey700' : 'blue400'}>
</Row>
{!isCollectionNftsLoading && (
<>
{showFilterBadge && (
<Row className={styles.filterBadge} color={isFiltersExpanded ? 'grey700' : 'blue400'}>
</Row>
)}
<FilterIcon
style={{ marginBottom: '-4px', paddingRight: `${!isFiltersExpanded || showFilterBadge ? '6px' : '0px'}` }}
/>
</>
)}
<FilterIcon
style={{ marginBottom: '-4px', paddingRight: `${!isFiltersExpanded || showFilterBadge ? '6px' : '0px'}` }}
/>
{!isMobile && !isFiltersExpanded && 'Filter'}
{showFilterBadge && !isMobile ? (
......
import { style } from '@vanilla-extract/css'
import { loadingAsset } from 'nft/css/loading.css'
import { sprinkles } from 'nft/css/sprinkles.css'
export const activeDropdown = style({
borderBottom: 'none',
......@@ -7,3 +9,13 @@ export const activeDropdown = style({
export const activeDropDownItems = style({
borderTop: 'none',
})
export const isLoadingDropdown = style([
loadingAsset,
sprinkles({
height: '44',
}),
{
width: 220,
},
])
......@@ -5,6 +5,7 @@ import { Row } from 'nft/components/Flex'
import { ArrowsIcon, ChevronUpIcon, ReversedArrowsIcon } from 'nft/components/icons'
import { buttonTextMedium } from 'nft/css/common.css'
import { themeVars } from 'nft/css/sprinkles.css'
import { useIsCollectionLoading } from 'nft/hooks'
import { DropDownOption } from 'nft/types'
import { useEffect, useLayoutEffect, useMemo, useReducer, useRef, useState } from 'react'
......@@ -28,6 +29,7 @@ export const SortDropdown = ({
const [isOpen, toggleOpen] = useReducer((s) => !s, false)
const [isReversed, toggleReversed] = useReducer((s) => !s, false)
const [selectedIndex, setSelectedIndex] = useState(0)
const isCollectionStatsLoading = useIsCollectionLoading((state) => state.isCollectionStatsLoading)
const [maxWidth, setMaxWidth] = useState(0)
......@@ -41,6 +43,8 @@ export const SortDropdown = ({
[selectedIndex, dropDownOptions]
)
const width = isCollectionStatsLoading ? 220 : inFilters ? 'full' : mini ? 'min' : maxWidth ? maxWidth : '300px'
return (
<Box
ref={ref}
......@@ -49,7 +53,7 @@ export const SortDropdown = ({
borderBottomLeftRadius={isOpen ? '0' : undefined}
borderBottomRightRadius={isOpen ? '0' : undefined}
height="44"
style={{ width: inFilters ? 'full' : mini ? 'min' : maxWidth ? maxWidth : '300px' }}
style={{ width }}
>
<Box
as="button"
......@@ -70,51 +74,56 @@ export const SortDropdown = ({
width={inFilters ? 'full' : 'inherit'}
onClick={toggleOpen}
cursor="pointer"
className={clsx(isOpen && !mini && styles.activeDropdown)}
className={isCollectionStatsLoading ? styles.isLoadingDropdown : clsx(isOpen && !mini && styles.activeDropdown)}
>
<Box display="flex" alignItems="center">
{!isOpen && reversable && (
<Row
onClick={(e) => {
e.stopPropagation()
{!isCollectionStatsLoading && (
<>
<Box display="flex" alignItems="center">
{!isOpen && reversable && (
<Row
onClick={(e) => {
e.stopPropagation()
if (dropDownOptions[selectedIndex].reverseOnClick) {
dropDownOptions[selectedIndex].reverseOnClick?.()
toggleReversed()
} else {
const dropdownIndex = dropDownOptions[selectedIndex].reverseIndex ?? 1
dropDownOptions[dropdownIndex - 1].onClick()
setSelectedIndex(dropdownIndex - 1)
}
}}
>
{dropDownOptions[selectedIndex].reverseOnClick && (isReversed ? <ArrowsIcon /> : <ReversedArrowsIcon />)}
{dropDownOptions[selectedIndex].reverseIndex &&
(selectedIndex > (dropDownOptions[selectedIndex].reverseIndex ?? 1) - 1 ? (
<ArrowsIcon />
) : (
<ReversedArrowsIcon />
))}
</Row>
)}
<Box
marginLeft={reversable ? '4' : '0'}
marginRight={mini ? '2' : '0'}
color="textPrimary"
className={buttonTextMedium}
>
{mini ? miniPrompt : isOpen ? 'Sort by' : dropDownOptions[selectedIndex].displayText}
</Box>
</Box>
if (dropDownOptions[selectedIndex].reverseOnClick) {
dropDownOptions[selectedIndex].reverseOnClick?.()
toggleReversed()
} else {
const dropdownIndex = dropDownOptions[selectedIndex].reverseIndex ?? 1
dropDownOptions[dropdownIndex - 1].onClick()
setSelectedIndex(dropdownIndex - 1)
}
}}
>
{dropDownOptions[selectedIndex].reverseOnClick &&
(isReversed ? <ArrowsIcon /> : <ReversedArrowsIcon />)}
{dropDownOptions[selectedIndex].reverseIndex &&
(selectedIndex > (dropDownOptions[selectedIndex].reverseIndex ?? 1) - 1 ? (
<ArrowsIcon />
) : (
<ReversedArrowsIcon />
))}
</Row>
)}
<ChevronUpIcon
secondaryColor={mini ? themeVars.colors.textPrimary : undefined}
secondaryWidth={mini ? '20' : undefined}
secondaryHeight={mini ? '20' : undefined}
style={{
transform: isOpen ? '' : 'rotate(180deg)',
}}
/>
<Box
marginLeft={reversable ? '4' : '0'}
marginRight={mini ? '2' : '0'}
color="textPrimary"
className={buttonTextMedium}
>
{mini ? miniPrompt : isOpen ? 'Sort by' : dropDownOptions[selectedIndex].displayText}
</Box>
</Box>
<ChevronUpIcon
secondaryColor={mini ? themeVars.colors.textPrimary : undefined}
secondaryWidth={mini ? '20' : undefined}
secondaryHeight={mini ? '20' : undefined}
style={{
transform: isOpen ? '' : 'rotate(180deg)',
}}
/>
</>
)}
</Box>
<Box
position="absolute"
......
export * from './useBag'
export * from './useCollectionFilters'
export * from './useFiltersExpanded'
export * from './useIsCollectionLoading'
export * from './useIsMobile'
export * from './useIsTablet'
export * from './useMarketplaceSelect'
......
import create from 'zustand'
import { devtools } from 'zustand/middleware'
interface State {
isCollectionNftsLoading: boolean
setIsCollectionNftsLoading: (isCollectionNftsLoading: boolean) => void
isCollectionStatsLoading: boolean
setIsCollectionStatsLoading: (isCollectionStatsLoading: boolean) => void
}
export const useIsCollectionLoading = create<State>()(
devtools(
(set) => ({
isCollectionNftsLoading: false,
setIsCollectionNftsLoading: (isCollectionNftsLoading) =>
set(() => {
return { isCollectionNftsLoading }
}),
isCollectionStatsLoading: false,
setIsCollectionStatsLoading: (isCollectionStatsLoading) =>
set(() => {
return { isCollectionStatsLoading }
}),
}),
{ name: 'useIsCollectionLoading' }
)
)
import { style } from '@vanilla-extract/css'
import { buttonTextMedium } from 'nft/css/common.css'
import { loadingBlock } from 'nft/css/loading.css'
import { sprinkles, vars } from '../../css/sprinkles.css'
......@@ -46,6 +47,14 @@ export const selectedActivitySwitcherToggle = style([
},
])
export const loadingBanner = style([
loadingBlock,
sprinkles({
width: 'full',
height: '100',
}),
])
export const noCollectionAssets = sprinkles({
display: 'flex',
justifyContent: 'center',
......
import { AnimatedBox, Box } from 'nft/components/Box'
import { Activity, ActivitySwitcher, CollectionNfts, CollectionStats, Filters } from 'nft/components/collection'
import { Column, Row } from 'nft/components/Flex'
import { useBag, useCollectionFilters, useFiltersExpanded, useIsMobile } from 'nft/hooks'
import { useBag, useCollectionFilters, useFiltersExpanded, useIsCollectionLoading, useIsMobile } from 'nft/hooks'
import * as styles from 'nft/pages/collection/index.css'
import { CollectionStatsFetcher } from 'nft/queries'
import { GenieCollection } from 'nft/types'
import { useEffect } from 'react'
import { useQuery } from 'react-query'
import { useLocation, useNavigate, useParams } from 'react-router-dom'
import { useSpring } from 'react-spring/web'
import * as styles from './index.css'
const FILTER_WIDTH = 332
const BAG_WIDTH = 324
const Collection = () => {
const { contractAddress } = useParams()
const setIsCollectionStatsLoading = useIsCollectionLoading((state) => state.setIsCollectionStatsLoading)
const isMobile = useIsMobile()
const [isFiltersExpanded, setFiltersExpanded] = useFiltersExpanded()
......@@ -28,6 +29,10 @@ const Collection = () => {
CollectionStatsFetcher(contractAddress as string)
)
useEffect(() => {
setIsCollectionStatsLoading(isLoading)
}, [isLoading, setIsCollectionStatsLoading])
const { gridX, gridWidthOffset } = useSpring({
gridX: isFiltersExpanded ? FILTER_WIDTH : 0,
gridWidthOffset: isFiltersExpanded
......@@ -55,20 +60,30 @@ const Collection = () => {
return (
<Column width="full">
{collectionStats && contractAddress ? (
{contractAddress ? (
<>
{' '}
<Box width="full" height="160">
<Box
as="img"
maxHeight="full"
width="full"
src={collectionStats?.bannerImageUrl}
className={`${styles.bannerImage}`}
/>
<Box width="full" height="160">
{isLoading ? (
<Box height="full" width="full" className={styles.loadingBanner} />
) : (
<Box
as="img"
height="full"
width="full"
src={collectionStats?.bannerImageUrl}
className={isLoading ? styles.loadingBanner : styles.bannerImage}
background="none"
/>
)}
</Box>
</Box>
<Column paddingX="32">
{collectionStats && <CollectionStats stats={collectionStats} isMobile={isMobile} />}
{(isLoading || collectionStats !== undefined) && (
<CollectionStats stats={collectionStats || ({} as GenieCollection)} isMobile={isMobile} />
)}
<ActivitySwitcher
showActivity={isActivityToggled}
toggleActivity={() => {
......@@ -102,10 +117,11 @@ const Collection = () => {
collectionName={collectionStats?.name ?? ''}
/>
)
: contractAddress && (
: contractAddress &&
(isLoading || collectionStats !== undefined) && (
<CollectionNfts
collectionStats={collectionStats || ({} as GenieCollection)}
contractAddress={contractAddress}
collectionStats={collectionStats}
rarityVerified={collectionStats?.rarityVerified}
/>
)}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment