REFACTOR http requests in frontend

This commit is contained in:
2025-07-14 23:06:27 +02:00
parent 416da3281a
commit 0fbb68fdb7
4 changed files with 138 additions and 141 deletions

View File

@@ -34,30 +34,32 @@ const ClipEdit = () => {
const sendData = async() => { const sendData = async() => {
if (!id) return; if (!id) return;
setDownloadable(false); editFile(id, outputMetadata)
.then(() => {
const edited = await editFile(id, outputMetadata, setError); processFile(id)
.catch((err: Error) => setError(`Failed to process file: ${err.message}`));
if (!edited) { })
return; .catch((err: Error) => setError(`Failed to edit file: ${err.message}`));
}
const processed = await processFile(id, setError); const interval = setInterval(async() => await pollProgress(id, interval), 500);
}
if (!processed) { const pollProgress = async (id: string, intervalId: number) => {
return; getProgress(id)
} .then((progress) => {
setProgress(progress);
const interval = setInterval(async () => { if (progress >= 1) {
const progress = await getProgress(id); clearInterval(intervalId);
setProgress(progress); setDownloadable(true);
}
if (progress >= 1) { })
clearInterval(interval); .catch((err: Error) => {
setDownloadable(true); setError(`Failed to fetch progress: ${err.message}`);
console.log("Downloadable"); clearInterval(intervalId);
} });
}, 500);
} }
const handleDownload = async () => { const handleDownload = async () => {

View File

@@ -10,13 +10,14 @@ const clipUpload = () => {
const [error, setError] = useState<null | string>(null); const [error, setError] = useState<null | string>(null);
const press = (() => { const press = (() => {
if (file) { if (!file) {
uploadFile(file, setError)
.then(uuid => navigate(`/create/${uuid}`))
.catch(e => console.error(e));
} else {
setError("Please choose a file"); setError("Please choose a file");
return;
} }
uploadFile(file)
.then(uuid => navigate(`/create/${uuid}`))
.catch((e: Error) => setError(`Failed to upload file: ${e.message}`));
}); });
return ( return (

View File

@@ -8,7 +8,9 @@ const MyClips = () => {
const [error, setError] = useState<null | string>(null); const [error, setError] = useState<null | string>(null);
useEffect(() => { useEffect(() => {
getClips(setError).then((data) => setClips(data)); getClips()
.then((data) => setClips(data))
.catch((err) => setError(err));
}, []); }, []);
return ( return (

View File

@@ -2,36 +2,32 @@ import type {VideoMetadata, APIResponse, User, Clip} from "./types.ts";
/** /**
* Uploads a file to the backend. * Uploads a file to the backend.
* @param file - The file to upload.
*/ */
const uploadFile = async (file: File, setError: Function): Promise<string> => { const uploadFile = async (file: File): Promise<string> => {
const formData = new FormData(); const formData = new FormData();
formData.append('file', file); formData.append('file', file);
try { const response = await fetch('/api/v1/upload', {
const response = await fetch('/api/v1/upload', { method: 'POST',
method: 'POST', body: formData,
body: formData, });
});
const result: APIResponse = await response.json(); const result: APIResponse = await response.json();
if (result.status == "error") { if (result.status == "error") {
setError(result.message); throw new Error(`Failed to upload file: ${result.message}`);
}
return result.data.uuid;
} catch (error: unknown) {
throw new Error(`Failed to upload file: ${error instanceof Error ? error.message : 'Unknown error'}`);
} }
return result.data.uuid;
}; };
/** /**
* Submits metadata changes to the backend. * Submits metadata changes to the backend.
* @param uuid - The UUID of the video file to edit.
* @param videoMetadata - The metadata to update.
*/ */
const editFile = async ( const editFile = async (uuid: string, videoMetadata: VideoMetadata) => {
uuid: string,
videoMetadata: VideoMetadata,
setError: Function ): Promise<boolean> => {
const formData = new URLSearchParams(); const formData = new URLSearchParams();
for (const [key, value] of Object.entries(videoMetadata)) { for (const [key, value] of Object.entries(videoMetadata)) {
@@ -40,147 +36,143 @@ const editFile = async (
} }
} }
try { const response = await fetch(`/api/v1/edit/${uuid}`, {
const response = await fetch(`/api/v1/edit/${uuid}`, { method: 'POST',
method: 'POST', headers: {
headers: { 'Content-Type': 'application/x-www-form-urlencoded',
'Content-Type': 'application/x-www-form-urlencoded', },
}, body: formData.toString(),
body: formData.toString(), });
});
const result: APIResponse = await response.json(); if (!response.ok) {
throw new Error(`Failed to edit file: ${response.status}`);
if (result.status === "error") {
setError(result.message);
return false;
}
return true;
} catch (error: unknown) {
console.error('Error editing file:', error);
return false;
} }
const result: APIResponse = await response.json();
if (result.status === "error") {
throw new Error(`Failed to edit file: ${result.message}`);
}
}; };
/** /**
* Triggers file processing. * Triggers file processing.
* @param uuid - The UUID of the video file to process.
*/ */
const processFile = async ( const processFile = async (uuid: string) => {
uuid: string, const response = await fetch(`/api/v1/process/${uuid}`);
setError: Function): Promise<boolean> => {
try {
const response = await fetch(`/api/v1/process/${uuid}`);
const result: APIResponse = await response.json(); if (!response.ok) {
if (result.status === "error") { throw new Error(`Failed to process file: ${response.status}`);
setError(result.message); }
return false;
}
return response.ok; const result: APIResponse = await response.json();
} catch (error: unknown) {
console.error('Error processing file:', error); if (result.status === "error") {
return false; throw new Error("Failed to process file: " + result.message);
} }
}; };
/** /**
* Fetches the processing progress percentage. * Fetches the processing progress percentage.
* @param uuid - The UUID of the video file.
*/ */
const getProgress = async ( const getProgress = async (uuid: string): Promise<number> => {
uuid: string): Promise<number> => { const response = await fetch(`/api/v1/progress/${uuid}`);
try {
const response = await fetch(`/api/v1/progress/${uuid}`);
if (!response.ok) { if (!response.ok) {
console.error('Failed to fetch progress:', response.status); throw new Error(`Failed to fetch progress: ${response.status}`);
return 0;
}
const result = await response.json();
return result.data?.progress ?? 0;
} catch (error: unknown) {
console.error('Error getting progress:', error);
return 0;
} }
const result = await response.json();
if (result.status === "error") {
throw new Error(`Failed to fetch progress: ${result.message}`);
}
if (!result.data || typeof result.data.progress !== 'number') {
throw new Error('Invalid progress data received');
}
return result.data.progress;
}; };
/** /**
* Fetches original metadata from the backend. * Fetches original metadata from the backend.
* @param uuid - The UUID of the video file.
*/ */
const getMetadata = async ( const getMetadata = async (uuid: string): Promise<VideoMetadata> => {
uuid: string): Promise<VideoMetadata> => { const response = await fetch(`/api/v1/metadata/original/${uuid}`);
try {
const response = await fetch(`/api/v1/metadata/original/${uuid}`);
if (!response.ok) { if (!response.ok) {
throw new Error(`Failed to fetch metadata: ${response.status}`); throw new Error(`Failed to fetch metadata: ${response.status}`);
}
const result = await response.json();
return result.data;
} catch (error: unknown) {
console.error('Error fetching metadata:', error);
return {
title: '',
description: '',
startPoint: 0,
endPoint: 0,
fps: 0,
width: 0,
height: 0,
fileSize: 0,
};
} }
const result = await response.json();
if (result.status === "error") {
throw new Error(`Failed to fetch metadata: ${result.message}`);
}
return result.data;
}; };
/**
* Fetches the current user information. Returns null if not authenticated.
*/
const getUser = async (): Promise<null | User > => { const getUser = async (): Promise<null | User > => {
try { const response = await fetch('/api/v1/auth/user', {credentials: "include",});
const response = await fetch('/api/v1/auth/user', {credentials: "include",});
const result = await response.json(); if (!response.ok) {
return result.data;
} catch (error: unknown) {
console.error('Error fetching user:', error);
return null; return null;
} }
const result = await response.json();
if (result.status === "error") {
return null;
}
return result.data;
} }
const getClips = async (setError: Function): Promise< Clip[]> => { /**
* Fetches all clips for the current user.
*/
const getClips = async (): Promise<Clip[]> => {
const response = await fetch('/api/v1/clips/', { credentials: 'include' });
if (!response.ok) {
const errorResult: APIResponse = await response.json();
throw new Error(`Failed to fetch clips: ${errorResult.message}`);
}
try { try {
const response = await fetch('/api/v1/clips/', {credentials: "include",});
if (!response.ok) {
const errorResult: APIResponse = await response.json();
setError(errorResult.message);
return [];
}
const result: APIResponse = await response.json(); const result: APIResponse = await response.json();
return result.data; return result.data;
} catch {
} catch (error: unknown) { throw new Error('Failed to parse response');
console.error('Error fetching clips:', error);
setError('Failed to fetch clips');
return [];
} }
} }
/**
* Fetches a clip by its ID.
* @param id
*/
const getClipById = async (id: string): Promise<Clip | null> => { const getClipById = async (id: string): Promise<Clip | null> => {
try { const response = await fetch(`/api/v1/clips/${id}`, {credentials: "include",});
const response = await fetch(`/api/v1/clips/${id}`, {credentials: "include",});
if (!response.ok) { if (!response.ok) {
console.error('Failed to fetch clip:', response.status); throw new Error(`Failed to fetch clip: ${response.status}`);
return null; }
}
try{
const result: APIResponse = await response.json(); const result: APIResponse = await response.json();
return result.data; return result.data;
} catch (error: unknown) { } catch (error: unknown) {
console.error('Error fetching clip:', error); throw new Error(`Failed to parse clip response:
return null; ${error instanceof Error ? error.message : 'Unknown error'}`);
} }
}; };