Skip to content

Commit

Permalink
[C-5479] Add error states for track replace progress (#10656)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyle-Shanks authored Dec 10, 2024
1 parent f28f80f commit 4a39102
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type ReplaceTrackProgressModalState = {
upload: number
transcode: number
}
error: boolean
}

const replaceTrackProgressModal = createModal<ReplaceTrackProgressModalState>({
Expand All @@ -14,7 +15,8 @@ const replaceTrackProgressModal = createModal<ReplaceTrackProgressModalState>({
progress: {
upload: 0,
transcode: 0
}
},
error: false
},
sliceSelector: (state) => state.ui.modals
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useReplaceTrackProgressModal } from '@audius/common/store'

import {
Button,
Flex,
IconAudiusLogo,
IconValidationCheck,
Expand All @@ -15,45 +16,59 @@ const messages = {
'Please hold on while we upload and replace the file for this track.',
inProgress: 'Upload in progress',
finalizing: 'Finalizing...',
cancel: 'Cancel'
error: 'Something went wrong. Please try again later',
close: 'Close'
}

export const ReplaceTrackProgressDrawer = () => {
const { data } = useReplaceTrackProgressModal()
const { progress } = data
const { data, onClose } = useReplaceTrackProgressModal()
const { progress, error } = data

const uploadProgress = Math.min(progress.upload + progress.transcode, 2) / 2
const isUploadComplete = uploadProgress >= 1

return (
<AppDrawer modalName='ReplaceTrackProgress' isFullscreen>
<Flex h='100%' justifyContent='center'>
<Flex direction='column' gap='3xl' ph='2xl' pb='3xl'>
<Flex alignItems='center' direction='column' gap='xl'>
<IconAudiusLogo height={48} width={48} color='default' />
<Text variant='body' size='l'>
{messages.description}
</Text>
{error ? (
<Flex direction='column' gap='3xl' ph='2xl'>
<Flex w={220} alignSelf='center' alignItems='center'>
<Text variant='body' size='l' color='danger' textAlign='center'>
{messages.error}
</Text>
</Flex>
<Button variant='secondary' onPress={onClose}>
{messages.close}
</Button>
</Flex>
<Flex direction='column'>
<Flex justifyContent='space-between' direction='row'>
<Text variant='label' size='s'>
{isUploadComplete ? messages.finalizing : messages.inProgress}
) : (
<Flex direction='column' gap='3xl' ph='2xl' pb='3xl'>
<Flex alignItems='center' direction='column' gap='xl'>
<IconAudiusLogo height={48} width={48} color='default' />
<Text variant='body' size='l'>
{messages.description}
</Text>
<Flex alignItems='center' gap='l' direction='row'>
</Flex>
<Flex direction='column'>
<Flex justifyContent='space-between' direction='row'>
<Text variant='label' size='s'>
{Math.round(uploadProgress * 100)}%
{isUploadComplete ? messages.finalizing : messages.inProgress}
</Text>
{isUploadComplete ? (
<IconValidationCheck size='s' />
) : (
<LoadingSpinner style={{ height: 16, width: 16 }} />
)}
<Flex alignItems='center' gap='l' direction='row'>
<Text variant='label' size='s'>
{Math.round(uploadProgress * 100)}%
</Text>
{isUploadComplete ? (
<IconValidationCheck size='s' />
) : (
<LoadingSpinner style={{ height: 16, width: 16 }} />
)}
</Flex>
</Flex>
<ProgressBar progress={uploadProgress} max={1} />
</Flex>
<ProgressBar progress={uploadProgress} max={1} />
</Flex>
</Flex>
)}
</Flex>
</AppDrawer>
)
Expand Down
129 changes: 74 additions & 55 deletions packages/web/src/common/store/upload/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1196,76 +1196,95 @@ export function* updateTrackAudioAsync(
yield* call(waitForWrite)
const payload = action.payload

const tracks = yield* call(retrieveTracks, {
trackIds: [payload.trackId]
})
try {
const tracks = yield* call(retrieveTracks, {
trackIds: [payload.trackId]
})

if (tracks.length === 0) return
const track = tracks[0]
const sdk = yield* getSDK()
const userId = yield* select(accountSelectors.getUserId)
if (!tracks[0]) {
throw new Error('Missing track for track audio replace.')
}
const track = tracks[0]
const sdk = yield* getSDK()
const userId = yield* select(accountSelectors.getUserId)

if (!track) return
if (!userId) {
throw new Error('No user id found during upload. Not signed in?')
}
if (!userId) {
throw new Error('No user id found during upload. Not signed in?')
}

const metadata = trackMetadataForUploadToSdk({
...track,
...(payload.metadata ?? {})
})
const metadata = trackMetadataForUploadToSdk({
...track,
...(payload.metadata ?? {})
})

const dispatch = yield* getContext('dispatch')
const handleProgressUpdate = (progress: Parameters<ProgressHandler>[0]) => {
if (!('audio' in progress)) return
const { upload, transcode } = progress.audio
const dispatch = yield* getContext('dispatch')
const handleProgressUpdate = (progress: Parameters<ProgressHandler>[0]) => {
if (!('audio' in progress)) return
const { upload, transcode } = progress.audio

const uploadVal =
transcode === undefined ? (upload?.loaded ?? 0) / (upload?.total ?? 1) : 1
const uploadVal =
transcode === undefined
? (upload?.loaded ?? 0) / (upload?.total ?? 1)
: 1

dispatch(
replaceTrackProgressModalActions.set({
progress: { upload: uploadVal, transcode: transcode?.decimal ?? 0 },
error: false
})
)
}

dispatch(
yield* put(
replaceTrackProgressModalActions.set({
progress: { upload: uploadVal, transcode: transcode?.decimal ?? 0 }
progress: { upload: 0, transcode: 0 },
error: false
})
)
}
const updatedMetadata = yield* call(
[sdk.tracks, sdk.tracks.uploadTrackFiles],
{
userId: Id.parse(userId),
trackFile: fileToSdk(payload.file, 'audio'),
metadata,
onProgress: handleProgressUpdate
}
)

const updatedMetadata = yield* call(
[sdk.tracks, sdk.tracks.uploadTrackFiles],
{
userId: Id.parse(userId),
trackFile: fileToSdk(payload.file, 'audio'),
metadata,
onProgress: handleProgressUpdate
const newMetadata = {
...metadata,
orig_file_cid: updatedMetadata.origFileCid,
bpm: metadata.isCustomBpm ? track.bpm : null,
musical_key: metadata.isCustomMusicalKey ? metadata.musicalKey : null,
audio_analysis_error_count: 0,
orig_filename: updatedMetadata.origFilename || '',
preview_cid: updatedMetadata.previewCid || '',
preview_start_seconds: updatedMetadata.previewStartSeconds ?? 0,
track_cid: updatedMetadata.trackCid || '',
audio_upload_id: updatedMetadata.audioUploadId,
duration: updatedMetadata.duration
}
)

const newMetadata = {
...metadata,
orig_file_cid: updatedMetadata.origFileCid,
bpm: metadata.isCustomBpm ? track.bpm : null,
musical_key: metadata.isCustomMusicalKey ? metadata.musicalKey : null,
audio_analysis_error_count: 0,
orig_filename: updatedMetadata.origFilename || '',
preview_cid: updatedMetadata.previewCid || '',
preview_start_seconds: updatedMetadata.previewStartSeconds ?? 0,
track_cid: updatedMetadata.trackCid || '',
audio_upload_id: updatedMetadata.audioUploadId,
duration: updatedMetadata.duration
}

yield* put(
cacheTracksActions.editTrack(
track.track_id,
newMetadata as TrackMetadataForUpload
yield* put(
cacheTracksActions.editTrack(
track.track_id,
newMetadata as TrackMetadataForUpload
)
)
)

// Delay to allow the user to see that the track replace upload has finished
yield* delay(3000)
// Delay to allow the user to see that the track replace upload has finished
yield* delay(3000)

yield* put(replaceTrackProgressModalActions.close())
yield* put(push(track.permalink))
yield* put(replaceTrackProgressModalActions.close())
yield* put(push(track.permalink))
} catch (e) {
yield* put(
replaceTrackProgressModalActions.set({
progress: { upload: 0, transcode: 0 },
error: true
})
)
}
}

function* watchUploadTracks() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,68 @@ import {
IconAudiusLogo,
ProgressBar,
IconValidationCheck,
LoadingSpinner
LoadingSpinner,
Button
} from '@audius/harmony'

const messages = {
description:
'Please hold on while we upload and replace the file for this track.',
inProgress: 'Upload in progress',
finalizing: 'Finalizing...'
finalizing: 'Finalizing...',
error: 'Something went wrong. Please try again later',
close: 'Close'
}

export const ReplaceTrackProgressModal = () => {
const { data, isOpen, onClose } = useReplaceTrackProgressModal()
const { progress } = data
const { progress, error } = data

const uploadProgress = Math.min(progress.upload + progress.transcode, 2) / 2
const isUploadComplete = uploadProgress >= 1

return (
<Modal isOpen={isOpen} onClose={onClose} size='small'>
<ModalContent>
<Flex direction='column' gap='unit14'>
<Flex alignItems='center' direction='column' gap='xl'>
<IconAudiusLogo height={48} width={48} color='default' />
<Text variant='body' size='l'>
{messages.description}
</Text>
{error ? (
<Flex direction='column' gap='3xl' pt='3xl'>
<Flex w={220} alignSelf='center' alignItems='center'>
<Text variant='body' size='l' color='danger' textAlign='center'>
{messages.error}
</Text>
</Flex>
<Button variant='secondary' onClick={onClose}>
{messages.close}
</Button>
</Flex>
<Flex direction='column' gap='m'>
<Flex justifyContent='space-between'>
<Text variant='label' size='s'>
{isUploadComplete ? messages.finalizing : messages.inProgress}
) : (
<Flex direction='column' gap='unit14'>
<Flex alignItems='center' direction='column' gap='xl'>
<IconAudiusLogo height={48} width={48} color='default' />
<Text variant='body' size='l'>
{messages.description}
</Text>
<Flex alignItems='center' gap='l'>
</Flex>
<Flex direction='column' gap='m'>
<Flex justifyContent='space-between'>
<Text variant='label' size='s'>
{Math.round(uploadProgress * 100)}%
{isUploadComplete ? messages.finalizing : messages.inProgress}
</Text>
{isUploadComplete ? (
<IconValidationCheck size='s' />
) : (
<LoadingSpinner css={{ height: 16, width: 16 }} />
)}
<Flex alignItems='center' gap='l'>
<Text variant='label' size='s'>
{Math.round(uploadProgress * 100)}%
</Text>
{isUploadComplete ? (
<IconValidationCheck size='s' />
) : (
<LoadingSpinner css={{ height: 16, width: 16 }} />
)}
</Flex>
</Flex>
<ProgressBar value={uploadProgress * 100} />
</Flex>
<ProgressBar value={uploadProgress * 100} />
</Flex>
</Flex>
)}
</ModalContent>
</Modal>
)
Expand Down

0 comments on commit 4a39102

Please sign in to comment.