Skip to content

Commit

Permalink
👓 CRTs UI fixes (Joystream#6236)
Browse files Browse the repository at this point in the history
* Marketplace fixes

* Leave only 7 days as a suggested rs duration

* Switch mcap with total supply on channel token view

* Check if revenue share is ended, not finalized

* Make viewer side tables interactive

* Make studio side tables interactive

* Fix weird loading animation for carousels
  • Loading branch information
WRadoslaw authored and ikprk committed May 21, 2024
1 parent 6dffb6d commit 7ca3202
Show file tree
Hide file tree
Showing 23 changed files with 201 additions and 114 deletions.
6 changes: 4 additions & 2 deletions packages/atlas/src/components/AssetImage/AssetImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ export const AssetImage: FC<AssetImageProps> = ({ resolvedUrls, isLoading, type,
>
{loading ? (
<SkeletonLoader className={imgProps.className} />
) : imagePlaceholder && !url ? (
) : url ? (
<img {...imgProps} src={url} />
) : imagePlaceholder ? (
<>{imagePlaceholder}</>
) : (
<img {...imgProps} src={url} />
<span />
)}
</CSSTransition>
</SwitchTransition>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import styled from '@emotion/styled'
import BN from 'bn.js'
import { ReactElement, useMemo } from 'react'
import { useNavigate } from 'react-router'
Expand All @@ -14,8 +15,10 @@ import { HoldersWidget } from '@/components/_crt/HoldersWidget'
import { SkeletonLoader } from '@/components/_loaders/SkeletonLoader'
import { absoluteRoutes } from '@/config/routes'
import { useMediaMatch } from '@/hooks/useMediaMatch'
import { hapiBnToTokenNumber } from '@/joystream-lib/utils'
import { useConfirmationModal } from '@/providers/confirmationModal'
import { useUser } from '@/providers/user/user.hooks'
import { media, square } from '@/styles'
import { permillToPercentage } from '@/utils/number'

import {
Expand Down Expand Up @@ -59,17 +62,22 @@ export const getTokenDetails = (token: FullCreatorTokenFragment, cumulativeReven
'This percentage of the token supply gets minted every year and paid to creator for channel management.',
},
{
caption: 'TOTAL SUPPLY',
content: +token.totalSupply,
tooltipText: `Total amount of tokens owned by all holders.`,
caption: 'MARKET CAP',
content:
token.lastPrice && token.totalSupply
? hapiBnToTokenNumber(new BN(token.lastPrice).muln(+token.totalSupply))
: 0,
tooltipText: `The total market value of a token's supply.`,
icon: <StyledJoyTokenIcon variant="silver" />,
withDenomination: true,
},
]

if (cumulativeRevenue)
details.push({
caption: 'TOTAL REV.',
content: new BN(cumulativeRevenue),
icon: <JoyTokenIcon size={16} variant="silver" />,
icon: <StyledJoyTokenIcon variant="silver" />,
tooltipText: 'Total cumulative revenue of this channel on Joystream to date.',
withDenomination: true,
})
Expand Down Expand Up @@ -161,3 +169,11 @@ export const CrtPreviewLayout = ({
</Wrapper>
)
}

export const StyledJoyTokenIcon = styled(JoyTokenIcon)`
${square(16)}
${media.sm} {
${square(24)}
}
`
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from '@emotion/styled'
import { Link } from 'react-router-dom'

import { cVar, media, sizes } from '@/styles'
import { cVar, media, sizes, zIndex } from '@/styles'

export const InformationContainer = styled.div<{ isPaused: boolean }>`
width: 100%;
Expand Down Expand Up @@ -35,6 +35,12 @@ export const Container = styled.div`
}
`

export const LinkArea = styled.div`
position: absolute;
inset: 0;
z-index: ${zIndex.nearOverlay};
`

export const VideoContainer = styled.div`
position: relative;
width: 100%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { VideoCardWrapper } from '@/components/NftCarousel/components/Marketplac
import { Text } from '@/components/Text'
import { SkeletonLoader } from '@/components/_loaders/SkeletonLoader'
import { DetailsContent, DetailsContentProps } from '@/components/_nft/NftTile'
import { absoluteRoutes } from '@/config/routes'
import { useMediaMatch } from '@/hooks/useMediaMatch'
import { hapiBnToTokenNumber } from '@/joystream-lib/utils'
import { pluralizeNoun } from '@/utils/misc'
Expand Down Expand Up @@ -131,10 +132,11 @@ export const CrtCarouselDetails = ({
goNextSlide={slideNext}
mediaUrls={mediaUrls}
thumbnailUrls={thumbnailUrls}
to={absoluteRoutes.viewer.channel(channel?.channel.id ?? '', { tab: 'Token' })}
details={
<FlexBox flow="column" gap={4} width="100%">
<FlexBox gap={4}>
<Avatar size={smMatch ? 64 : 40} />
<Avatar assetUrls={channel?.channel.avatarPhoto?.resolvedUrls} size={smMatch ? 64 : 40} />

<FlexBox flow="column">
<Text variant={smMatch ? 'h600' : 'h500'} as="h5">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import BN from 'bn.js'
import { ReactNode, useMemo, useState } from 'react'
import { useNavigate } from 'react-router'
import { Link } from 'react-router-dom'
import { CSSTransition } from 'react-transition-group'

import { getNftStatus } from '@/api/hooks/nfts'
Expand All @@ -12,6 +13,7 @@ import {
Container,
DetailsContainer,
InformationContainer,
LinkArea,
StatsContainer,
StyledLink,
VideoContainer,
Expand Down Expand Up @@ -224,6 +226,7 @@ type VideoCardWrapperProps = {
mediaUrls: string[]
thumbnailUrls: string[]
goNextSlide: () => void
to?: string
details: ReactNode
}

Expand All @@ -233,28 +236,33 @@ export const VideoCardWrapper = ({
thumbnailUrls,
mediaUrls,
videoId,
to,
details,
}: VideoCardWrapperProps) => {
const [isPaused, setIsPaused] = useState(!active)
const debouncedActive = useDebounceValue(active, 500)
const debouncedActive = useDebounceValue(active, 800, true)

return (
<Container>
<Link to={to ? to : absoluteRoutes.viewer.video(videoId)}>
<LinkArea />
</Link>
<VideoContainer>
{active ? (
<BackgroundVideoPlayer
videoId={videoId}
withFade={active ? debouncedActive : active}
playing={active ? debouncedActive : active}
withFade={active ? !!debouncedActive : active}
playing={active ? !!debouncedActive : active}
muted={true}
onPause={() => setIsPaused(true)}
onPlay={() => setIsPaused(false)}
preload="auto"
src={mediaUrls ?? undefined}
poster={thumbnailUrls ?? undefined}
handleActions={active ? debouncedActive : active}
handleActions={active ? !!debouncedActive : active}
videoPlaytime={30}
onEnded={goNextSlide}
customLink={to}
/>
) : (
<VideoWrapper>
Expand Down
22 changes: 21 additions & 1 deletion packages/atlas/src/components/Table/Table.styles.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { css } from '@emotion/react'
import styled from '@emotion/styled'
import { Link } from 'react-router-dom'

import { Pagination } from '@/components/Pagination'
import { Text } from '@/components/Text'
import { cVar, sizes } from '@/styles'

export const Wrapper = styled.div`
export const Wrapper = styled.div<{ interactive?: boolean }>`
background-color: ${cVar('colorBackgroundMuted')};
overflow: auto;
Expand All @@ -14,6 +15,25 @@ export const Wrapper = styled.div`
cursor: pointer;
}
}
${(props) =>
props.interactive
? css`
.table-row {
transition: background-color 300ms ease-in-out;
border-radius: ${cVar('radiusMedium')};
:hover {
cursor: pointer;
background: ${cVar('colorBackgroundMutedAlpha')};
}
}
`
: ''}
`

export const AnchorRow = styled(Link)`
text-decoration: none;
`

export const TableBase = styled.table`
Expand Down
46 changes: 34 additions & 12 deletions packages/atlas/src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Text } from '@/components/Text'
import { useMediaMatch } from '@/hooks/useMediaMatch'

import {
AnchorRow,
EmptyTableContainer,
EmptyTableDescription,
EmptyTableHeader,
Expand All @@ -22,6 +23,7 @@ import {
export type TableProps<T = object> = {
columns: Column[]
onRowClick?: (rowIdx: number) => void
getRowTo?: (rowIdx: number) => string
data: T[]
title?: string
pageSize?: number
Expand All @@ -31,6 +33,7 @@ export type TableProps<T = object> = {
description: string
icon: ReactElement
}
interactive?: boolean
className?: string
pagination?: TablePaginationProps
minWidth?: number
Expand All @@ -46,6 +49,8 @@ export const Table = <T extends object>({
onRowClick,
className,
pagination,
interactive,
getRowTo,
minWidth = 300,
}: TableProps<T>) => {
const scrollRef = useRef<HTMLDivElement>(null)
Expand Down Expand Up @@ -74,7 +79,7 @@ export const Table = <T extends object>({

const mdMatch = useMediaMatch('md')
return (
<Wrapper className={className}>
<Wrapper interactive={interactive} className={className}>
{title && (
<Text
as="h3"
Expand Down Expand Up @@ -109,24 +114,41 @@ export const Table = <T extends object>({
<tbody {...getTableBodyProps()}>
{subpage.map((row, idx) => {
prepareRow(row)
const rowTo = getRowTo ? getRowTo(idx) : undefined
const mappedCells = row.cells.map((cell) => (
<Td
variant="t100"
as="td"
{...cell.getCellProps()}
key={cell.getCellProps().key}
className="table-cell"
>
{cell.render('Cell')}
</Td>
))

if (rowTo) {
return (
<AnchorRow
className="table-row"
{...row.getRowProps()}
onClick={() => onRowClick?.(idx)}
key={row.getRowProps().key}
to={rowTo}
>
{mappedCells}
</AnchorRow>
)
}

return (
<tr
className="table-row"
{...row.getRowProps()}
onClick={() => onRowClick?.(idx)}
key={row.getRowProps().key}
>
{row.cells.map((cell) => (
<Td
variant="t100"
as="td"
{...cell.getCellProps()}
key={cell.getCellProps().key}
className="table-cell"
>
{cell.render('Cell')}
</Td>
))}
{mappedCells}
</tr>
)
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const COLUMNS: TableProps['columns'] = [
width: 9,
},
{
Header: () => <RightAlignedHeader>REVENUE VOLUME</RightAlignedHeader>,
Header: () => <RightAlignedHeader>REVENUE</RightAlignedHeader>,
accessor: 'salesVolume',
width: 4,
},
Expand All @@ -61,7 +61,7 @@ export const TopEarningChannels = ({ withCrtOnly }: { withCrtOnly?: boolean }) =
})

const lgMatch = useMediaMatch('lg')
const mappedData: TableProps['data'] = useMemo(() => {
const mappedData = useMemo(() => {
return loading
? Array.from({ length: 10 }, () => ({
index: null,
Expand All @@ -72,6 +72,7 @@ export const TopEarningChannels = ({ withCrtOnly }: { withCrtOnly?: boolean }) =
</SkeletonChannelContainer>
),
salesVolume: <SkeletonLoader width="100%" height={16} />,
channelId: null,
}))
: channels?.map((data, index) => ({
index: (
Expand All @@ -94,6 +95,7 @@ export const TopEarningChannels = ({ withCrtOnly }: { withCrtOnly?: boolean }) =
</JoyAmountWrapper>
),
channel: <Channel channel={data} />,
channelId: data.id,
})) ?? []
}, [channels, loading])

Expand Down Expand Up @@ -124,6 +126,10 @@ export const TopEarningChannels = ({ withCrtOnly }: { withCrtOnly?: boolean }) =
columns={COLUMNS}
data={mappedData}
doubleColumn={lgMatch}
getRowTo={(idx) =>
absoluteRoutes.viewer.channel(mappedData[idx].channelId ?? '', { tab: withCrtOnly ? 'Token' : 'Videos' })
}
interactive
/>,
],
}}
Expand Down
Loading

0 comments on commit 7ca3202

Please sign in to comment.