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
24 changes: 23 additions & 1 deletion packages/embed/src/components/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ const App = (props) => {
const searchParams = useSearchParams()
const [didError, setDidError] = useState(false) // General errors
const [did404, setDid404] = useState(false) // 404s indicate content was deleted
// A track whose owner is no longer active - the artist deactivated their own
// account, or the account was delisted by the trusted notifier. Rendered with
// the same "not available" treatment as a 404, but with its own copy.
const [isUnavailable, setIsUnavailable] = useState(false)
const [requestState, setRequestState] = useState(null) // Parsed request state
const [isRetrying, setIsRetrying] = useState(false) // Currently retrying?

Expand Down Expand Up @@ -188,10 +192,20 @@ const App = (props) => {

if (!track) {
setDid404(true)
setIsUnavailable(false)
setTracksResponse(null)
} else if (track.isStreamable === false) {
// The stream endpoint refuses these, so there is nothing to play -
// don't render the title, artist and artwork either. Checked with an
// explicit `=== false` because an absent field must not read as
// unavailable.
setDid404(true)
setIsUnavailable(true)
setTracksResponse(null)
} else {
const events = await getEntityEvents(track.id, 'track')
setDid404(false)
setIsUnavailable(false)
setTracksResponse({ ...track, events })
recordOpen(
decodeHashId(track.id),
Expand Down Expand Up @@ -234,9 +248,11 @@ const App = (props) => {

if (!collection) {
setDid404(true)
setIsUnavailable(false)
setCollectionsResponse(null)
} else {
setDid404(false)
setIsUnavailable(false)
setCollectionsResponse(collection)
recordOpen(
decodeHashId(collection.id),
Expand Down Expand Up @@ -273,6 +289,7 @@ const App = (props) => {
setDidError(true)
setShowLoadingAnimation(false)
setDid404(false)
setIsUnavailable(false)
setTracksResponse(null)
setCollectionsResponse(null)
}
Expand Down Expand Up @@ -334,7 +351,12 @@ const App = (props) => {

// Tiny variant renders its own deleted content
if (did404) {
return <DeletedContent flavor={requestState.playerFlavor} />
return (
<DeletedContent
flavor={requestState.playerFlavor}
isUnavailable={isUnavailable}
/>
)
}

if (showLoadingAnimation && !isTiny) {
Expand Down
22 changes: 17 additions & 5 deletions packages/embed/src/components/deleted/DeletedContent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,36 @@ import DeletedContentTiny from './DeletedContentTiny'
const messages = {
mainLabel: 'This content was removed by the creator.',
deleted: 'Deleted',
unavailable: 'This track can no longer be streamed on Audius.',
subLabel1: 'Unlimited Uploads.',
subLabel2: '320kbps Streaming.',
subLabel3: '100% Free.',
buttonLabel: 'Find more on'
}

const DeletedContent = ({ flavor, isBlocked }) => {
const DeletedContent = ({ flavor, isBlocked, isUnavailable }) => {
const onClickFindMore = () => {
window.open(getCopyableLink(), '_blank')
}

// `unavailable` says nothing about the account on purpose: the same flag
// covers a self deactivation and a delisted account, and we shouldn't tell
// listeners the creator removed the track when moderation suppressed it.
const label = isUnavailable
? messages.unavailable
: isBlocked
? messages.deleted
: messages.mainLabel

const isCard = flavor === PlayerFlavor.CARD
const isTiny = flavor === PlayerFlavor.TINY
if (isTiny) {
return (
<DeletedContentTiny onClick={onClickFindMore} isBlocked={isBlocked} />
<DeletedContentTiny
onClick={onClickFindMore}
isBlocked={isBlocked}
isUnavailable={isUnavailable}
/>
)
}

Expand All @@ -41,9 +55,7 @@ const DeletedContent = ({ flavor, isBlocked }) => {
}}
/>
)}
<div className={styles.label}>
{isBlocked ? messages.deleted : messages.mainLabel}
</div>
<div className={styles.label}>{label}</div>
{isCard && (
<div className={styles.subLabel}>
<span>{messages.subLabel1}</span>
Expand Down
17 changes: 12 additions & 5 deletions packages/embed/src/components/deleted/DeletedContentTiny.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,27 @@ import styles from './DeletedContentTiny.module.css'

const messages = {
deletedBy: 'Track Deleted By Artist',
deleted: 'Deleted'
deleted: 'Deleted',
unavailable: 'Track Unavailable'
}

const DeletedContentTiny = ({ onClick, isBlocked }) => {
const DeletedContentTiny = ({ onClick, isBlocked, isUnavailable }) => {
// `unavailable` says nothing about the account on purpose: the same flag
// covers a self deactivation and a delisted account.
const label = isUnavailable
? messages.unavailable
: isBlocked
? messages.deleted
: messages.deletedBy

return (
<div className={styles.wrapper}>
<PlayButton
playingState={PlayingState.Stopped}
className={styles.playButton}
/>
<div className={styles.container} onClick={onClick}>
<div className={styles.info}>
{isBlocked ? messages.deleted : messages.deletedBy}
</div>
<div className={styles.info}>{label}</div>
<AudiusLogoGlyph className={styles.logo} />
</div>
</div>
Expand Down
Loading