Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃憮 CRTs UI fixes #6236

Merged
merged 8 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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