Refactor file upload to use SDK instead of XMLHttpRequest
Replaced manual XMLHttpRequest implementation with the SDK's `uploadFile` method for handling file uploads to presigned URLs. This simplifies the code, leverages built-in features like progress tracking, and improves error handling. Added token extraction and upload progress updates to maintain functionality.
This commit is contained in:
@@ -17,7 +17,8 @@ logger.info(f"Starting app!!!")
|
|||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
title=settings.PROJECT_NAME,
|
title=settings.PROJECT_NAME,
|
||||||
version=settings.VERSION,
|
version=settings.VERSION,
|
||||||
openapi_url=f"{settings.API_VERSION_STR}/openapi.json"
|
openapi_url=f"{settings.API_VERSION_STR}/openapi.json",
|
||||||
|
debug=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set up CORS middleware
|
# Set up CORS middleware
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { useState, useCallback, useEffect } from "react";
|
import { useState, useCallback, useEffect } from "react";
|
||||||
import { useMutation } from "@tanstack/react-query";
|
import { useMutation } from "@tanstack/react-query";
|
||||||
import { generatePresignedUrl, PresignedUrlResponse } from "@/client";
|
import {
|
||||||
|
generatePresignedUrl,
|
||||||
|
uploadFile as uploadFileSdk,
|
||||||
|
PresignedUrlResponse,
|
||||||
|
} from "@/client";
|
||||||
|
|
||||||
export interface FileUploadState {
|
export interface FileUploadState {
|
||||||
file?: File;
|
file?: File;
|
||||||
@@ -58,26 +62,48 @@ export function usePresignedUpload(options: UsePresignedUploadOptions = {}) {
|
|||||||
const uploadFileToPresignedUrl = useCallback(
|
const uploadFileToPresignedUrl = useCallback(
|
||||||
async (file: File, uploadUrl: string): Promise<void> => {
|
async (file: File, uploadUrl: string): Promise<void> => {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
const xhr = new XMLHttpRequest();
|
try {
|
||||||
|
// Use the SDK's uploadFile method instead of direct XMLHttpRequest
|
||||||
|
|
||||||
xhr.upload.onprogress = ({ loaded, total }) => {
|
// Create form data for the file
|
||||||
const progress = total ? Math.round((loaded / total) * 100) : 0;
|
const formData = new FormData();
|
||||||
setUploadState((prev) => ({ ...prev, progress }));
|
formData.append("file", file);
|
||||||
};
|
|
||||||
|
|
||||||
xhr.onload = () => {
|
// Get the token from the upload URL
|
||||||
if (xhr.status >= 200 && xhr.status < 300) {
|
// Assuming the uploadUrl format has a token part after the last '/'
|
||||||
resolve();
|
const token = uploadUrl.split("/").pop();
|
||||||
} else {
|
|
||||||
reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`));
|
if (!token) {
|
||||||
|
reject(new Error("Invalid upload URL - missing token"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
xhr.onerror = () =>
|
// Create a progress tracker
|
||||||
reject(new Error("Network error during file upload."));
|
const onProgress = (progressEvent: any) => {
|
||||||
xhr.open("PUT", uploadUrl);
|
const progress =
|
||||||
xhr.setRequestHeader("Content-Type", file.type);
|
progressEvent.loaded && progressEvent.total
|
||||||
xhr.send(file);
|
? Math.round((progressEvent.loaded / progressEvent.total) * 100)
|
||||||
|
: 0;
|
||||||
|
setUploadState((prev) => ({ ...prev, progress }));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Call the SDK's upload method
|
||||||
|
uploadFileSdk({
|
||||||
|
path: { token },
|
||||||
|
body: { file },
|
||||||
|
onUploadProgress: onProgress,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
|
reject(
|
||||||
|
new Error(`Upload failed: ${error.message || "Unknown error"}`),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
reject(new Error(`Network error during file upload: ${error}`));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
|
|||||||
Reference in New Issue
Block a user