Skip to content
This repository has been archived by the owner on Oct 4, 2023. It is now read-only.

[PAY-1505] USDC-gated mobile track tiles #3684

Merged
merged 7 commits into from
Jun 30, 2023
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/mobile/src/assets/images/iconCart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 9 additions & 8 deletions packages/mobile/src/components/core/DogEar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { ViewStyle } from 'react-native'
import { View } from 'react-native'
import LinearGradient from 'react-native-linear-gradient'

import IconCart from 'app/assets/images/iconCart.svg'
import IconCollectible from 'app/assets/images/iconCollectible.svg'
import IconHidden from 'app/assets/images/iconHidden.svg'
import IconLock from 'app/assets/images/iconLock.svg'
import IconSpecialAccess from 'app/assets/images/iconSpecialAccess.svg'
import IconStar from 'app/assets/images/iconStar.svg'
import { makeStyles } from 'app/styles'
Expand Down Expand Up @@ -39,9 +39,9 @@ const useStyles = makeStyles(({ spacing }) => ({
export enum DogEarType {
STAR = 'star',
HIDDEN = 'hidden',
LOCKED = 'locked',
COLLECTIBLE_GATED = 'collectible gated',
SPECIAL_ACCESS = 'special access'
SPECIAL_ACCESS = 'special access',
USDC_PURCHASE = 'usdc purchase'
}

type DogEarProps = {
Expand All @@ -58,7 +58,8 @@ export const DogEar = (props: DogEarProps) => {
pageHeaderGradientColor2,
secondary,
staticWhite,
accentBlue
accentBlue,
specialLightGreen1
} = useThemeColors()

const { icon: Icon, colors } = {
Expand All @@ -70,17 +71,17 @@ export const DogEar = (props: DogEarProps) => {
icon: IconHidden,
colors: [neutral, neutralLight3]
},
[DogEarType.LOCKED]: {
icon: IconLock,
colors: [accentBlue, accentBlue]
},
[DogEarType.COLLECTIBLE_GATED]: {
icon: IconCollectible,
colors: [accentBlue, accentBlue]
},
[DogEarType.SPECIAL_ACCESS]: {
icon: IconSpecialAccess,
colors: [accentBlue, accentBlue]
},
[DogEarType.USDC_PURCHASE]: {
icon: IconCart,
colors: [specialLightGreen1, specialLightGreen1]
}
}[type]

Expand Down
8 changes: 6 additions & 2 deletions packages/mobile/src/components/details-tile/DetailsTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
import Text from 'app/components/text'
import UserBadges from 'app/components/user-badges'
import { light } from 'app/haptics'
import { useIsUSDCEnabled } from 'app/hooks/useIsUSDCEnabled'
import { useNavigation } from 'app/hooks/useNavigation'
import { useFeatureFlag } from 'app/hooks/useRemoteConfig'
import { flexRowCentered, makeStyles } from 'app/styles'
Expand Down Expand Up @@ -228,6 +229,7 @@ export const DetailsTile = ({
const { isEnabled: isAiGeneratedTracksEnabled } = useFeatureFlag(
FeatureFlags.AI_ATTRIBUTION
)
const isUSDCEnabled = useIsUSDCEnabled()
const { track_id: trackId, premium_conditions: premiumConditions } =
track ?? {}

Expand Down Expand Up @@ -266,10 +268,12 @@ export const DetailsTile = ({

const dogEarType = showPremiumDogEar
? isOwner
? premiumConditions.nft_collection
? isUSDCEnabled && premiumConditions.usdc_purchase
dharit-tan marked this conversation as resolved.
Show resolved Hide resolved
? DogEarType.USDC_PURCHASE
: premiumConditions.nft_collection
? DogEarType.COLLECTIBLE_GATED
: DogEarType.SPECIAL_ACCESS
: DogEarType.LOCKED
: null
: null

if (showPremiumDogEar && dogEarType) {
Expand Down
9 changes: 7 additions & 2 deletions packages/mobile/src/components/lineup-tile/LineupTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useSelector, useDispatch } from 'react-redux'

import { DogEar, DogEarType } from 'app/components/core'
import type { LineupTileProps } from 'app/components/lineup-tile/types'
import { useIsUSDCEnabled } from 'app/hooks/useIsUSDCEnabled'
import { setVisibility } from 'app/store/drawers/slice'

import { LineupTileActionButtons } from './LineupTileActionButtons'
Expand Down Expand Up @@ -59,6 +60,8 @@ export const LineupTile = ({
repost_count,
save_count
} = item
const dispatch = useDispatch()
const isUSDCEnabled = useIsUSDCEnabled()
const { artist_pick_track_id, name, user_id } = user
const currentUserId = useSelector(getUserId)
const isOwner = user_id === currentUserId
Expand All @@ -68,15 +71,16 @@ export const LineupTile = ({
const premiumConditions = isTrack ? item.premium_conditions : null
const isArtistPick = artist_pick_track_id === id
const { doesUserHaveAccess } = usePremiumContentAccess(isTrack ? item : null)
const dispatch = useDispatch()

const showPremiumDogEar =
premiumConditions &&
(isOwner || !doesUserHaveAccess) &&
!(showArtistPick && isArtistPick)

const dogEarType = showPremiumDogEar
? premiumConditions.nft_collection
? isUSDCEnabled && premiumConditions.usdc_purchase
dharit-tan marked this conversation as resolved.
Show resolved Hide resolved
? DogEarType.USDC_PURCHASE
: premiumConditions.nft_collection
? DogEarType.COLLECTIBLE_GATED
: DogEarType.SPECIAL_ACCESS
: null
Expand Down Expand Up @@ -159,6 +163,7 @@ export const LineupTile = ({
isShareHidden={hideShare}
isUnlisted={isUnlisted}
trackId={trackId}
premiumConditions={premiumConditions}
doesUserHaveAccess={doesUserHaveAccess}
onPressOverflow={onPressOverflow}
onPressRepost={onPressRepost}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { ID } from '@audius/common'
import type { ID, PremiumConditions } from '@audius/common'
import { premiumContentSelectors } from '@audius/common'
import { View } from 'react-native'
import { useSelector } from 'react-redux'

import IconLock from 'app/assets/images/iconLock.svg'
import { Text } from 'app/components/core'
import LoadingSpinner from 'app/components/loading-spinner'
import { useIsUSDCEnabled } from 'app/hooks/useIsUSDCEnabled'
import { flexRowCentered, makeStyles } from 'app/styles'
import { useColor } from 'app/utils/theme'

Expand Down Expand Up @@ -33,17 +34,34 @@ const useStyles = makeStyles(({ palette, spacing, typography }) => ({
loadingSpinner: {
width: spacing(4),
height: spacing(4)
},
usdcPurchase: {
backgroundColor: palette.specialLightGreen1
}
}))

export const LineupTileAccessStatus = ({ trackId }: { trackId: ID }) => {
export const LineupTileAccessStatus = ({
trackId,
premiumConditions
}: {
trackId: ID
premiumConditions: PremiumConditions
}) => {
const styles = useStyles()
const isUSDCEnabled = useIsUSDCEnabled()
const premiumTrackStatusMap = useSelector(getPremiumTrackStatusMap)
const premiumTrackStatus = premiumTrackStatusMap[trackId]
const staticWhite = useColor('staticWhite')

return (
<View style={styles.root}>
<View
style={[
styles.root,
isUSDCEnabled && premiumConditions.usdc_purchase
? styles.usdcPurchase
: null
]}
>
{premiumTrackStatus === 'UNLOCKING' ? (
<LoadingSpinner style={styles.loadingSpinner} fill={staticWhite} />
) : (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ID } from '@audius/common'
import type { ID, Nullable, PremiumConditions } from '@audius/common'
import { View } from 'react-native'

import IconKebabHorizontal from 'app/assets/images/iconKebabHorizontal.svg'
Expand All @@ -20,6 +20,7 @@ type Props = {
isShareHidden?: boolean
isUnlisted?: boolean
trackId?: ID
premiumConditions?: Nullable<PremiumConditions>
doesUserHaveAccess?: boolean
onPressOverflow?: GestureResponderHandler
onPressRepost?: GestureResponderHandler
Expand Down Expand Up @@ -57,6 +58,7 @@ export const LineupTileActionButtons = ({
isUnlisted,
trackId,
doesUserHaveAccess = false,
premiumConditions,
onPressOverflow,
onPressRepost,
onPressSave,
Expand Down Expand Up @@ -111,9 +113,12 @@ export const LineupTileActionButtons = ({
return (
<View style={styles.bottomButtons}>
<View style={styles.leftButtons}>
{showPremiumAccessStatus && (
<LineupTileAccessStatus trackId={trackId} />
)}
{showPremiumAccessStatus && premiumConditions != null ? (
<LineupTileAccessStatus
trackId={trackId}
premiumConditions={premiumConditions}
/>
) : null}
{showLeftButtons && (
<>
{repostButton}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ import { useMemo } from 'react'
import type { PremiumConditions } from '@audius/common'
import { View } from 'react-native'

import IconCart from 'app/assets/images/iconCart.svg'
import IconCollectible from 'app/assets/images/iconCollectible.svg'
import IconSpecialAccess from 'app/assets/images/iconSpecialAccess.svg'
import Text from 'app/components/text'
import { useIsUSDCEnabled } from 'app/hooks/useIsUSDCEnabled'
import { makeStyles, flexRowCentered } from 'app/styles'
import { spacing } from 'app/styles/spacing'
import { useThemeColors } from 'app/utils/theme'

const messages = {
collectibleGated: 'Collectible Gated',
specialAccess: 'Special Access'
specialAccess: 'Special Access',
premium: 'Premium'
}

const useStyles = makeStyles(({ spacing, palette, typography }) => ({
Expand All @@ -28,7 +31,8 @@ const useStyles = makeStyles(({ spacing, palette, typography }) => ({

enum PremiumContentType {
COLLECTIBLE_GATED = 'collectible gated',
SPECIAL_ACCESS = 'special access'
SPECIAL_ACCESS = 'special access',
USDC_PURCHASE = 'usdc purchase'
}

type LineupTilePremiumContentTypeTagProps = {
Expand All @@ -49,11 +53,15 @@ export const LineupTilePremiumContentTypeTag = ({
isOwner
}: LineupTilePremiumContentTypeTagProps) => {
const styles = useStyles()
const { accentBlue, neutralLight4 } = useThemeColors()
const { accentBlue, neutralLight4, specialLightGreen1 } = useThemeColors()
const isUSDCEnabled = useIsUSDCEnabled()

const type = premiumConditions?.nft_collection
? PremiumContentType.COLLECTIBLE_GATED
: PremiumContentType.SPECIAL_ACCESS
const type =
isUSDCEnabled && premiumConditions?.usdc_purchase
? PremiumContentType.USDC_PURCHASE
: premiumConditions?.nft_collection
? PremiumContentType.COLLECTIBLE_GATED
: PremiumContentType.SPECIAL_ACCESS

const premiumContentTypeMap = useMemo(() => {
return {
Expand All @@ -66,9 +74,21 @@ export const LineupTilePremiumContentTypeTag = ({
icon: IconSpecialAccess,
color: doesUserHaveAccess && !isOwner ? neutralLight4 : accentBlue,
text: messages.specialAccess
},
[PremiumContentType.USDC_PURCHASE]: {
icon: IconCart,
color:
doesUserHaveAccess && !isOwner ? neutralLight4 : specialLightGreen1,
text: messages.premium
}
}
}, [accentBlue, doesUserHaveAccess, isOwner, neutralLight4])
}, [
accentBlue,
doesUserHaveAccess,
isOwner,
neutralLight4,
specialLightGreen1
])

const { icon: Icon, color, text } = premiumContentTypeMap[type]

Expand Down
10 changes: 9 additions & 1 deletion packages/mobile/src/components/lineup-tile/LineupTileStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import IconUnlocked from 'app/assets/images/iconUnlocked.svg'
import { CollectionDownloadStatusIndicator } from 'app/components/offline-downloads/CollectionDownloadStatusIndicator'
import { TrackDownloadStatusIndicator } from 'app/components/offline-downloads/TrackDownloadStatusIndicator'
import Text from 'app/components/text'
import { useIsUSDCEnabled } from 'app/hooks/useIsUSDCEnabled'
import { useNavigation } from 'app/hooks/useNavigation'
import { makeStyles, flexRowCentered } from 'app/styles'
import { useThemeColors } from 'app/utils/theme'
Expand Down Expand Up @@ -77,6 +78,9 @@ const useStyles = makeStyles(({ spacing, palette }) => ({
},
iconUnlocked: {
backgroundColor: palette.accentBlue
},
iconUSDC: {
backgroundColor: palette.specialLightGreen1
}
}))

Expand Down Expand Up @@ -122,6 +126,7 @@ export const LineupTileStats = ({
const { neutralLight4, staticWhite } = useThemeColors()
const dispatch = useDispatch()
const navigation = useNavigation()
const isUSDCEnabled = useIsUSDCEnabled()

const hasEngagement = Boolean(repostCount || saveCount)

Expand Down Expand Up @@ -203,7 +208,10 @@ export const LineupTileStats = ({
style={[
styles.iconLocked,
styles.listenCount,
doesUserHaveAccess ? styles.iconUnlocked : null
doesUserHaveAccess ? styles.iconUnlocked : null,
isUSDCEnabled && premiumConditions.usdc_purchase
? styles.iconUSDC
: null
]}
>
{doesUserHaveAccess ? (
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/utils/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const defaultTheme = {
staticNeutralLight2: '#AAA7B8',
staticNeutralLight8: '#F2F2F4',
staticAccentGreenLight1: '#23AD1A',
specialLightGreen1: '#13C65A',
staticPrimary: '#CC0FE0',
staticSecondary: '#7E1BCC',
pageHeaderGradientColor1: '#5B23E1',
Expand Down Expand Up @@ -115,6 +116,7 @@ export const darkTheme = {
staticNeutralLight2: '#AAA7B8',
staticNeutralLight8: '#F2F2F4',
staticAccentGreenLight1: '#23AD1A',
specialLightGreen1: '#13C65A',
staticPrimary: '#CC0FE0',
staticSecondary: '#7E1BCC',
pageHeaderGradientColor1: '#7652CC',
Expand Down Expand Up @@ -162,6 +164,7 @@ export const matrixTheme = {
staticNeutralLight2: '#AAA7B8',
staticNeutralLight8: '#F2F2F4',
staticAccentGreenLight1: '#23AD1A',
specialLightGreen1: '#13C65A',
staticPrimary: '#CC0FE0',
staticSecondary: '#7E1BCC',
pageHeaderGradientColor1: '#4FF069',
Expand Down Expand Up @@ -223,6 +226,7 @@ export type ThemeColors = {
staticNeutralLight2: string
staticNeutralLight8: string
staticAccentGreenLight1: string
specialLightGreen1: string
staticPrimary: string
staticSecondary: string
pageHeaderGradientColor1: string
Expand Down