Commit 910e86d6 authored by Charles Bachmeier's avatar Charles Bachmeier Committed by GitHub

feat: Add loading skeleton for profile page (#4823)

* Add loading skeleton for profile page

* add consts for sidebar width and padding
Co-authored-by: default avatarCharles Bachmeier <charlie@genie.xyz>
parent 537fea10
......@@ -26,6 +26,7 @@ import styled from 'styled-components/macro'
import { EmptyWalletContent } from './EmptyWalletContent'
import { ProfileAccountDetails } from './ProfileAccountDetails'
import * as styles from './ProfilePage.css'
import { ProfilePageLoadingSkeleton } from './ProfilePageLoadingSkeleton'
import { WalletAssetDisplay } from './WalletAssetDisplay'
const SellModeButton = styled.button<{ active: boolean }>`
......@@ -46,6 +47,9 @@ const SellModeButton = styled.button<{ active: boolean }>`
}
`
const FILTER_SIDEBAR_WIDTH = 300
const PADDING = 16
function roundFloorPrice(price?: number, n?: number) {
return price ? Math.round(price * Math.pow(10, n ?? 3) + Number.EPSILON) / Math.pow(10, n ?? 3) : 0
}
......@@ -76,7 +80,7 @@ export const ProfilePage = () => {
toggleSellMode()
}
const { data: ownerCollections } = useQuery(
const { data: ownerCollections, isLoading: collectionsAreLoading } = useQuery(
['ownerCollections', address],
() => OSCollectionsFetcher({ params: { asset_owner: address, offset: '0', limit: '300' } }),
{
......@@ -85,7 +89,7 @@ export const ProfilePage = () => {
)
const ownerCollectionsAddresses = useMemo(() => ownerCollections?.map(({ address }) => address), [ownerCollections])
const { data: collectionStats } = useQuery(
const { data: collectionStats, isLoading: collectionStatsAreLoading } = useQuery(
['ownerCollectionStats', ownerCollectionsAddresses],
() => fetchMultipleCollectionStats({ addresses: ownerCollectionsAddresses ?? [] }),
{
......@@ -98,6 +102,7 @@ export const ProfilePage = () => {
fetchNextPage,
hasNextPage,
isSuccess,
isLoading: assetsAreLoading,
} = useInfiniteQuery(
['ownerAssets', address, collectionFilters],
async ({ pageParam = 0 }) => {
......@@ -116,6 +121,8 @@ export const ProfilePage = () => {
}
)
const anyQueryIsLoading = collectionsAreLoading || collectionStatsAreLoading || assetsAreLoading
const ownerAssets = useMemo(() => (isSuccess ? ownerAssetsData?.pages.flat() : null), [isSuccess, ownerAssetsData])
useEffect(() => {
......@@ -153,17 +160,19 @@ export const ProfilePage = () => {
}, [collectionStats, ownerCollections, setWalletCollections])
const { gridX } = useSpring({
gridX: isFiltersExpanded ? 300 : -16,
gridX: isFiltersExpanded ? FILTER_SIDEBAR_WIDTH : -PADDING,
})
return (
<Column
width="full"
paddingLeft={{ sm: '16', md: '52' }}
paddingRight={{ sm: '0', md: isBagExpanded ? '0' : '72' }}
paddingTop={{ sm: '16', md: '40' }}
paddingLeft={{ sm: `${PADDING}`, md: '52' }}
paddingRight={{ sm: `${PADDING}`, md: isBagExpanded ? '0' : '72' }}
paddingTop={{ sm: `${PADDING}`, md: '40' }}
>
{walletAssets.length === 0 ? (
{anyQueryIsLoading ? (
<ProfilePageLoadingSkeleton />
) : walletAssets.length === 0 ? (
<EmptyWalletContent />
) : (
<Row alignItems="flex-start" position="relative">
......@@ -173,10 +182,12 @@ export const ProfilePage = () => {
<Column width="full">
<ProfileAccountDetails />
<AnimatedBox
paddingLeft={isFiltersExpanded ? '24' : '16'}
flexShrink="0"
style={{
transform: gridX.to((x) => `translate(${Number(x) - (!isMobile && isFiltersExpanded ? 300 : 0)}px)`),
transform: gridX.to(
(x) =>
`translate(${Number(x) - (!isMobile && isFiltersExpanded ? FILTER_SIDEBAR_WIDTH : -PADDING)}px)`
),
}}
>
<Row gap="8" flexWrap="nowrap" justifyContent="space-between">
......
import { assetList } from 'nft/components/collection/CollectionNfts.css'
import styled from 'styled-components/macro'
const SkeletonPageWrapper = styled.div`
display: flex;
flex-direction: column;
width: 100%;
gap: 18px;
`
const SkeletonRowWrapper = styled.div`
display: flex;
flex-direct: row;
width: 100%;
`
const AccountDetailsSkeletonWrapper = styled(SkeletonRowWrapper)`
gap: 12px;
margin-bottom: 30px;
`
const ProfilePictureSkeleton = styled.div`
height: 44px;
width: 44px;
background: ${({ theme }) => theme.backgroundModule};
border-radius: 100px;
`
const ProfileDetailsSkeleton = styled.div`
width: 180px;
height: 36px;
background: ${({ theme }) => theme.backgroundModule};
border-radius: 12px;
`
const FilterBarSkeletonWrapper = styled(SkeletonRowWrapper)`
justify-content: space-between;
`
const FilterButtonSkeleton = styled.div`
width: 92px;
height: 44px;
background: ${({ theme }) => theme.backgroundModule};
border-radius: 12px;
`
const SellButtonSkeleton = styled.div`
width: 80px;
height: 44px;
background: ${({ theme }) => theme.backgroundModule};
border-radius: 12px;
`
export const ProfileAssetsWrapperSkeleton = styled(SkeletonRowWrapper)`
flex-wrap: wrap;
gap: 26px;
margin-bottom: 20px;
`
export const ProfileAssetCardSkeleton = styled.div`
width: 100%;
height: 330px;
background: ${({ theme }) => theme.backgroundModule};
border-radius: 20px;
`
export const ProfilePageLoadingSkeleton = () => {
return (
<SkeletonPageWrapper>
<AccountDetailsSkeletonWrapper>
<ProfilePictureSkeleton />
<ProfileDetailsSkeleton />
</AccountDetailsSkeletonWrapper>
<FilterBarSkeletonWrapper>
<FilterButtonSkeleton />
<SellButtonSkeleton />
</FilterBarSkeletonWrapper>
<div className={assetList}>{new Array(25).fill(<ProfileAssetCardSkeleton />)}</div>
</SkeletonPageWrapper>
)
}
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