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
56 changes: 20 additions & 36 deletions components/upload-progress-fullpage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,11 @@ import useSwr from 'swr';
import Layout from './layout';
import Button from './button';
import Cookies from 'js-cookie';
import { reportUploadTelemetry, UploadTelemetry } from '../lib/telemetry';

const fetcher = (url: string) => fetch(url).then((res) => res.json());
const MAX_VIDEO_DURATION_MIN = 60;

type ChunkInfo = {
size: number;
uploadStarted: number;
uploadFinished?: number;
}

type UploadTelemetry = {
fileSize: number;
uploadStarted: number;
uploadFinished?: number;
chunkSize: number;
dynamicChunkSize: boolean;
chunks: ChunkInfo[];
};

type Props = {
file: File;
resetPage: () => void;
Expand All @@ -32,6 +18,8 @@ type Props = {
const UploadProgressFullpage: React.FC<Props> = ({ file, resetPage }) => {
const [isUploading, setIsUploading] = useState(false);
const [uploadId, setUploadId] = useState('');
// Add this ref to store the current upload ID
const currentUploadIdRef = useRef('');
const [progress, setProgress] = useState(0);
const [isPreparing, setIsPreparing] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
Expand All @@ -46,18 +34,15 @@ const UploadProgressFullpage: React.FC<Props> = ({ file, resetPage }) => {

const createUpload = async () => {
try {
return fetch('/api/uploads', {
method: 'POST',
})
.then((res) => res.json())
.then(({ id, url }) => {
setUploadId(id);
return url;
});
const res = await fetch('/api/uploads', { method: 'POST' });
const { id, url } = await res.json();
setUploadId(id);
currentUploadIdRef.current = id; // Store the current upload ID in the ref
return url;
} catch (e) {
console.error('Error in createUpload', e); // eslint-disable-line no-console
setErrorMessage('Error creating upload');
return Promise.reject(e);
return e;
}
};

Expand Down Expand Up @@ -100,26 +85,25 @@ const UploadProgressFullpage: React.FC<Props> = ({ file, resetPage }) => {

upChunk.on('error', (err) => {
setErrorMessage(err.detail);
reportUploadTelemetry({
...uploadAnalytics,
uploadId: currentUploadIdRef.current,
uploadFinished: Date.now(),
uploadErrored: true,
message: err.detail,
});
});

upChunk.on('progress', (progressEvt) => {
setProgress(Math.floor(progressEvt.detail));
});

upChunk.on('success', () => {
uploadAnalytics.uploadFinished = Date.now();

fetch('/api/telemetry', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'upload',
data: uploadAnalytics,
})
reportUploadTelemetry({
...uploadAnalytics,
uploadId: currentUploadIdRef.current,
uploadFinished: Date.now(),
});

setIsPreparing(true);
});
} catch (err) {
Expand Down
30 changes: 30 additions & 0 deletions lib/telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export type ChunkInfo = {
size: number;
uploadStarted: number;
uploadFinished?: number;
};

export type UploadTelemetry = {
uploadId?: string;
message?: string;
fileSize?: number;
uploadStarted?: number;
uploadFinished?: number;
uploadErrored?: boolean;
dynamicChunkSize?: boolean;
chunkSize?: number;
chunks: ChunkInfo[];
}

export function reportUploadTelemetry(data: UploadTelemetry) {
fetch('/api/telemetry', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'upload',
data,
}),
});
}
60 changes: 23 additions & 37 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,12 @@ import Link from 'next/link';
import Button from '../components/button';
import Layout from '../components/layout';
import { breakpoints } from '../style-vars';
import { reportUploadTelemetry, UploadTelemetry, ChunkInfo } from '../lib/telemetry';

const fetcher = (url: string) => fetch(url).then((res) => res.json());

type Props = null;

type ChunkInfo = {
size: number;
uploadStarted: number;
uploadFinished?: number;
}

type UploadTelemetry = {
fileSize: number;
uploadStarted: number;
uploadFinished?: number;
dynamicChunkSize?: boolean;
chunkSize: number;
chunks: ChunkInfo[];
};

const Index: React.FC<Props> = () => {
const [isUploading, setIsUploading] = useState<boolean>(false);
const [uploadId, setUploadId] = useState<string>('');
Expand All @@ -45,18 +31,14 @@ const Index: React.FC<Props> = () => {

const createUpload = async () => {
try {
return fetch('/api/uploads', {
method: 'POST',
})
.then((res) => res.json())
.then(({ id, url }) => {
setUploadId(id);
return url;
});
const res = await fetch('/api/uploads', { method: 'POST' });
const { id, url } = await res.json();
setUploadId(id);
return url;
} catch (e) {
console.error('Error in createUpload', e);
setErrorMessage('Error creating upload.');
return Promise.reject(e);
return e;
}
};

Expand Down Expand Up @@ -99,23 +81,26 @@ const Index: React.FC<Props> = () => {
};

const handleSuccess: MuxUploaderProps['onSuccess'] = () => {
const finalAnalytics = {...uploadAnalytics};
finalAnalytics.uploadFinished = Date.now();

fetch('/api/telemetry', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'upload',
data: finalAnalytics,
})
reportUploadTelemetry({
...uploadAnalytics,
uploadFinished: Date.now(),
uploadId,
});

setIsPreparing(true);
};

const handleUploadError: MuxUploaderProps['onUploadError'] = ({ detail }) => {
setIsUploading(false);
reportUploadTelemetry({
...uploadAnalytics,
uploadId,
uploadFinished: Date.now(),
uploadErrored: true,
message: detail.message,
});
};


const [isDynamicChunkSizeSet, setIsDynamicChunkSizeSet] = useState(false);
useEffect(() => {
const isDynamic: string = Cookies.get('dynamicChunkSize') || '';
Expand Down Expand Up @@ -165,6 +150,7 @@ const Index: React.FC<Props> = () => {
onChunkAttempt={handleChunkAttempt}
onChunkSuccess={handleChunkSuccess}
onSuccess={handleSuccess}
onUploadError={handleUploadError}
dynamicChunkSize={isDynamicChunkSizeSet}
endpoint={createUpload}
style={{ fontSize: isUploading ? '4vw': '26px' }}
Expand Down