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
42 changes: 42 additions & 0 deletions packages/common/src/models/Analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ export enum Name {
SEARCH_RESULT_SELECT = 'Search: Result Select',
SEARCH_TAB_CLICK = 'Search: Tab Click',

// Explore
EXPLORE_SECTION_VIEW = 'Explore: Section View',
EXPLORE_SECTION_CLICK = 'Explore: Section Click',

// Errors
ERROR_PAGE = 'Error Page',
NOT_FOUND_PAGE = 'Not Found Page',
Expand Down Expand Up @@ -1552,6 +1556,42 @@ type SearchResultSelect = {
kind: 'track' | 'profile' | 'playlist' | 'album'
}

// Explore
export type ExploreSectionName =
| 'Recommended Tracks'
| 'Artist Coin Tracks'
| 'Recently Played'
| 'Quick Search'
| 'Featured Playlists'
| 'Featured Remix Contests'
| 'Underground Trending Tracks'
| 'Artist Spotlight'
| 'Label Spotlight'
| 'Active Discussions'
| 'Downloads Available'
| 'Mood Grid'
| 'Trending Playlists'
| 'Most Shared'
| 'Best Selling'
| 'Recent Premium Tracks'
| 'Feeling Lucky'
| 'Recent Searches'

type ExploreSectionView = {
eventName: Name.EXPLORE_SECTION_VIEW
section: ExploreSectionName
source: 'web' | 'mobile'
}

type ExploreSectionClick = {
eventName: Name.EXPLORE_SECTION_CLICK
section: ExploreSectionName
source: 'web' | 'mobile'
id?: ID
kind?: 'track' | 'profile' | 'playlist' | 'album' | 'mood' | 'preset'
link?: string
}

type ListenGated = {
eventName: Name.LISTEN_GATED
trackId: string
Expand Down Expand Up @@ -3127,6 +3167,8 @@ export type AllTrackingEvents =
| SearchTag
| SearchMoreResults
| SearchResultSelect
| ExploreSectionView
| ExploreSectionClick
| ListenGated
| ErrorPage
| NotFoundPage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { useExploreContent } from '@audius/common/api'
import { exploreMessages as messages } from '@audius/common/messages'
import { QueueSource } from '@audius/common/store'

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

import { ExploreSection } from './ExploreSection'
import { TrackTileCarousel } from './TrackTileCarousel'

export const FeaturedArtistCoinTracks = () => {
const { InViewWrapper, inView } = useDeferredElement()
const { InViewWrapper, inView } =
useExploreSectionTracking('Artist Coin Tracks')
const { data, isPending } = useExploreContent({ enabled: inView })

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import { exploreMessages as messages } from '@audius/common/messages'
import { useTheme } from '@audius/harmony-native'
import { CollectionList } from 'app/components/collection-list'

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

import { ExploreSection } from './ExploreSection'

export const FeaturedPlaylists = () => {
const { spacing } = useTheme()
const { InViewWrapper, inView } = useDeferredElement()
const { InViewWrapper, inView } =
useExploreSectionTracking('Featured Playlists')

const { data: exploreContent } = useExploreContent({ enabled: inView })
const { data: playlists } = useCollections(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { exploreMessages as messages } from '@audius/common/messages'
import { QueueSource } from '@audius/common/store'
import { full } from '@audius/sdk'

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

import { ExploreSection } from './ExploreSection'
import { TrackTileCarousel } from './TrackTileCarousel'

export const ForYouTracks = () => {
const { inView, InViewWrapper } = useDeferredElement()
const { inView, InViewWrapper } =
useExploreSectionTracking('Recommended Tracks')
const { data: recommendedTracks, isPending } = useRecommendedTracks(
{ pageSize: 10, timeRange: full.GetRecommendedTracksTimeEnum.Week },
{ enabled: inView }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { exploreMessages as messages } from '@audius/common/messages'

import { useTheme } from '@audius/harmony-native'
import { TrackCardList } from 'app/components/track-card-list'
import { useDeferredElement } from 'app/hooks/useDeferredElement'

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

import { ExploreSection } from './ExploreSection'

export const RecentlyPlayedTracks = () => {
const { spacing } = useTheme()
const { InViewWrapper, inView } = useDeferredElement()
const { InViewWrapper, inView } = useExploreSectionTracking('Recently Played')
const { data: recentlyPlayedTracks } = useRecentlyPlayedTracks(
{ pageSize: 10 },
{ enabled: inView }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useEffect } from 'react'

import { useAnalytics } from '@audius/common/hooks'
import type { ExploreSectionName } from '@audius/common/models'
import { Name } from '@audius/common/models'

import { useDeferredElement } from 'app/hooks/useDeferredElement'

/**
* Hook to track explore section impressions when they come into view on mobile
*/
export const useExploreSectionTracking = (sectionName: ExploreSectionName) => {
const { inView, InViewWrapper } = useDeferredElement()
const { trackEvent } = useAnalytics()

useEffect(() => {
if (inView) {
trackEvent({
eventName: Name.EXPLORE_SECTION_VIEW,
section: sectionName,
source: 'mobile'
})
}
}, [inView, sectionName, trackEvent])

return { inView, InViewWrapper }
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { exploreMessages as messages } from '@audius/common/messages'

import { Carousel } from './Carousel'
import { TilePairs, TileSkeletons } from './TileHelpers'
import { useDeferredElement } from './useDeferredElement'
import { useExploreSectionTracking } from './useExploreSectionTracking'

export const ArtistCoinTracksSection = () => {
const { ref, inView } = useDeferredElement()
const { ref, inView } = useExploreSectionTracking('Artist Coin Tracks')

const { data, isLoading, isError, isSuccess } = useExploreContent({
enabled: inView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { UserCard, UserCardSkeleton } from 'components/user-card'
import { useIsMobile } from 'hooks/useIsMobile'

import { Carousel } from './Carousel'
import { useDeferredElement } from './useDeferredElement'
import { useExploreSectionTracking } from './useExploreSectionTracking'

export const ArtistSpotlightSection = () => {
const { ref, inView } = useDeferredElement()
const { ref, inView } = useExploreSectionTracking('Artist Spotlight')
const { data, isLoading, isError, isSuccess } = useExploreContent({
enabled: inView
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { useCallback, useState } from 'react'

import { useCollection, useUser } from '@audius/common/api'
import { ID, SquareSizes } from '@audius/common/models'
import { useAnalytics } from '@audius/common/hooks'
import {
ID,
SquareSizes,
ExploreSectionName,
Name
} from '@audius/common/models'
import { Flex } from '@audius/harmony'
import { useNavigate } from 'react-router'

Expand All @@ -11,23 +17,47 @@ import { UserLink } from 'components/link/UserLink'
import PerspectiveCard from 'components/perspective-card/PerspectiveCard'
import { FavoriteStats } from 'components/stats/FavoriteStats'
import { RepostStats } from 'components/stats/RepostStats'
import { useIsMobile } from 'hooks/useIsMobile'
import { UserListEntityType } from 'store/application/ui/userListModal/types'

type CollectionArtCardProps = {
id: ID
sectionName?: ExploreSectionName
}

const ARTWORK_SIZE = 240

export const CollectionArtCard = ({ id }: CollectionArtCardProps) => {
export const CollectionArtCard = ({
id,
sectionName
}: CollectionArtCardProps) => {
const [isPerspectiveDisabled] = useState(false)
const navigate = useNavigate()
const { trackEvent } = useAnalytics()
const isMobile = useIsMobile()
const { data: partialCollection } = useCollection(id)

const goToPlaylist = useCallback(() => {
if (!partialCollection?.permalink) return
if (sectionName) {
trackEvent({
eventName: Name.EXPLORE_SECTION_CLICK,
section: sectionName,
source: isMobile ? 'mobile' : 'web',
id,
kind: 'playlist',
Copy link

Choose a reason for hiding this comment

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

Collection click analytics hardcodes kind as playlist

Low Severity

CollectionArtCard hardcodes kind: 'playlist' in the EXPLORE_SECTION_CLICK analytics event, but a collection can also be an album. Since the ExploreSectionClick type explicitly supports both 'playlist' and 'album' as valid kinds, the analytics data will misclassify album clicks as playlist clicks. The collection data from useCollection is already available and could be used to determine the correct kind.

Fix in Cursor Fix in Web

link: partialCollection.permalink
})
}
navigate(partialCollection.permalink)
}, [navigate, partialCollection?.permalink])
}, [
navigate,
partialCollection?.permalink,
sectionName,
id,
trackEvent,
isMobile
])

const { data: user } = useUser(partialCollection?.playlist_owner_id)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { CollectionCard, CollectionCardSkeleton } from 'components/collection'
import { useIsMobile } from 'hooks/useIsMobile'

import { Carousel } from './Carousel'
import { useDeferredElement } from './useDeferredElement'
import { useExploreSectionTracking } from './useExploreSectionTracking'

export const FeaturedPlaylistsSection = () => {
const { ref, inView } = useDeferredElement()
const { ref, inView } = useExploreSectionTracking('Featured Playlists')

const { data, isLoading, isError, isSuccess } = useExploreContent({
enabled: inView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import {
import { useIsMobile } from 'hooks/useIsMobile'

import { Carousel } from './Carousel'
import { useDeferredElement } from './useDeferredElement'
import { useExploreSectionTracking } from './useExploreSectionTracking'

export const FeaturedRemixContestsSection = () => {
const { ref, inView } = useDeferredElement()
const { ref, inView } = useExploreSectionTracking('Featured Remix Contests')

const { data, isLoading, isError, isSuccess } = useExploreContent({
enabled: inView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import { TrackTile as MobileTrackTile } from 'components/track/mobile/TrackTile'
import { TrackTileSize } from 'components/track/types'
import { useIsMobile } from 'hooks/useIsMobile'

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

export const FeelingLuckySection = () => {
const { ref, inView } = useDeferredElement()
const { ref, inView } = useExploreSectionTracking('Feeling Lucky')
const isMobile = useIsMobile()
const {
data: feelingLuckyTrack,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { UserCard, UserCardSkeleton } from 'components/user-card'
import { useIsMobile } from 'hooks/useIsMobile'

import { Carousel } from './Carousel'
import { useDeferredElement } from './useDeferredElement'
import { useExploreSectionTracking } from './useExploreSectionTracking'

export const LabelSpotlightSection = () => {
const { ref, inView } = useDeferredElement()
const { ref, inView } = useExploreSectionTracking('Label Spotlight')
const { data, isLoading, isError, isSuccess } = useExploreContent({
enabled: inView
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { Flex } from '@audius/harmony'
import { useIsMobile } from 'hooks/useIsMobile'
import { RecentSearches } from 'pages/search-page/RecentSearches'

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

export const RecentSearchesSection = () => {
const { ref, inView } = useDeferredElement()
const { ref, inView } = useExploreSectionTracking('Recent Searches')
const isMobile = useIsMobile()

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { TrackCard, TrackCardSkeleton } from 'components/track/TrackCard'
import { useIsMobile } from 'hooks/useIsMobile'

import { Carousel } from './Carousel'
import { useDeferredElement } from './useDeferredElement'
import { useExploreSectionTracking } from './useExploreSectionTracking'

export const RecentlyPlayedSection = () => {
const { ref, inView } = useDeferredElement()
const { ref, inView } = useExploreSectionTracking('Recently Played')
const { data, isLoading, isError, isSuccess } = useRecentlyPlayedTracks(
{ pageSize: 10 },
{ enabled: inView }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { full } from '@audius/sdk'

import { Carousel } from './Carousel'
import { TilePairs, TileSkeletons } from './TileHelpers'
import { useDeferredElement } from './useDeferredElement'
import { useExploreSectionTracking } from './useExploreSectionTracking'

export const RecommendedTracksSection = () => {
const { ref, inView } = useDeferredElement()
const { ref, inView } = useExploreSectionTracking('Recommended Tracks')
const { data, isLoading, isError, isSuccess } = useRecommendedTracks(
{
pageSize: 10,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { useCallback } from 'react'

import { useRemixContest, useTrack } from '@audius/common/api'
import { ID, SquareSizes } from '@audius/common/models'
import { useAnalytics } from '@audius/common/hooks'
import {
ID,
SquareSizes,
ExploreSectionName,
Name
} from '@audius/common/models'
import { dayjs, formatContestDeadlineWithStatus } from '@audius/common/utils'
import { Flex, Skeleton, Text } from '@audius/harmony'
import { useNavigate } from 'react-router'
Expand All @@ -10,9 +16,11 @@ import { TrackLink } from 'components/link/TrackLink'
import { UserLink } from 'components/link/UserLink'
import PerspectiveCard from 'components/perspective-card/PerspectiveCard'
import { TrackArtwork } from 'components/track/TrackArtwork'
import { useIsMobile } from 'hooks/useIsMobile'

type TrackArtCardProps = {
id: ID
sectionName?: ExploreSectionName
}

const messages = {
Expand All @@ -29,8 +37,10 @@ const messages = {

const ARTWORK_SIZE = 240

export const TrackArtCard = ({ id }: TrackArtCardProps) => {
export const TrackArtCard = ({ id, sectionName }: TrackArtCardProps) => {
const navigate = useNavigate()
const { trackEvent } = useAnalytics()
const isMobile = useIsMobile()

const { data: track, isLoading: isTrackLoading } = useTrack(id)
const { data: contest, isLoading: isContestLoading } = useRemixContest(id)
Expand All @@ -39,8 +49,18 @@ export const TrackArtCard = ({ id }: TrackArtCardProps) => {

const goToTrack = useCallback(() => {
if (!track?.permalink) return
if (sectionName) {
trackEvent({
eventName: Name.EXPLORE_SECTION_CLICK,
section: sectionName,
source: isMobile ? 'mobile' : 'web',
id,
kind: 'track',
link: track.permalink
})
}
navigate(track.permalink)
}, [navigate, track?.permalink])
}, [navigate, track?.permalink, sectionName, id, trackEvent, isMobile])

if (!track) return null

Expand Down
Loading