From 4a3910285eecfd3accdb0fb8434298ecf7f4c963 Mon Sep 17 00:00:00 2001 From: Kyle Shanks Date: Tue, 10 Dec 2024 14:05:32 -0500 Subject: [PATCH] [C-5479] Add error states for track replace progress (#10656) --- .../replace-track-progress-modal/index.ts | 4 +- .../components/ReplaceTrackProgressDrawer.tsx | 59 +++++--- packages/web/src/common/store/upload/sagas.ts | 129 ++++++++++-------- .../ReplaceTrackProgressModal.tsx | 60 +++++--- 4 files changed, 152 insertions(+), 100 deletions(-) diff --git a/packages/common/src/store/ui/modals/replace-track-progress-modal/index.ts b/packages/common/src/store/ui/modals/replace-track-progress-modal/index.ts index c44763df9df..817a4a763ac 100644 --- a/packages/common/src/store/ui/modals/replace-track-progress-modal/index.ts +++ b/packages/common/src/store/ui/modals/replace-track-progress-modal/index.ts @@ -5,6 +5,7 @@ export type ReplaceTrackProgressModalState = { upload: number transcode: number } + error: boolean } const replaceTrackProgressModal = createModal({ @@ -14,7 +15,8 @@ const replaceTrackProgressModal = createModal({ progress: { upload: 0, transcode: 0 - } + }, + error: false }, sliceSelector: (state) => state.ui.modals }) diff --git a/packages/mobile/src/screens/edit-track-screen/components/ReplaceTrackProgressDrawer.tsx b/packages/mobile/src/screens/edit-track-screen/components/ReplaceTrackProgressDrawer.tsx index 8dec4a718d8..ff8798ae5d8 100644 --- a/packages/mobile/src/screens/edit-track-screen/components/ReplaceTrackProgressDrawer.tsx +++ b/packages/mobile/src/screens/edit-track-screen/components/ReplaceTrackProgressDrawer.tsx @@ -1,6 +1,7 @@ import { useReplaceTrackProgressModal } from '@audius/common/store' import { + Button, Flex, IconAudiusLogo, IconValidationCheck, @@ -15,12 +16,13 @@ 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 @@ -28,32 +30,45 @@ export const ReplaceTrackProgressDrawer = () => { return ( - - - - - {messages.description} - + {error ? ( + + + + {messages.error} + + + - - - - {isUploadComplete ? messages.finalizing : messages.inProgress} + ) : ( + + + + + {messages.description} - + + + - {Math.round(uploadProgress * 100)}% + {isUploadComplete ? messages.finalizing : messages.inProgress} - {isUploadComplete ? ( - - ) : ( - - )} + + + {Math.round(uploadProgress * 100)}% + + {isUploadComplete ? ( + + ) : ( + + )} + + - - + )} ) diff --git a/packages/web/src/common/store/upload/sagas.ts b/packages/web/src/common/store/upload/sagas.ts index 89e0772162b..c15cd24555d 100644 --- a/packages/web/src/common/store/upload/sagas.ts +++ b/packages/web/src/common/store/upload/sagas.ts @@ -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[0]) => { - if (!('audio' in progress)) return - const { upload, transcode } = progress.audio + const dispatch = yield* getContext('dispatch') + const handleProgressUpdate = (progress: Parameters[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() { diff --git a/packages/web/src/components/replace-track-progress-modal/ReplaceTrackProgressModal.tsx b/packages/web/src/components/replace-track-progress-modal/ReplaceTrackProgressModal.tsx index ebc042676c5..51f772cb701 100644 --- a/packages/web/src/components/replace-track-progress-modal/ReplaceTrackProgressModal.tsx +++ b/packages/web/src/components/replace-track-progress-modal/ReplaceTrackProgressModal.tsx @@ -7,19 +7,22 @@ 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 @@ -27,32 +30,45 @@ export const ReplaceTrackProgressModal = () => { return ( - - - - - {messages.description} - + {error ? ( + + + + {messages.error} + + + - - - - {isUploadComplete ? messages.finalizing : messages.inProgress} + ) : ( + + + + + {messages.description} - + + + - {Math.round(uploadProgress * 100)}% + {isUploadComplete ? messages.finalizing : messages.inProgress} - {isUploadComplete ? ( - - ) : ( - - )} + + + {Math.round(uploadProgress * 100)}% + + {isUploadComplete ? ( + + ) : ( + + )} + + - - + )} )