Skip to content

Commit

Permalink
[PAY-2766] Analytics events for premium albums (#8262)
Browse files Browse the repository at this point in the history
  • Loading branch information
DejayJD committed May 1, 2024
1 parent 035a8fb commit d7c8e34
Show file tree
Hide file tree
Showing 21 changed files with 195 additions and 59 deletions.
35 changes: 33 additions & 2 deletions packages/common/src/models/Analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import {
WalletAddress
} from '~/models/Wallet'
import { MintName } from '~/services/index'
import { Prettify } from '~/utils/typeUtils'
import { Nullable, Prettify } from '~/utils/typeUtils'

import { Chain } from './Chain'
import { PlaylistLibraryKind } from './PlaylistLibrary'
import { PurchaseMethod } from './PurchaseContent'
import { TrackAccessType } from './Track'
import { AccessConditions, TrackAccessType } from './Track'

const ANALYTICS_TRACK_EVENT = 'ANALYTICS/TRACK_EVENT'

Expand Down Expand Up @@ -219,11 +219,16 @@ export enum Name {
// Track Edits
TRACK_EDIT_ACCESS_CHANGED = 'Track Edit: Access Changed',

// Collection Edits
COLLECTION_EDIT_ACCESS_CHANGED = 'Collection Edit: Access Changed',
COLLECTION_EDIT = 'Collection Edit: General Edits',

// Gated Track Listen
LISTEN_GATED = 'Listen: Gated',

// Unlocked Gated Tracks
USDC_PURCHASE_GATED_TRACK_UNLOCKED = 'USDC Gated: Track Unlocked',
USDC_PURCHASE_GATED_COLLECTION_UNLOCKED = 'USDC Gated: Collection Unlocked',
COLLECTIBLE_GATED_TRACK_UNLOCKED = 'Collectible Gated: Track Unlocked',
FOLLOW_GATED_TRACK_UNLOCKED = 'Follow Gated: Track Unlocked',
TIP_GATED_TRACK_UNLOCKED = 'Tip Gated: Track Unlocked',
Expand Down Expand Up @@ -1146,6 +1151,21 @@ type TrackEditAccessChanged = {
to: TrackAccessType
}

// Collection Edits
type CollectionEditAccessChanged = {
eventName: Name.COLLECTION_EDIT_ACCESS_CHANGED
id: number
from: Nullable<AccessConditions>
to: Nullable<AccessConditions>
}

type CollectionEdit = {
eventName: Name.COLLECTION_EDIT
id: number
from: TrackAccessType
to: TrackAccessType
}

// Unlocked Gated Tracks
type USDCGatedTrackUnlocked = {
eventName: Name.USDC_PURCHASE_GATED_TRACK_UNLOCKED
Expand Down Expand Up @@ -1334,8 +1354,10 @@ export enum PlaybackSource {
PLAYLIST_PAGE = 'playlist page',
TRACK_PAGE = 'track page',
TRACK_TILE = 'track tile',
TRACK_TILE_LINEUP = 'track tile lineup',
PLAYLIST_TRACK = 'playlist page track list',
PLAYLIST_TILE_TRACK = 'playlist track tile',
PLAYLIST_TILE_TRACK_LINEUP = 'playlist track tile lineup',
HISTORY_PAGE = 'history page',
LIBRARY_PAGE = 'library page',
PASSIVE = 'passive',
Expand Down Expand Up @@ -1370,9 +1392,16 @@ type TagClicking = {

export enum ModalSource {
TrackTile = 'track tile',
CollectionTile = 'collection tile',
TrackDetails = 'track details',
CollectionDetails = 'collection details',
NowPlaying = 'now playing',
PlayBar = 'play bar',
DirectMessageTrackTile = 'track tile - direct message',
DirectMessageCollectionTile = 'collection tile - direct message',
LineUpTrackTile = 'track tile - lineup',
LineUpCollectionTile = 'collection tile - lineup',
TrackListItem = 'track list item',
// Should never be used, but helps with type-checking
Unknown = 'unknown'
}
Expand Down Expand Up @@ -2424,6 +2453,8 @@ export type AllTrackingEvents =
| TrackDownloadSuccessfulDownloadSingle
| TrackDownloadFailedDownloadSingle
| TrackEditAccessChanged
| CollectionEditAccessChanged
| CollectionEdit
| TrackUploadSuccess
| TrackUploadFailure
| TrackUploadRejected
Expand Down
25 changes: 15 additions & 10 deletions packages/common/src/store/gated-content/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,16 +492,21 @@ export function* pollGatedContent({
return
}

// TODO: Add separate analytics names for gated albums
const eventName =
!isAlbum &&
(isContentUSDCPurchaseGated(apiEntity.stream_conditions)
? Name.USDC_PURCHASE_GATED_TRACK_UNLOCKED
: isContentFollowGated(apiEntity.stream_conditions)
? Name.FOLLOW_GATED_TRACK_UNLOCKED
: isContentTipGated(apiEntity.stream_conditions)
? Name.TIP_GATED_TRACK_UNLOCKED
: null)
const getEventName = () => {
if (isContentUSDCPurchaseGated(apiEntity.stream_conditions)) {
return isAlbum
? Name.USDC_PURCHASE_GATED_COLLECTION_UNLOCKED
: Name.USDC_PURCHASE_GATED_TRACK_UNLOCKED
}
if (isContentFollowGated(apiEntity.stream_conditions)) {
return Name.FOLLOW_GATED_TRACK_UNLOCKED
}
if (isContentTipGated(apiEntity.stream_conditions)) {
return Name.TIP_GATED_TRACK_UNLOCKED
}
return null
}
const eventName = getEventName()
if (eventName) {
analytics.track({
eventName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
AccessPermissions,
CoverArtSizes,
ID,
ModalSource,
Variant,
isContentUSDCPurchaseGated
} from '@audius/common/models'
Expand Down Expand Up @@ -315,6 +316,7 @@ export const CollectionHeader = (props: CollectionHeaderProps) => {
hasStreamAccess={hasStreamAccess}
isOwner={ownerId === currentUserId}
ownerId={ownerId}
source={ModalSource.CollectionDetails}
/>
) : null}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { MouseEventHandler, memo, useCallback } from 'react'

import { imageBlank } from '@audius/common/assets'
import { Variant, SquareSizes, Collection, ID } from '@audius/common/models'
import {
Variant,
SquareSizes,
Collection,
ID,
ModalSource
} from '@audius/common/models'
import { FeatureFlags } from '@audius/common/services'
import {
CommonState,
Expand Down Expand Up @@ -261,6 +267,7 @@ const CollectionHeader = ({
className={styles.gatedContentSection}
buttonClassName={styles.gatedContentSectionButton}
ownerId={userId}
source={ModalSource.CollectionDetails}
/>
</Box>
) : null}
Expand Down
25 changes: 13 additions & 12 deletions packages/web/src/components/create-playlist/PlaylistForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
SquareSizes,
CollectionMetadata,
Collection
} from '@audius/common/models'
import { SquareSizes, Collection } from '@audius/common/models'
import { createCollectionSchema } from '@audius/common/schemas'
import { Nullable } from '@audius/common/utils'
import { Flex } from '@audius/harmony'
Expand Down Expand Up @@ -47,7 +43,10 @@ type PlaylistFormProps = {
onDelete?: () => void
/** Only applies to edit mode */
onCancel?: () => void
onSave: (formFields: CollectionMetadata) => void
onSave: (
formFields: EditPlaylistValues,
initialValues: EditPlaylistValues
) => void
}

const createCollectionFormSchema = (collectionType: 'album' | 'playlist') => {
Expand All @@ -72,14 +71,16 @@ const PlaylistForm = ({
SquareSizes.SIZE_1000_BY_1000
)

const initialValues = {
...metadata,
artwork: coverArtUrl ? { url: coverArtUrl } : null,
description: metadata.description ?? ''
}

return (
<Formik<EditPlaylistValues>
initialValues={{
...metadata,
artwork: coverArtUrl ? { url: coverArtUrl } : null,
description: metadata.description ?? ''
}}
onSubmit={onSave}
initialValues={initialValues}
onSubmit={(values) => onSave(values, initialValues)}
validationSchema={toFormikValidationSchema(
createCollectionFormSchema(isAlbum ? 'album' : 'playlist')
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useCallback, useEffect, useState } from 'react'

import { Name } from '@audius/common/models'
import {
EditPlaylistValues,
accountActions,
cacheCollectionsActions,
cacheCollectionsSelectors,
Expand All @@ -16,9 +18,12 @@ import {
import { push as pushRoute } from 'connected-react-router'
import { useDispatch } from 'react-redux'

import PlaylistForm from 'components/create-playlist/PlaylistForm'
import PlaylistForm, {
EditPlaylistValues as PlaylistFormValues
} from 'components/create-playlist/PlaylistForm'
import LoadingSpinner from 'components/loading-spinner/LoadingSpinner'
import { DeleteCollectionConfirmationModal } from 'components/nav/desktop/PlaylistLibrary/DeleteCollectionConfirmationModal'
import { track } from 'services/analytics'
import { useSelector } from 'utils/reducer'
import { TRENDING_PAGE } from 'utils/route'
import zIndex from 'utils/zIndex'
Expand Down Expand Up @@ -62,9 +67,26 @@ const EditPlaylistModal = () => {
const onCancelDelete = () => setShowDeleteConfirmation(false)

const handleSubmit = useCallback(
(formFields: any) => {
(formFields: PlaylistFormValues, initialValues: PlaylistFormValues) => {
if (playlistId) {
dispatch(editPlaylist(playlistId, formFields))
track({
eventName: Name.COLLECTION_EDIT,
properties: {
id: playlistId
}
})
// We want to pay special attention to access condition changes
if (formFields.stream_conditions !== initialValues.stream_conditions) {
track({
eventName: Name.COLLECTION_EDIT_ACCESS_CHANGED,
properties: {
id: playlistId,
from: initialValues.stream_conditions,
to: formFields.stream_conditions
}
})
}
dispatch(editPlaylist(playlistId, formFields as EditPlaylistValues))
}
onClose()
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useState, useCallback } from 'react'

import { imageBlank as placeholderCoverArt } from '@audius/common/assets'
import { useGatedContentAccessMap } from '@audius/common/hooks'
import { SquareSizes, Collection, ID } from '@audius/common/models'
import { SquareSizes, Collection, ID, Name } from '@audius/common/models'
import { newCollectionMetadata } from '@audius/common/schemas'
import { RandomImage } from '@audius/common/services'
import {
Expand All @@ -29,6 +29,7 @@ import TrackList from 'components/track/mobile/TrackList'
import { useCollectionCoverArt } from 'hooks/useCollectionCoverArt'
import useHasChangedRoute from 'hooks/useHasChangedRoute'
import UploadStub from 'pages/profile-page/components/mobile/UploadStub'
import { track } from 'services/analytics'
import { AppState } from 'store/types'
import { resizeImage } from 'utils/imageProcessingUtil'
import { useSelector } from 'utils/reducer'
Expand Down Expand Up @@ -238,6 +239,13 @@ const EditPlaylistPage = g(

editPlaylist(metadata.playlist_id, editPlaylistData)

track({
eventName: Name.COLLECTION_EDIT,
properties: {
id: metadata.playlist_id
}
})

onClose()
}
}, [
Expand Down
13 changes: 8 additions & 5 deletions packages/web/src/components/lineup/LineupProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
Status,
ID,
UID,
Lineup
Lineup,
ModalSource
} from '@audius/common/models'
import {
LineupBaseActions,
Expand Down Expand Up @@ -527,7 +528,7 @@ class LineupProvider extends PureComponent<CombinedProps, LineupProviderState> {
// Render a track tile if the kind tracks or there's a track id present

if (entry._marked_deleted) return null
let trackProps = {
let trackProps: TrackTileProps = {
...entry,
key: index,
index,
Expand All @@ -542,7 +543,8 @@ class LineupProvider extends PureComponent<CombinedProps, LineupProviderState> {
isTrending,
showRankIcon: index < rankIconCount,
showFeedTipTile,
onClick: onClickTile
onClick: onClickTile,
source: ModalSource.LineUpTrackTile
}
if (entry.id === leadingElementId) {
trackProps = { ...trackProps, ...leadingElementTileProps }
Expand All @@ -551,7 +553,7 @@ class LineupProvider extends PureComponent<CombinedProps, LineupProviderState> {
} else if (entry.kind === Kind.COLLECTIONS || entry.playlist_id) {
// Render a track tile if the kind tracks or there's a track id present

const playlistProps = {
const playlistProps: PlaylistTileProps = {
...entry,
key: index,
index,
Expand All @@ -567,7 +569,8 @@ class LineupProvider extends PureComponent<CombinedProps, LineupProviderState> {
numLoadingSkeletonRows: numPlaylistSkeletonRows,
isTrending,
showRankIcon: index < rankIconCount,
showFeedTipTile
showFeedTipTile,
source: ModalSource.LineUpCollectionTile
}

return <this.props.playlistTile key={index} {...playlistProps} />
Expand Down

0 comments on commit d7c8e34

Please sign in to comment.