|
1 | | -import { useRemixContest } from '@audius/common/api' |
| 1 | +import type { LineupData } from '@audius/common/api' |
| 2 | +import { useRemixes, useTrack, useUser } from '@audius/common/api' |
2 | 3 | import type { ID } from '@audius/common/models' |
3 | 4 |
|
4 | | -import { Flex, Text } from '@audius/harmony-native' |
| 5 | +import { |
| 6 | + Artwork, |
| 7 | + Box, |
| 8 | + Flex, |
| 9 | + IconArrowRight, |
| 10 | + PlainButton, |
| 11 | + Skeleton, |
| 12 | + Text |
| 13 | +} from '@audius/harmony-native' |
| 14 | +import { TrackLink } from 'app/components/track/TrackLink' |
| 15 | +import { TrackFlair, Size } from 'app/components/track-flair' |
| 16 | +import { UserLink } from 'app/components/user-link' |
| 17 | +import { useNavigation } from 'app/hooks/useNavigation' |
5 | 18 |
|
6 | | -type Props = { |
| 19 | +const artworkSize = 120 |
| 20 | +const userAvatarSize = 40 |
| 21 | + |
| 22 | +const messages = { |
| 23 | + noSubmissions: 'No submissions yet', |
| 24 | + beFirst: 'Be the first to upload a remix!', |
| 25 | + viewAll: 'View All' |
| 26 | +} |
| 27 | + |
| 28 | +type RemixContestSubmissionsTabProps = { |
7 | 29 | trackId: ID |
8 | 30 | } |
9 | 31 |
|
10 | 32 | /** |
11 | 33 | * Tab content displaying submissions for a remix contest |
12 | 34 | */ |
13 | | -export const RemixContestSubmissionsTab = ({ trackId }: Props) => { |
14 | | - const { data: remixContest } = useRemixContest(trackId) |
| 35 | +export const RemixContestSubmissionsTab = ({ |
| 36 | + trackId |
| 37 | +}: RemixContestSubmissionsTabProps) => { |
| 38 | + const { data: remixes } = useRemixes({ trackId, isContestEntry: true }) |
| 39 | + const submissions = remixes?.slice(0, 6) |
15 | 40 |
|
16 | | - if (!remixContest) return null |
| 41 | + // If there are no submissions, show the empty state |
| 42 | + if (submissions.length === 0) { |
| 43 | + return <EmptyRemixContestSubmissions /> |
| 44 | + } |
| 45 | + |
| 46 | + return <RemixContestSubmissions trackId={trackId} submissions={submissions} /> |
| 47 | +} |
| 48 | + |
| 49 | +const SubmissionCard = ({ submission }: { submission: LineupData }) => { |
| 50 | + const { data: track, isLoading: trackLoading } = useTrack(submission.id) |
| 51 | + const { data: user, isLoading: userLoading } = useUser(track?.owner_id) |
| 52 | + const isLoading = trackLoading || userLoading |
| 53 | + const displaySkeleton = isLoading || !track || !user |
| 54 | + |
| 55 | + return ( |
| 56 | + <Flex column gap='s'> |
| 57 | + <Flex h={artworkSize} w={artworkSize}> |
| 58 | + {displaySkeleton ? ( |
| 59 | + <Skeleton /> |
| 60 | + ) : ( |
| 61 | + <> |
| 62 | + <TrackFlair |
| 63 | + style={{ |
| 64 | + height: '100%', |
| 65 | + width: '100%', |
| 66 | + borderRadius: 4, |
| 67 | + overflow: 'hidden' |
| 68 | + }} |
| 69 | + trackId={track.track_id} |
| 70 | + size={Size.SMALL} |
| 71 | + > |
| 72 | + <Artwork source={{ uri: track.artwork['150x150'] }} /> |
| 73 | + </TrackFlair> |
| 74 | + <Box |
| 75 | + h={userAvatarSize} |
| 76 | + w={userAvatarSize} |
| 77 | + borderRadius='circle' |
| 78 | + style={{ |
| 79 | + position: 'absolute', |
| 80 | + top: -8, |
| 81 | + right: -8, |
| 82 | + overflow: 'hidden' |
| 83 | + }} |
| 84 | + > |
| 85 | + <Artwork source={{ uri: user.profile_picture['150x150'] }} /> |
| 86 | + </Box> |
| 87 | + </> |
| 88 | + )} |
| 89 | + </Flex> |
| 90 | + <Flex column gap='xs' alignItems='center'> |
| 91 | + {displaySkeleton ? ( |
| 92 | + <> |
| 93 | + <Box h={20} w={100}> |
| 94 | + <Skeleton /> |
| 95 | + </Box> |
| 96 | + <Box h={20} w={64}> |
| 97 | + <Skeleton /> |
| 98 | + </Box> |
| 99 | + </> |
| 100 | + ) : ( |
| 101 | + <> |
| 102 | + <TrackLink textVariant='title' size='s' trackId={track.track_id} /> |
| 103 | + <UserLink userId={user.user_id} size='s' /> |
| 104 | + </> |
| 105 | + )} |
| 106 | + </Flex> |
| 107 | + </Flex> |
| 108 | + ) |
| 109 | +} |
| 110 | +const RemixContestSubmissions = ({ |
| 111 | + trackId, |
| 112 | + submissions |
| 113 | +}: { |
| 114 | + trackId: ID |
| 115 | + submissions: LineupData[] |
| 116 | +}) => { |
| 117 | + const navigation = useNavigation() |
| 118 | + |
| 119 | + return ( |
| 120 | + <Flex w='100%' column gap='2xl' pv='xl' ph='l' borderTop='default'> |
| 121 | + <Flex gap='2xl' wrap='wrap'> |
| 122 | + {submissions.map((submission) => ( |
| 123 | + <SubmissionCard key={submission.id} submission={submission} /> |
| 124 | + ))} |
| 125 | + </Flex> |
| 126 | + <Flex justifyContent='center'> |
| 127 | + <PlainButton |
| 128 | + iconRight={IconArrowRight} |
| 129 | + onPress={() => { |
| 130 | + navigation.navigate('TrackRemixes', { trackId }) |
| 131 | + }} |
| 132 | + > |
| 133 | + {messages.viewAll} |
| 134 | + </PlainButton> |
| 135 | + </Flex> |
| 136 | + </Flex> |
| 137 | + ) |
| 138 | +} |
17 | 139 |
|
| 140 | +const EmptyRemixContestSubmissions = () => { |
18 | 141 | return ( |
19 | | - <Flex p='xl' borderTop='default'> |
20 | | - <Text variant='body' size='l'> |
21 | | - {/* TODO: Implement submissions content */} |
| 142 | + <Flex |
| 143 | + column |
| 144 | + w='100%' |
| 145 | + pv='2xl' |
| 146 | + gap='s' |
| 147 | + justifyContent='center' |
| 148 | + alignItems='center' |
| 149 | + > |
| 150 | + <Text variant='title'>{messages.noSubmissions}</Text> |
| 151 | + <Text variant='body' color='subdued'> |
| 152 | + {messages.beFirst} |
22 | 153 | </Text> |
23 | 154 | </Flex> |
24 | 155 | ) |
|
0 commit comments