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

Commit

Permalink
Add route for audio nft playlists (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyle-Shanks authored May 19, 2022
1 parent fe880fe commit 75d87a4
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 77 deletions.
178 changes: 107 additions & 71 deletions src/components/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import { PauseContextProvider } from './pausedpopover/PauseProvider'
import PausePopover from './pausedpopover/PausePopover'

import styles from './App.module.css'
import { initTrackSessionStart, recordOpen, recordError } from '../analytics/analytics'
import {
initTrackSessionStart,
recordOpen,
recordError
} from '../analytics/analytics'
import transitions from './AppTransitions.module.css'
import { CSSTransition } from 'react-transition-group'
import { getDominantColor } from '../util/image/dominantColor'
Expand All @@ -37,12 +41,14 @@ import {
COLLECTIBLES_ROUTE,
COLLECTIBLE_ID_ROUTE,
COLLECTIBLES_DISCORD_ROUTE,
COLLECTIBLE_ID_DISCORD_ROUTE
COLLECTIBLE_ID_DISCORD_ROUTE,
AUDIO_NFT_PLAYLIST_ROUTE,
AUDIO_NFT_PLAYLIST_DISCORD_ROUTE
} from '../routes'

if ((module).hot) {
// tslint:disable-next-line:no-var-requires
require('preact/debug')
if (module.hot) {
// tslint:disable-next-line:no-var-requires
require('preact/debug')
}

// How long to wait for GA before we show the loading screen
Expand All @@ -55,10 +61,10 @@ const RequestType = Object.seal({
})

const pathComponentRequestTypeMap = {
"playlist": RequestType.COLLECTION,
"album": RequestType.COLLECTION,
"track": RequestType.TRACK,
"collectibles": RequestType.COLLECTIBLES,
playlist: RequestType.COLLECTION,
album: RequestType.COLLECTION,
track: RequestType.TRACK,
collectibles: RequestType.COLLECTIBLES
}

export const PlayerFlavor = Object.seal({
Expand All @@ -69,12 +75,7 @@ export const PlayerFlavor = Object.seal({

// Attemps to parse a the window's url.
// Returns null if the URL scheme is invalid.
const getRequestDataFromURL = ({
path,
type,
flavor,
matches
}) => {
const getRequestDataFromURL = ({ path, type, flavor, matches }) => {
// Get request type
const requestType = pathComponentRequestTypeMap[type]
if (!requestType) return null
Expand All @@ -96,7 +97,7 @@ const getRequestDataFromURL = ({
const { id, ownerId, isTwitter } = matches

// Validate the search params not null
if ([id, ownerId].some(e => e === null)) {
if ([id, ownerId].some((e) => e === null)) {
return null
}
// Parse them as ints
Expand All @@ -123,6 +124,8 @@ const getRequestDataFromURL = ({
isTwitter
}
}
case AUDIO_NFT_PLAYLIST_ROUTE:
case AUDIO_NFT_PLAYLIST_DISCORD_ROUTE:
case COLLECTIBLES_ROUTE:
case COLLECTIBLES_DISCORD_ROUTE: {
const { handle, isTwitter } = matches
Expand Down Expand Up @@ -228,16 +231,27 @@ const App = (props) => {
} else {
setDid404(false)
setCollectionsResponse(collection)
recordOpen(collection.id, collection.name, collection.ownerHandle, collection.collectionURLPath)
recordOpen(
collection.id,
collection.name,
collection.ownerHandle,
collection.collectionURLPath
)

// Set dominant color
const color = await getDominantColor(collection.coverArt)
setDominantColor({ primary: color, secondary: shadeColor(color, -20) })
setDominantColor({
primary: color,
secondary: shadeColor(color, -20)
})
}
} else if (requestType === RequestType.COLLECTIBLES) {
let collectibleData
if (request.collectibleId) {
collectibleData = await getCollectible(request.handle, request.collectibleId)
collectibleData = await getCollectible(
request.handle,
request.collectibleId
)
} else {
collectibleData = await getCollectibles(request.handle)
}
Expand All @@ -248,7 +262,12 @@ const App = (props) => {
} else {
setDid404(false)
setCollectiblesResponse(collectibleData)
recordOpen(request.collectibleId, collectibleData.name, request.handle, request.url)
recordOpen(
request.collectibleId,
collectibleData.name,
request.handle,
request.url
)
setDominantColor({ primary: '#fff' })
}
}
Expand Down Expand Up @@ -295,21 +314,22 @@ const App = (props) => {
setIsRetrying(false)
}

const isCompact = requestState && requestState.playerFlavor && requestState.playerFlavor === PlayerFlavor.COMPACT
const isTiny = requestState && requestState.playerFlavor && requestState.playerFlavor === PlayerFlavor.TINY
const isCompact =
requestState &&
requestState.playerFlavor &&
requestState.playerFlavor === PlayerFlavor.COMPACT
const isTiny =
requestState &&
requestState.playerFlavor &&
requestState.playerFlavor === PlayerFlavor.TINY
const mobileWebTwitter = isMobileWebTwitter(requestState?.isTwitter)

// The idea is to show nothing (null) until either we
// get metadata back from GA, or we pass the loading threshold
// and display the loading screen.
const renderPlayerContainer = () => {
if (didError) {
return (
<Error
onRetry={retryRequestMetadata}
isRetrying={isRetrying}
/>
)
return <Error onRetry={retryRequestMetadata} isRetrying={isRetrying} />
}

// Tiny variant renders its own deleted content
Expand All @@ -332,38 +352,42 @@ const App = (props) => {
return (
<CSSTransition
classNames={{
appear: mobileWebTwitter ? transitions.appearMobileWebTwitter : transitions.appear,
appearActive: mobileWebTwitter ? transitions.appearActiveMobileWebTwitter : transitions.appearActive
appear: mobileWebTwitter
? transitions.appearMobileWebTwitter
: transitions.appear,
appearActive: mobileWebTwitter
? transitions.appearActiveMobileWebTwitter
: transitions.appearActive
}}
appear
in
timeout={1000}
>
{tracksResponse && (
<TrackPlayerContainer
track={tracksResponse}
flavor={requestState.playerFlavor}
isTwitter={requestState.isTwitter}
backgroundColor={dominantColor.primary}
/>
)}
{collectionsResponse && (
<CollectionPlayerContainer
collection={collectionsResponse}
flavor={requestState.playerFlavor}
isTwitter={requestState.isTwitter}
backgroundColor={dominantColor.primary}
rowBackgroundColor={dominantColor.secondary}
/>
)}
{collectiblesResponse && (
<CollectiblesPlayerContainer
collectiblesInfo={collectiblesResponse}
flavor={requestState.playerFlavor}
isTwitter={requestState.isTwitter}
backgroundColor={dominantColor.primary}
/>
)}
{tracksResponse && (
<TrackPlayerContainer
track={tracksResponse}
flavor={requestState.playerFlavor}
isTwitter={requestState.isTwitter}
backgroundColor={dominantColor.primary}
/>
)}
{collectionsResponse && (
<CollectionPlayerContainer
collection={collectionsResponse}
flavor={requestState.playerFlavor}
isTwitter={requestState.isTwitter}
backgroundColor={dominantColor.primary}
rowBackgroundColor={dominantColor.secondary}
/>
)}
{collectiblesResponse && (
<CollectiblesPlayerContainer
collectiblesInfo={collectiblesResponse}
flavor={requestState.playerFlavor}
isTwitter={requestState.isTwitter}
backgroundColor={dominantColor.primary}
/>
)}
</CSSTransition>
)
}
Expand All @@ -372,21 +396,29 @@ const App = (props) => {
}

const renderPausePopover = () => {
if (!requestState || (!tracksResponse && !collectionsResponse && !collectiblesResponse)) {
if (
!requestState ||
(!tracksResponse && !collectionsResponse && !collectiblesResponse)
) {
return null
}

let artworkURL = tracksResponse?.coverArt || collectionsResponse?.coverArt || null
let artworkClickURL = tracksResponse?.urlPath || collectionsResponse?.collectionURLPath || null
let listenOnAudiusURL = tracksResponse?.urlPath || collectionsResponse?.collectionURLPath || null
let artworkURL =
tracksResponse?.coverArt || collectionsResponse?.coverArt || null
let artworkClickURL =
tracksResponse?.urlPath || collectionsResponse?.collectionURLPath || null
let listenOnAudiusURL =
tracksResponse?.urlPath || collectionsResponse?.collectionURLPath || null
let flavor = requestState.playerFlavor
return (<PausePopover
artworkURL={artworkURL}
artworkClickURL={artworkClickURL}
listenOnAudiusURL={listenOnAudiusURL}
flavor={flavor}
isMobileWebTwitter={mobileWebTwitter}
/>)
return (
<PausePopover
artworkURL={artworkURL}
artworkClickURL={artworkClickURL}
listenOnAudiusURL={listenOnAudiusURL}
flavor={flavor}
isMobileWebTwitter={mobileWebTwitter}
/>
)
}

useEffect(() => {
Expand All @@ -398,11 +430,15 @@ const App = (props) => {
return (
<div
id='app'
className={
cn(styles.app,
{ [styles.compactApp]: isCompact },
{ [styles.twitter]: requestState && requestState.isTwitter && !mobileWebTwitter}
)}>
className={cn(
styles.app,
{ [styles.compactApp]: isCompact },
{
[styles.twitter]:
requestState && requestState.isTwitter && !mobileWebTwitter
}
)}
>
<ToastContextProvider>
<PauseContextProvider>
<CardContextProvider>
Expand Down
14 changes: 9 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import Router from 'preact-router';
import App from './components/app';
import Router from 'preact-router'
import App from './components/app'
import {
HASH_ID_ROUTE,
ID_ROUTE,
COLLECTIBLES_ROUTE,
COLLECTIBLE_ID_ROUTE,
COLLECTIBLES_DISCORD_ROUTE,
COLLECTIBLE_ID_DISCORD_ROUTE,
} from './routes';
AUDIO_NFT_PLAYLIST_DISCORD_ROUTE,
AUDIO_NFT_PLAYLIST_ROUTE
} from './routes'

import './index.css';
import './index.css'

const Index = () => (
<Router>
<App path={AUDIO_NFT_PLAYLIST_ROUTE} type={'collectibles'} />
<App path={AUDIO_NFT_PLAYLIST_DISCORD_ROUTE} type={'collectibles'} />
<App path={COLLECTIBLES_ROUTE} type={'collectibles'} />
<App path={COLLECTIBLE_ID_ROUTE} type={'collectibles'} />
<App path={COLLECTIBLES_DISCORD_ROUTE} type={'collectibles'} />
Expand All @@ -25,4 +29,4 @@ const Index = () => (
</Router>
)

export default Index;
export default Index
4 changes: 3 additions & 1 deletion src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const ROUTE_PREFIX = process.env.PREACT_APP_HOST_PREFIX
export const ID_ROUTE = `${ROUTE_PREFIX}/:type`
export const HASH_ID_ROUTE = `${ROUTE_PREFIX}/:type/:hashId`

export const AUDIO_NFT_PLAYLIST_ROUTE = `${ROUTE_PREFIX}/:handle/audio-nft-playlist`
export const COLLECTIBLES_ROUTE = `${ROUTE_PREFIX}/:handle/collectibles`
export const COLLECTIBLE_ID_ROUTE = `${ROUTE_PREFIX}/:handle/collectibles/:collectibleId`

Expand All @@ -11,5 +12,6 @@ export const COLLECTIBLE_ID_ROUTE = `${ROUTE_PREFIX}/:handle/collectibles/:colle
// We add support for Discord by offering a an alternative route "hack"
// These URLs are *never* to be shared more broadly than in the
// general-admission response to a Discordbot.
export const AUDIO_NFT_PLAYLIST_DISCORD_ROUTE = `${ROUTE_PREFIX}/track/:handle/audio-nft-playlist`
export const COLLECTIBLES_DISCORD_ROUTE = `${ROUTE_PREFIX}/track/:handle/collectibles`
export const COLLECTIBLE_ID_DISCORD_ROUTE = `${ROUTE_PREFIX}/track/:handle/collectibles/:collectibleId`
export const COLLECTIBLE_ID_DISCORD_ROUTE = `${ROUTE_PREFIX}/track/:handle/collectibles/:collectibleId`

0 comments on commit 75d87a4

Please sign in to comment.