Skip to content

Commit 1e4ca71

Browse files
committed
show 'Preparing your video for casting…' during finalize step
1 parent d775cbb commit 1e4ca71

4 files changed

Lines changed: 57 additions & 5 deletions

File tree

src/App.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { useState, useCallback, useRef, useEffect } from 'react'
22
import { DropZone } from './components/DropZone'
33
import { Player } from './components/Player'
4-
import { UploadProgress } from './components/UploadProgress'
4+
import { UploadProgress, FinalizingProgress } from './components/UploadProgress'
55
import { uploadVideo, deleteVideo } from './api'
66
import { MAX_FILE_SIZE } from './config'
77
import './App.css'
88

99
type AppState =
1010
| { phase: 'idle' }
1111
| { phase: 'uploading'; file: File; progress: number }
12+
| { phase: 'finalizing'; file: File }
1213
| { phase: 'ready'; file: File; videoUrl: string; videoId: string }
1314
| { phase: 'error'; message: string }
1415

@@ -45,8 +46,13 @@ export default function App() {
4546
setState({ phase: 'uploading', file, progress: 0 })
4647

4748
try {
48-
const result = await uploadVideo(file, (progress) => {
49-
setState(prev => prev.phase === 'uploading' ? { ...prev, progress } : prev)
49+
const result = await uploadVideo(file, {
50+
onProgress: (progress) => {
51+
setState(prev => prev.phase === 'uploading' ? { ...prev, progress } : prev)
52+
},
53+
onFinalizing: () => {
54+
setState(prev => prev.phase === 'uploading' ? { phase: 'finalizing', file: prev.file } : prev)
55+
},
5056
})
5157
videoIdRef.current = result.id
5258
setState({ phase: 'ready', file, videoUrl: result.url, videoId: result.id })
@@ -76,6 +82,10 @@ export default function App() {
7682
<UploadProgress filename={state.file.name} progress={state.progress} />
7783
)}
7884

85+
{state.phase === 'finalizing' && (
86+
<FinalizingProgress filename={state.file.name} />
87+
)}
88+
7989
{state.phase === 'ready' && (
8090
<Player
8191
videoUrl={state.videoUrl}

src/api.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ interface UploadResult {
66
url: string
77
}
88

9+
interface UploadCallbacks {
10+
onProgress: (progress: number) => void
11+
onFinalizing: () => void
12+
}
13+
914
export async function uploadVideo(
1015
file: File,
11-
onProgress: (progress: number) => void
16+
callbacks: UploadCallbacks
1217
): Promise<UploadResult> {
1318
// Step 1: Initialize upload
1419
const initRes = await fetch(`${WORKER_URL}/upload/init`, {
@@ -44,10 +49,12 @@ export async function uploadVideo(
4449
throw new Error(`Chunk ${i + 1}/${totalChunks} failed (${res.status})`)
4550
}
4651

47-
onProgress(Math.round(((i + 1) / totalChunks) * 100))
52+
callbacks.onProgress(Math.round(((i + 1) / totalChunks) * 100))
4853
}
4954

5055
// Step 3: Finalize
56+
callbacks.onFinalizing()
57+
5158
const finalRes = await fetch(`${WORKER_URL}/upload/${id}/finalize`, {
5259
method: 'POST',
5360
})

src/components/UploadProgress.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,28 @@
3838
transition: width 0.3s ease;
3939
}
4040

41+
.progress-bar.indeterminate::after {
42+
content: '';
43+
display: block;
44+
height: 100%;
45+
width: 40%;
46+
background: #4a9eff;
47+
border-radius: 3px;
48+
animation: indeterminate 1.5s ease-in-out infinite;
49+
}
50+
51+
@keyframes indeterminate {
52+
0% { transform: translateX(-100%); }
53+
100% { transform: translateX(350%); }
54+
}
55+
4156
.progress-text {
4257
color: #4a9eff;
4358
font-size: 0.9rem;
4459
font-weight: 600;
4560
}
61+
62+
.finalizing-text {
63+
color: #888;
64+
font-weight: 400;
65+
}

src/components/UploadProgress.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,18 @@ export function UploadProgress({ filename, progress }: UploadProgressProps) {
1717
</div>
1818
)
1919
}
20+
21+
interface FinalizingProgressProps {
22+
filename: string
23+
}
24+
25+
export function FinalizingProgress({ filename }: FinalizingProgressProps) {
26+
return (
27+
<div className="upload-progress">
28+
<div className="upload-icon">⚙️</div>
29+
<div className="upload-filename">{filename}</div>
30+
<div className="progress-bar indeterminate" />
31+
<div className="progress-text finalizing-text">Preparing your video for casting…</div>
32+
</div>
33+
)
34+
}

0 commit comments

Comments
 (0)