Commit 818e9832 authored by Jack Short's avatar Jack Short Committed by GitHub

style: adding loading state for asset activity (#5503)

* style: adding loading state for asset activity

* translations

* previous translations did not work
parent aa3225c2
import { Trans } from '@lingui/macro'
import { OpacityHoverState, ScrollBarStyles } from 'components/Common' import { OpacityHoverState, ScrollBarStyles } from 'components/Common'
import { LoadingBubble } from 'components/Tokens/loading'
import { EventCell, MarketplaceIcon } from 'nft/components/collection/ActivityCells'
import { ActivityEventResponse } from 'nft/types' import { ActivityEventResponse } from 'nft/types'
import { shortenAddress } from 'nft/utils/address' import { shortenAddress } from 'nft/utils/address'
import { formatEthPrice } from 'nft/utils/currency' import { formatEthPrice } from 'nft/utils/currency'
import { getTimeDifference } from 'nft/utils/date' import { getTimeDifference } from 'nft/utils/date'
import { putCommas } from 'nft/utils/putCommas' import { putCommas } from 'nft/utils/putCommas'
import { ReactNode } from 'react'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { EventCell } from '../collection/ActivityCells'
import { MarketplaceIcon } from '../collection/ActivityCells'
const TR = styled.tr` const TR = styled.tr`
border-bottom: ${({ theme }) => `1px solid ${theme.backgroundOutline}`}; border-bottom: ${({ theme }) => `1px solid ${theme.backgroundOutline}`};
width: 100%; width: 100%;
...@@ -84,20 +85,71 @@ const ActivityContainer = styled.div` ...@@ -84,20 +85,71 @@ const ActivityContainer = styled.div`
${ScrollBarStyles} ${ScrollBarStyles}
` `
const AssetActivity = ({ eventsData }: { eventsData: ActivityEventResponse | undefined }) => { const LoadingCell = styled(LoadingBubble)`
height: 20px;
width: 80px;
`
const ActivityTable = ({ children }: { children: ReactNode }) => {
return ( return (
<ActivityContainer id="activityContainer"> <ActivityContainer id="activityContainer">
<Table> <Table>
<thead> <thead>
<TR> <TR>
<TH>Event</TH> <TH>
<TH>Price</TH> <Trans>Event</Trans>
<TH>By</TH> </TH>
<TH>To</TH> <TH>
<TH>Time</TH> <Trans>Price</Trans>
</TH>
<TH>
<Trans>By</Trans>
</TH>
<TH>
<Trans>To</Trans>
</TH>
<TH>
<Trans>Time</Trans>
</TH>
</TR> </TR>
</thead> </thead>
<tbody> <tbody>{children}</tbody>
</Table>
</ActivityContainer>
)
}
const LoadingAssetActivityRow = ({ cellCount }: { cellCount: number }) => {
return (
<TR>
{Array(cellCount)
.fill(null)
.map((_, index) => {
return (
<TD key={index}>
<LoadingCell />
</TD>
)
})}
</TR>
)
}
export const LoadingAssetActivity = ({ rowCount }: { rowCount: number }) => {
return (
<ActivityTable>
{Array(rowCount)
.fill(null)
.map((_, index) => {
return <LoadingAssetActivityRow key={index} cellCount={5} />
})}
</ActivityTable>
)
}
const AssetActivity = ({ eventsData }: { eventsData: ActivityEventResponse | undefined }) => {
return (
<ActivityTable>
{eventsData?.events && {eventsData?.events &&
eventsData.events.map((event, index) => { eventsData.events.map((event, index) => {
const { eventTimestamp, eventType, fromAddress, marketplace, price, toAddress, transactionHash } = event const { eventTimestamp, eventType, fromAddress, marketplace, price, toAddress, transactionHash } = event
...@@ -124,11 +176,7 @@ const AssetActivity = ({ eventsData }: { eventsData: ActivityEventResponse | und ...@@ -124,11 +176,7 @@ const AssetActivity = ({ eventsData }: { eventsData: ActivityEventResponse | und
<TD> <TD>
{fromAddress && ( {fromAddress && (
<Link <Link href={`https://etherscan.io/address/${fromAddress}`} target="_blank" rel="noopener noreferrer">
href={`https://etherscan.io/address/${fromAddress}`}
target="_blank"
rel="noopener noreferrer"
>
{shortenAddress(fromAddress, 2, 4)} {shortenAddress(fromAddress, 2, 4)}
</Link> </Link>
)} )}
...@@ -136,11 +184,7 @@ const AssetActivity = ({ eventsData }: { eventsData: ActivityEventResponse | und ...@@ -136,11 +184,7 @@ const AssetActivity = ({ eventsData }: { eventsData: ActivityEventResponse | und
<TD> <TD>
{toAddress && ( {toAddress && (
<Link <Link href={`https://etherscan.io/address/${toAddress}`} target="_blank" rel="noopener noreferrer">
href={`https://etherscan.io/address/${toAddress}`}
target="_blank"
rel="noopener noreferrer"
>
{shortenAddress(toAddress, 2, 4)} {shortenAddress(toAddress, 2, 4)}
</Link> </Link>
)} )}
...@@ -149,9 +193,7 @@ const AssetActivity = ({ eventsData }: { eventsData: ActivityEventResponse | und ...@@ -149,9 +193,7 @@ const AssetActivity = ({ eventsData }: { eventsData: ActivityEventResponse | und
</TR> </TR>
) )
})} })}
</tbody> </ActivityTable>
</Table>
</ActivityContainer>
) )
} }
......
...@@ -22,7 +22,7 @@ import { Link as RouterLink } from 'react-router-dom' ...@@ -22,7 +22,7 @@ import { Link as RouterLink } from 'react-router-dom'
import { useIsDarkMode } from 'state/user/hooks' import { useIsDarkMode } from 'state/user/hooks'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import AssetActivity from './AssetActivity' import AssetActivity, { LoadingAssetActivity } from './AssetActivity'
import * as styles from './AssetDetails.css' import * as styles from './AssetDetails.css'
import DetailsContainer from './DetailsContainer' import DetailsContainer from './DetailsContainer'
import InfoContainer from './InfoContainer' import InfoContainer from './InfoContainer'
...@@ -312,6 +312,7 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => { ...@@ -312,6 +312,7 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => {
hasNextPage, hasNextPage,
isFetchingNextPage, isFetchingNextPage,
isSuccess, isSuccess,
isLoading: isActivityLoading,
} = useInfiniteQuery<ActivityEventResponse>( } = useInfiniteQuery<ActivityEventResponse>(
[ [
'collectionActivity', 'collectionActivity',
...@@ -410,16 +411,17 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => { ...@@ -410,16 +411,17 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => {
<Filter eventType={ActivityEventType.Transfer} /> <Filter eventType={ActivityEventType.Transfer} />
<Filter eventType={ActivityEventType.CancelListing} /> <Filter eventType={ActivityEventType.CancelListing} />
</ActivitySelectContainer> </ActivitySelectContainer>
{isActivityLoading && <LoadingAssetActivity rowCount={10} />}
{events && events.length > 0 ? ( {events && events.length > 0 ? (
<InfiniteScroll <InfiniteScroll
next={fetchNextPage} next={fetchNextPage}
hasMore={!!hasNextPage} hasMore={!!hasNextPage}
loader={ loader={
isFetchingNextPage ? ( isFetchingNextPage && (
<Center> <Center>
<LoadingSparkle /> <LoadingSparkle />
</Center> </Center>
) : null )
} }
dataLength={events?.length ?? 0} dataLength={events?.length ?? 0}
scrollableTarget="activityContainer" scrollableTarget="activityContainer"
...@@ -427,12 +429,16 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => { ...@@ -427,12 +429,16 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => {
<AssetActivity eventsData={{ events }} /> <AssetActivity eventsData={{ events }} />
</InfiniteScroll> </InfiniteScroll>
) : ( ) : (
<>
{!isActivityLoading && (
<EmptyActivitiesContainer> <EmptyActivitiesContainer>
<div>No activities yet</div> <div>No activities yet</div>
<Link to={`/nfts/collection/${asset.address}`}>View collection items</Link>{' '} <Link to={`/nfts/collection/${asset.address}`}>View collection items</Link>{' '}
</EmptyActivitiesContainer> </EmptyActivitiesContainer>
)} )}
</> </>
)}
</>
</InfoContainer> </InfoContainer>
<InfoContainer primaryHeader="Description" defaultOpen secondaryHeader={null}> <InfoContainer primaryHeader="Description" defaultOpen secondaryHeader={null}>
<> <>
......
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