Skip to content
63 changes: 62 additions & 1 deletion packages/common/src/adapters/track.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
StemCategory,
TrackSegment
} from '~/models'
import { UserTrackMetadata } from '~/models/Track'
import { StemTrackMetadata, UserTrackMetadata } from '~/models/Track'
import { License } from '~/utils'
import { decodeHashId } from '~/utils/hashIds'

Expand Down Expand Up @@ -151,3 +151,64 @@ export const userTrackMetadataFromSDK = (

return newTrack
}

export const stemTrackMetadataFromSDK = (

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @raymondjacobson I know you have a PR to add the public stems endpoint. I had to write this adapter for our existing usage of the full version. I'm not entirely sure why we need to represent a stem as a full track with mostly null fields (upload validation?). But you'll probably want this to process the response.

input: full.StemFull
): StemTrackMetadata | undefined => {
const [id, parentId, ownerId] = [input.id, input.parentId, input.userId].map(
decodeHashId
)
if (!(id && parentId && ownerId)) return undefined

return {
blocknumber: input.blocknumber,
is_delete: false,
track_id: id,
created_at: '',
isrc: null,
iswc: null,
credits_splits: null,
create_date: null,
description: null,
followee_reposts: [],
followee_saves: [],
genre: '',
has_current_user_reposted: false,
has_current_user_saved: false,
license: null,
mood: null,
play_count: 0,
owner_id: ownerId,
release_date: null,
repost_count: 0,
save_count: 0,
tags: null,
title: '',
track_segments: [],
cover_art: null,
cover_art_sizes: null,
cover_art_cids: null,
is_scheduled_release: false,
is_unlisted: false,
stem_of: {
parent_track_id: parentId,
category: input.category as StemCategory
},
remix_of: null,
duration: 0,
updated_at: '',
permalink: '',
is_available: true,
is_stream_gated: false,
stream_conditions: null,
is_download_gated: false,
download_conditions: null,
access: { stream: true, download: true },
track_cid: input.cid,
orig_file_cid: '',
orig_filename: input.origFilename,
is_downloadable: true,
is_original_available: false,
is_playlist_upload: false
}
}
25 changes: 16 additions & 9 deletions packages/common/src/api/track.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { full } from '@audius/sdk'

import { transformAndCleanList, userTrackMetadataFromSDK } from '~/adapters'
import { createApi } from '~/audius-query'
import { ID, Id, Kind, OptionalId } from '~/models'
import { Nullable } from '~/utils/typeUtils'

import { SDKRequest } from './types'

const trackApi = createApi({
reducerPath: 'trackApi',
endpoints: {
Expand Down Expand Up @@ -84,18 +88,21 @@ const trackApi = createApi({
getUserTracksByHandle: {
fetch: async (
{
handle,
currentUserId,
limit
}: { handle: string; currentUserId: Nullable<ID>; limit?: number },
{ apiClient }
filterTracks = 'public',
sort = 'date',
...params
}: SDKRequest<full.GetTracksByUserHandleRequest>,
{ audiusSdk }
) => {
return await apiClient.getUserTracksByHandle({
handle,
currentUserId,
getUnlisted: false,
limit
const sdk = await audiusSdk()
const { data = [] } = await sdk.full.users.getTracksByUserHandle({
...params,
userId: OptionalId.parse(currentUserId),
sort,
filterTracks
})
return transformAndCleanList(data, userTrackMetadataFromSDK)
},
options: {
idListArgKey: 'ids',
Expand Down
10 changes: 10 additions & 0 deletions packages/common/src/api/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ID } from '~/models'

/** Helper type for accepting args to a SDK method. It strips out the signature
* parameters (which are passed by SDK middleware) and adds the common
* `currentUserId` parameter that most functions calling SDK methods will convert
* and pass along. */
export type SDKRequest<T> = Omit<
T,
'encodedDataMessage' | 'encodedDataSignature'
> & { currentUserId?: ID | null }
28 changes: 16 additions & 12 deletions packages/common/src/api/user.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { full } from '@audius/sdk'

import { transformAndCleanList, userTrackMetadataFromSDK } from '~/adapters'
import { userMetadataListFromSDK } from '~/adapters/user'
import { createApi } from '~/audius-query'
import { ID, Kind, OptionalId, StringUSDC } from '~/models'
Expand All @@ -10,6 +11,7 @@ import {
} from '~/models/USDCTransactions'
import { Nullable } from '~/utils/typeUtils'

import { SDKRequest } from './types'
import { Id } from './utils'

type GetUSDCTransactionListArgs = {
Expand Down Expand Up @@ -103,20 +105,22 @@ const userApi = createApi({
},
getTracksByUser: {
fetch: async (
{ userId, currentUserId }: { userId: ID; currentUserId: Nullable<ID> },
audiusQueryContext
) => {
const { apiClient } = audiusQueryContext
const { handle } = await userApiFetch.getUserById(
{ id: userId, currentUserId },
audiusQueryContext
)
const tracks = await apiClient.getUserTracksByHandle({
handle,
{
id,
currentUserId,
getUnlisted: userId === currentUserId
...params
}: {
id: ID
} & SDKRequest<full.GetTracksByUserRequest>,
{ audiusSdk }
) => {
const sdk = await audiusSdk()
const { data = [] } = await sdk.full.users.getTracksByUser({
...params,
id: Id.parse(id),
userId: OptionalId.parse(currentUserId)
})
return tracks
return transformAndCleanList(data, userTrackMetadataFromSDK)
},
options: {
kind: Kind.TRACKS,
Expand Down
Loading