Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/common/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ export * from './tan-query/events'

// Explore
export * from './tan-query/collection/useExploreContent'
export * from './tan-query/collection/useTrendingAlbums'
export * from './tan-query/collection/useNewAlbumReleases'
export * from './tan-query/collection/useBestSellingAlbums'

// Lineups
export * from './tan-query/lineups/useFeed'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { HashId } from '@audius/sdk'
import { useQuery } from '@tanstack/react-query'

import { useQueryContext } from '~/api/tan-query/utils'
import { ID } from '~/models'

import { QUERY_KEYS } from '../queryKeys'
import { QueryKey, QueryOptions } from '../types'
import { entityCacheOptions } from '../utils/entityCacheOptions'

import { useCollections } from './useCollections'

type UseBestSellingAlbumsArgs = {
limit?: number
}

export const getBestSellingAlbumsQueryKey = (
args: UseBestSellingAlbumsArgs
) => {
const { limit = 10 } = args
return [QUERY_KEYS.bestSellingAlbums, { limit }] as unknown as QueryKey<ID[]>
}

export const useBestSellingAlbums = (
args: UseBestSellingAlbumsArgs = {},
options?: QueryOptions
) => {
const { limit = 10 } = args
const { audiusSdk } = useQueryContext()

const idQuery = useQuery({
queryKey: getBestSellingAlbumsQueryKey({ limit }),
queryFn: async (): Promise<ID[]> => {
const sdk = await audiusSdk()
const { data = [] } = await sdk.explore.getBestSelling({
limit,
type: 'album'
})
return data
.map((item) => HashId.parse(item.contentId))
.filter((id): id is ID => !!id && id > 0)
},
...options,
...entityCacheOptions,
enabled: options?.enabled !== false
})

const {
data: collections,
isPending: isCollectionsPending,
isLoading: isCollectionsLoading
} = useCollections(idQuery.data)

const hasPendingCollections =
(idQuery.data?.length ?? 0) > 0 && isCollectionsPending

return {
data: collections,
ids: idQuery.data,
isPending: idQuery.isPending || hasPendingCollections,
isLoading:
idQuery.isLoading || (hasPendingCollections && isCollectionsLoading),
isError: idQuery.isError,
isSuccess: idQuery.isSuccess
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { useQuery, useQueryClient } from '@tanstack/react-query'

import { userCollectionMetadataFromSDK } from '~/adapters/collection'
import { transformAndCleanList } from '~/adapters/utils'
import { useQueryContext } from '~/api/tan-query/utils'
import { ID } from '~/models'

import { QUERY_KEYS } from '../queryKeys'
import { QueryKey, QueryOptions } from '../types'
import { entityCacheOptions } from '../utils/entityCacheOptions'
import { primeCollectionData } from '../utils/primeCollectionData'

import { useCollections } from './useCollections'

type UseNewAlbumReleasesArgs = {
limit?: number
}

export const getNewAlbumReleasesQueryKey = (args: UseNewAlbumReleasesArgs) => {
const { limit = 10 } = args
return [QUERY_KEYS.newReleaseAlbums, { limit }] as unknown as QueryKey<ID[]>
}

export const useNewAlbumReleases = (
args: UseNewAlbumReleasesArgs = {},
options?: QueryOptions
) => {
const { limit = 10 } = args
const { audiusSdk } = useQueryContext()
const queryClient = useQueryClient()

const idQuery = useQuery({
queryKey: getNewAlbumReleasesQueryKey({ limit }),
queryFn: async (): Promise<ID[]> => {
const sdk = await audiusSdk()
const { data = [] } = await sdk.playlists.getPlaylistsNewReleases({
limit,
type: 'album'
})
const collections = transformAndCleanList(
data,
userCollectionMetadataFromSDK
)
primeCollectionData({ collections, queryClient })
return collections.map((c) => c.playlist_id)
},
...options,
...entityCacheOptions,
enabled: options?.enabled !== false
})

const {
data: collections,
isPending: isCollectionsPending,
isLoading: isCollectionsLoading
} = useCollections(idQuery.data)

const hasPendingCollections =
(idQuery.data?.length ?? 0) > 0 && isCollectionsPending

return {
data: collections,
ids: idQuery.data,
isPending: idQuery.isPending || hasPendingCollections,
isLoading:
idQuery.isLoading || (hasPendingCollections && isCollectionsLoading),
isError: idQuery.isError,
isSuccess: idQuery.isSuccess
}
}
78 changes: 78 additions & 0 deletions packages/common/src/api/tan-query/collection/useTrendingAlbums.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { OptionalId } from '@audius/sdk'
import { useQuery, useQueryClient } from '@tanstack/react-query'

import { userCollectionMetadataFromSDK } from '~/adapters/collection'
import { transformAndCleanList } from '~/adapters/utils'
import { useQueryContext } from '~/api/tan-query/utils'
import { ID } from '~/models'

import { QUERY_KEYS } from '../queryKeys'
import { QueryKey, QueryOptions } from '../types'
import { useCurrentUserId } from '../users/account/useCurrentUserId'
import { entityCacheOptions } from '../utils/entityCacheOptions'
import { primeCollectionData } from '../utils/primeCollectionData'

import { useCollections } from './useCollections'

type UseTrendingAlbumsArgs = {
time?: 'week' | 'month' | 'year' | 'allTime'
limit?: number
}

export const getTrendingAlbumsQueryKey = (args: UseTrendingAlbumsArgs) => {
const { time = 'month', limit = 10 } = args
return [QUERY_KEYS.trendingAlbums, { time, limit }] as unknown as QueryKey<
ID[]
>
}

export const useTrendingAlbums = (
args: UseTrendingAlbumsArgs = {},
options?: QueryOptions
) => {
const { time = 'month', limit = 10 } = args
const { audiusSdk } = useQueryContext()
const { data: currentUserId } = useCurrentUserId()
const queryClient = useQueryClient()

const idQuery = useQuery({
queryKey: getTrendingAlbumsQueryKey({ time, limit }),
queryFn: async (): Promise<ID[]> => {
const sdk = await audiusSdk()
const { data = [] } = await sdk.playlists.getTrendingPlaylists({
time,
limit,
type: 'album',
userId: OptionalId.parse(currentUserId)
})
const collections = transformAndCleanList(
data,
userCollectionMetadataFromSDK
)
primeCollectionData({ collections, queryClient })
return collections.map((c) => c.playlist_id)
},
...options,
...entityCacheOptions,
enabled: options?.enabled !== false
})

const {
data: collections,
isPending: isCollectionsPending,
isLoading: isCollectionsLoading
} = useCollections(idQuery.data)

const hasPendingCollections =
(idQuery.data?.length ?? 0) > 0 && isCollectionsPending

return {
data: collections,
ids: idQuery.data,
isPending: idQuery.isPending || hasPendingCollections,
isLoading:
idQuery.isLoading || (hasPendingCollections && isCollectionsLoading),
isError: idQuery.isError,
isSuccess: idQuery.isSuccess
}
}
3 changes: 3 additions & 0 deletions packages/common/src/api/tan-query/queryKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ export const QUERY_KEYS = {
trendingIds: 'trendingIds',
trendingUnderground: 'trendingUnderground',
trendingWinners: 'trendingWinners',
trendingAlbums: 'trendingAlbums',
newReleaseAlbums: 'newReleaseAlbums',
bestSellingAlbums: 'bestSellingAlbums',
trackPageLineup: 'trackPageLineup',
connectedWallets: 'connectedWallets',
audioBalance: 'audioBalance',
Expand Down
3 changes: 3 additions & 0 deletions packages/common/src/messages/explore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export const exploreMessages = {
forYou: 'For You',
recentlyListedForSale: 'Recently Listed for Sale',
bestSelling: 'Best Selling',
topAlbumsThisMonth: 'Top Albums This Month',
newAlbumReleases: 'New Album Releases',
bestSellingAlbums: 'Best Selling Albums',
exploreByMood: (category?: string) =>
`Explore${category ? ` ${category}` : ''} by Mood`,
quickSearch: 'Quick Search',
Expand Down
3 changes: 3 additions & 0 deletions packages/common/src/models/Analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1590,6 +1590,9 @@ export type ExploreSectionName =
| 'Mood Grid'
| 'Most Shared'
| 'Best Selling'
| 'Best Selling Albums'
| 'Top Albums This Month'
| 'New Album Releases'
| 'Recent Premium Tracks'
| 'Feeling Lucky'
| 'Recent Searches'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react'

import { useBestSellingAlbums } from '@audius/common/api'
import { exploreMessages as messages } from '@audius/common/messages'

import { useTheme } from '@audius/harmony-native'
import { CollectionList } from 'app/components/collection-list'

import { useExploreSectionTracking } from '../hooks/useExploreSectionTracking'

import { ExploreSection } from './ExploreSection'

export const BestSellingAlbums = () => {
const { spacing } = useTheme()
const { InViewWrapper, inView } = useExploreSectionTracking(
'Best Selling Albums'
)

const { ids, isError, isSuccess } = useBestSellingAlbums(
{ limit: 10 },
{ enabled: inView }
)

if (isError || (isSuccess && !ids?.length)) {
return null
}

return (
<InViewWrapper>
<ExploreSection title={messages.bestSellingAlbums}>
<CollectionList
horizontal
collectionIds={ids}
carouselSpacing={spacing.l}
/>
</ExploreSection>
</InViewWrapper>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import { RecentSearches } from 'app/screens/search-screen/RecentSearches'
import { useSearchCategory } from 'app/screens/search-screen/searchState'

import { ArtistSpotlight } from './ArtistSpotlight'
import { BestSellingAlbums } from './BestSellingAlbums'
import { FeaturedPlaylists } from './FeaturedPlaylists'
import { FeaturedRemixContests } from './FeaturedRemixContests'
import { FeelingLucky } from './FeelingLucky'
import { ForYouTracks } from './ForYouTracks'
import { LabelSpotlight } from './LabelSpotlight'
import { NewAlbumReleases } from './NewAlbumReleases'
import { RecentlyPlayedTracks } from './RecentlyPlayed'
import { TopAlbumsThisMonth } from './TopAlbumsThisMonth'

export const ExploreContent = () => {
const [category] = useSearchCategory()
Expand All @@ -22,12 +25,16 @@ export const ExploreContent = () => {
const showUserContextualContent = isCurrentUserIdLoading || !!currentUserId
const showTrackContent = category === 'tracks' || category === 'all'
const showPlaylistContent = category === 'playlists' || category === 'all'
const showAlbumContent = category === 'albums' || category === 'all'
const showUserContent = category === 'users' || category === 'all'

return (
<Flex gap='2xl' pt='s' pb={150} ph='l'>
{showTrackContent && showUserContextualContent && <ForYouTracks />}
{showPlaylistContent && <FeaturedPlaylists />}
{showAlbumContent && <TopAlbumsThisMonth />}
{showAlbumContent && <NewAlbumReleases />}
{showAlbumContent && <BestSellingAlbums />}
{showTrackContent && <FeaturedRemixContests />}
{showTrackContent && showUserContextualContent && (
<RecentlyPlayedTracks />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react'

import { useNewAlbumReleases } from '@audius/common/api'
import { exploreMessages as messages } from '@audius/common/messages'

import { useTheme } from '@audius/harmony-native'
import { CollectionList } from 'app/components/collection-list'

import { useExploreSectionTracking } from '../hooks/useExploreSectionTracking'

import { ExploreSection } from './ExploreSection'

export const NewAlbumReleases = () => {
const { spacing } = useTheme()
const { InViewWrapper, inView } =
useExploreSectionTracking('New Album Releases')

const { ids, isError, isSuccess } = useNewAlbumReleases(
{ limit: 10 },
{ enabled: inView }
)

if (isError || (isSuccess && !ids?.length)) {
return null
}

return (
<InViewWrapper>
<ExploreSection title={messages.newAlbumReleases}>
<CollectionList
horizontal
collectionIds={ids}
carouselSpacing={spacing.l}
/>
</ExploreSection>
</InViewWrapper>
)
}
Loading
Loading