Skip to content

Commit 05720e3

Browse files
authored
[C-4891] Add artist pick to mobile (#9359)
1 parent 932ddc7 commit 05720e3

File tree

13 files changed

+124
-46
lines changed

13 files changed

+124
-46
lines changed

packages/common/src/api/account.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { managedUserListFromSDK, userManagerListFromSDK } from '~/adapters/user'
44
import { createApi } from '~/audius-query'
55
import { ID, User, UserMetadata } from '~/models'
66

7+
import { useGetUserById } from './user'
78
import { Id } from './utils'
89

910
type ResetPasswordArgs = {
@@ -248,6 +249,11 @@ const accountApi = createApi({
248249
}
249250
})
250251

252+
export const useGetCurrentUser = () => {
253+
const { data: userId } = accountApi.hooks.useGetCurrentUserId({})
254+
return useGetUserById({ id: userId! })
255+
}
256+
251257
export const {
252258
useGetCurrentUserId,
253259
useGetCurrentWeb3User,

packages/common/src/store/ui/mobile-overflow-menu/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ export enum OverflowAction {
3030
MARK_AS_PLAYED = 'MARK_AS_PLAYED',
3131
MARK_AS_UNPLAYED = 'MARK_AS_UNPLAYED',
3232
RELEASE_NOW = 'RELEASE_NOW',
33-
PURCHASE_TRACK = 'PURCHASE_TRACK'
33+
PURCHASE_TRACK = 'PURCHASE_TRACK',
34+
SET_ARTIST_PICK = 'SET_ARTIST_PICk',
35+
UNSET_ARTIST_PICK = 'UNSET_ARTIST_PICK'
3436
}
3537

3638
export enum OverflowSource {

packages/mobile/src/app/Drawers.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { CreateChatActionsDrawer } from 'app/components/create-chat-actions-draw
1717
import { DeactivateAccountConfirmationDrawer } from 'app/components/deactivate-account-confirmation-drawer'
1818
import { DeleteChatDrawer } from 'app/components/delete-chat-drawer'
1919
import { DeletePlaylistConfirmationDrawer } from 'app/components/delete-playlist-confirmation-drawer'
20+
import { ArtistPickConfirmationDrawer } from 'app/components/drawers/ArtistPickConfirmationDrawer'
2021
import { DuplicateAddConfirmationDrawer } from 'app/components/duplicate-add-confirmation-drawer'
2122
import { EditCollectiblesDrawer } from 'app/components/edit-collectibles-drawer'
2223
import { EnablePushNotificationsDrawer } from 'app/components/enable-push-notifications-drawer'
@@ -125,7 +126,8 @@ const commonDrawersMap: { [Modal in Modals]?: ComponentType } = {
125126
CoinflowOnramp: CoinflowOnrampDrawer,
126127
InboxUnavailableModal: InboxUnavailableDrawer,
127128
LeavingAudiusModal: LeavingAudiusDrawer,
128-
WaitForDownloadModal: WaitForDownloadDrawer
129+
WaitForDownloadModal: WaitForDownloadDrawer,
130+
ArtistPick: ArtistPickConfirmationDrawer
129131
}
130132

131133
const nativeDrawersMap: { [DrawerName in Drawer]?: ComponentType } = {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { useCallback, useMemo } from 'react'
2+
3+
import { useGetCurrentUser } from '@audius/common/api'
4+
import { tracksSocialActions, useArtistPickModal } from '@audius/common/store'
5+
import { useDispatch } from 'react-redux'
6+
7+
import { ConfirmationDrawer } from './ConfirmationDrawer'
8+
9+
const messages = {
10+
add: {
11+
header: 'Set your Artist Pick',
12+
description:
13+
'This track will appear at the top of your profile, above your recent uploads, until you change or remove it.',
14+
confirm: 'Set Track'
15+
},
16+
update: {
17+
header: 'Change your Artist Pick?',
18+
description:
19+
'This track will appear at the top of your profile and replace your previously picked track.',
20+
confirm: 'Change Track'
21+
},
22+
remove: {
23+
header: 'Unset as Artist Pick',
24+
description:
25+
'Are you sure you want to remove your pick? This track will be displayed based on its release date.',
26+
confirm: 'Unset Track'
27+
}
28+
}
29+
30+
const { setArtistPick, unsetArtistPick } = tracksSocialActions
31+
32+
export const ArtistPickConfirmationDrawer = () => {
33+
const { data } = useArtistPickModal()
34+
const { trackId } = data
35+
const { data: user } = useGetCurrentUser()
36+
37+
const dispatch = useDispatch()
38+
39+
const action = useMemo(
40+
() => (!user?.artist_pick_track_id ? 'add' : trackId ? 'update' : 'remove'),
41+
// We don't want optimistic update, otherwise the text changes as the drawer is closing
42+
// eslint-disable-next-line react-hooks/exhaustive-deps
43+
[trackId]
44+
)
45+
46+
const handleConfirm = useCallback(() => {
47+
if (trackId) {
48+
dispatch(setArtistPick(trackId))
49+
} else {
50+
dispatch(unsetArtistPick())
51+
}
52+
}, [dispatch, trackId])
53+
54+
return (
55+
<ConfirmationDrawer
56+
variant={action === 'remove' ? 'destructive' : 'affirmative'}
57+
modalName='ArtistPick'
58+
messages={messages[action]}
59+
onConfirm={handleConfirm}
60+
/>
61+
)
62+
}

packages/mobile/src/components/drawers/ConfirmationDrawer.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ const ConfirmationDrawerContent = (props: DrawerContentProps) => {
8888
{messages.header}
8989
</Text>
9090
</Flex>
91-
<Text size='l'>{messages.description}</Text>
91+
<Text size='l' textAlign='center'>
92+
{messages.description}
93+
</Text>
9294
<Flex gap='l'>
9395
<Button
9496
variant={variant === 'destructive' ? 'destructive' : 'primary'}

packages/mobile/src/components/lineup-tile/LineupTileStats.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,16 +215,16 @@ export const LineupTileStats = ({
215215
/>
216216
) : null
217217
) : null}
218-
{isUnlisted && !isScheduledRelease ? (
219-
<LineupTileLabel icon={IconVisibilityHidden}>
220-
{messages.hidden}
221-
</LineupTileLabel>
222-
) : null}
223218
{isUnlisted && isScheduledRelease && releaseDate ? (
224219
<LineupTileLabel icon={IconCalendarMonth} color='accent'>
225220
{messages.releases(releaseDate)}
226221
</LineupTileLabel>
227222
) : null}
223+
{isUnlisted && !isScheduledRelease ? (
224+
<LineupTileLabel icon={IconVisibilityHidden}>
225+
{messages.hidden}
226+
</LineupTileLabel>
227+
) : null}
228228
<View style={styles.leftStats}>
229229
{hasEngagement && !isUnlisted ? (
230230
<>

packages/mobile/src/components/lineup-tile/TrackTile.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ export const TrackTileComponent = ({
116116
is_unlisted: isUnlisted
117117
} = track
118118

119+
const { artist_pick_track_id } = user
120+
const isArtistPick = isOwner && artist_pick_track_id === track_id
121+
119122
const hasPreview =
120123
isUSDCEnabled &&
121124
isContentUSDCPurchaseGated(streamConditions) &&
@@ -169,6 +172,8 @@ export const TrackTileComponent = ({
169172
? OverflowAction.MARK_AS_UNPLAYED
170173
: OverflowAction.MARK_AS_PLAYED
171174
: null,
175+
isOwner && !isArtistPick ? OverflowAction.SET_ARTIST_PICK : null,
176+
isArtistPick ? OverflowAction.UNSET_ARTIST_PICK : null,
172177
isOnArtistsTracksTab ? null : OverflowAction.VIEW_ARTIST_PAGE,
173178
isOwner && !ddexApp ? OverflowAction.EDIT_TRACK : null,
174179
isOwner && track?.is_scheduled_release && track?.is_unlisted
@@ -192,6 +197,7 @@ export const TrackTileComponent = ({
192197
isUnlisted,
193198
albumInfo,
194199
playbackPositionInfo?.status,
200+
isArtistPick,
195201
isOnArtistsTracksTab,
196202
track?.is_scheduled_release,
197203
track?.is_unlisted,

packages/mobile/src/components/overflow-menu-drawer/OverflowMenuDrawer.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ const overflowRowConfig: Record<OverflowAction, ActionDrawerRow> = {
5252
[OverflowAction.VIEW_EPISODE_PAGE]: { text: 'View Episode Page' },
5353
[OverflowAction.MARK_AS_PLAYED]: { text: 'Mark as Played' },
5454
[OverflowAction.MARK_AS_UNPLAYED]: { text: 'Mark as Unplayed' },
55-
[OverflowAction.PURCHASE_TRACK]: { text: 'Purchase Track' }
55+
[OverflowAction.PURCHASE_TRACK]: { text: 'Purchase Track' },
56+
[OverflowAction.SET_ARTIST_PICK]: { text: 'Set as Artist Pick' },
57+
[OverflowAction.UNSET_ARTIST_PICK]: { text: 'Unset as Artist Pick' }
5658
}
5759

5860
export const OverflowMenuDrawer = () => {

packages/mobile/src/components/overflow-menu-drawer/TrackOverflowMenuDrawer.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import {
2323
OverflowAction,
2424
playbackPositionActions,
2525
PurchaseableContentType,
26-
usePremiumContentPurchaseModal
26+
usePremiumContentPurchaseModal,
27+
artistPickModalActions
2728
} from '@audius/common/store'
2829
import type { CommonState, OverflowActionCallbacks } from '@audius/common/store'
2930
import { useDispatch, useSelector } from 'react-redux'
@@ -98,6 +99,16 @@ const TrackOverflowMenuDrawer = ({ render }: Props) => {
9899
}
99100
}, [track, openPremiumContentPurchaseModal])
100101

102+
const handleSetAsArtistPick = useCallback(() => {
103+
if (track) {
104+
dispatch(artistPickModalActions.open({ trackId: track.track_id }))
105+
}
106+
}, [dispatch, track])
107+
108+
const handleUnsetAsArtistPick = useCallback(() => {
109+
dispatch(artistPickModalActions.open({ trackId: null }))
110+
}, [dispatch])
111+
101112
if (!track || !user) {
102113
return null
103114
}
@@ -197,7 +208,9 @@ const TrackOverflowMenuDrawer = ({ render }: Props) => {
197208
dispatch(clearTrackPosition({ trackId: id, userId: currentUserId }))
198209
toast({ content: messages.markedAsUnplayed })
199210
},
200-
[OverflowAction.PURCHASE_TRACK]: handlePurchasePress
211+
[OverflowAction.PURCHASE_TRACK]: handlePurchasePress,
212+
[OverflowAction.SET_ARTIST_PICK]: handleSetAsArtistPick,
213+
[OverflowAction.UNSET_ARTIST_PICK]: handleUnsetAsArtistPick
201214
}
202215

203216
return render(callbacks)

packages/web/src/components/artist-pick-modal/ArtistPickModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const messagesMap = {
2727
confirm: 'Set Track'
2828
},
2929
update: {
30-
title: 'Change your artist pick?',
30+
title: 'Change your Artist Pick?',
3131
description:
3232
'This track will appear at the top of your profile and replace your previously picked track.',
3333
confirm: 'Change Track'

packages/web/src/components/track/GiantTrackTile.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ export const GiantTrackTile = ({
435435
isArtistPick,
436436
isUnlisted,
437437
includeEmbed: !(isUnlisted || isStreamGated),
438-
includeArtistPick: !isUnlisted,
438+
includeArtistPick: true,
439439
includeAddToAlbum: isOwner && !ddexApp,
440440
extraMenuItems: overflowMenuExtraItems
441441
}
Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
import { formatReleaseDate } from '@audius/common/utils'
2-
import {
3-
Text,
4-
IconCalendarMonth,
5-
Flex,
6-
useTheme,
7-
IconVisibilityHidden
8-
} from '@audius/harmony'
9-
import dayjs from 'dayjs'
2+
import { IconCalendarMonth, IconVisibilityHidden } from '@audius/harmony'
103

114
import { getLocalTimezone } from 'utils/dateUtils'
125

6+
import { LineupTileLabel } from './LineupTileLabel'
7+
138
const messages = {
149
hidden: 'Hidden',
1510
releases: (date: string) =>
@@ -27,34 +22,22 @@ export type VisibilityLabelProps = {
2722

2823
export const VisibilityLabel = (props: VisibilityLabelProps) => {
2924
const { releaseDate, isUnlisted, isScheduledRelease } = props
30-
const { color } = useTheme()
31-
32-
if (
33-
!releaseDate ||
34-
!isUnlisted ||
35-
!isScheduledRelease ||
36-
dayjs(releaseDate).isBefore(dayjs())
37-
) {
38-
return null
25+
26+
if (releaseDate && isUnlisted && isScheduledRelease) {
27+
return (
28+
<LineupTileLabel icon={IconCalendarMonth} color='accent'>
29+
{messages.releases(releaseDate)}
30+
</LineupTileLabel>
31+
)
3932
}
4033

41-
if (isUnlisted && !isScheduledRelease) {
34+
if (isUnlisted) {
4235
return (
43-
<Flex alignItems='center' gap='xs'>
44-
<IconVisibilityHidden size='s' color='subdued' />
45-
<Text variant='body' size='xs' color='subdued'>
46-
{messages.hidden}
47-
</Text>
48-
</Flex>
36+
<LineupTileLabel icon={IconVisibilityHidden} color='subdued'>
37+
{messages.hidden}
38+
</LineupTileLabel>
4939
)
5040
}
5141

52-
return (
53-
<Flex alignItems='center' gap='xs'>
54-
<IconCalendarMonth size='s' fill={color.icon.accent} />
55-
<Text variant='body' size='xs' color='accent'>
56-
{messages.releases(releaseDate)}
57-
</Text>
58-
</Flex>
59-
)
42+
return null
6043
}

packages/web/src/components/track/desktop/ConnectedTrackTile.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ const ConnectedTrackTile = ({
198198
handle,
199199
includeAddToPlaylist: !isUnlisted || isOwner,
200200
includeAddToAlbum: isOwner && !ddexApp,
201-
includeArtistPick: handle === userHandle && !isUnlisted,
201+
includeArtistPick: handle === userHandle,
202202
includeEdit: handle === userHandle,
203203
ddexApp: track?.ddex_app,
204204
includeEmbed: !(isUnlisted || isStreamGated),

0 commit comments

Comments
 (0)