diff --git a/frontend/src/pages/ClipEdit.tsx b/frontend/src/pages/ClipEdit.tsx index fdcae56..864d486 100644 --- a/frontend/src/pages/ClipEdit.tsx +++ b/frontend/src/pages/ClipEdit.tsx @@ -34,30 +34,32 @@ const ClipEdit = () => { const sendData = async() => { 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) { - return; - } + const pollProgress = async (id: string, intervalId: number) => { + getProgress(id) + .then((progress) => { + setProgress(progress); - const interval = setInterval(async () => { - const progress = await getProgress(id); - setProgress(progress); - - if (progress >= 1) { - clearInterval(interval); - setDownloadable(true); - console.log("Downloadable"); - } - }, 500); + if (progress >= 1) { + clearInterval(intervalId); + setDownloadable(true); + } + }) + .catch((err: Error) => { + setError(`Failed to fetch progress: ${err.message}`); + clearInterval(intervalId); + }); } const handleDownload = async () => { diff --git a/frontend/src/pages/ClipUpload.tsx b/frontend/src/pages/ClipUpload.tsx index 9743ed5..3f441cc 100644 --- a/frontend/src/pages/ClipUpload.tsx +++ b/frontend/src/pages/ClipUpload.tsx @@ -10,13 +10,14 @@ const clipUpload = () => { const [error, setError] = useState(null); const press = (() => { - if (file) { - uploadFile(file, setError) - .then(uuid => navigate(`/create/${uuid}`)) - .catch(e => console.error(e)); - } else { + if (!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 ( diff --git a/frontend/src/pages/MyClips.tsx b/frontend/src/pages/MyClips.tsx index 3f7ffba..8e19ae5 100644 --- a/frontend/src/pages/MyClips.tsx +++ b/frontend/src/pages/MyClips.tsx @@ -8,7 +8,9 @@ const MyClips = () => { const [error, setError] = useState(null); useEffect(() => { - getClips(setError).then((data) => setClips(data)); + getClips() + .then((data) => setClips(data)) + .catch((err) => setError(err)); }, []); return ( diff --git a/frontend/src/utils/endpoints.ts b/frontend/src/utils/endpoints.ts index 490bc15..c777edb 100644 --- a/frontend/src/utils/endpoints.ts +++ b/frontend/src/utils/endpoints.ts @@ -2,36 +2,32 @@ import type {VideoMetadata, APIResponse, User, Clip} from "./types.ts"; /** * Uploads a file to the backend. + * @param file - The file to upload. */ -const uploadFile = async (file: File, setError: Function): Promise => { +const uploadFile = async (file: File): Promise => { const formData = new FormData(); formData.append('file', file); - try { - const response = await fetch('/api/v1/upload', { - method: 'POST', - body: formData, - }); + const response = await fetch('/api/v1/upload', { + method: 'POST', + body: formData, + }); - const result: APIResponse = await response.json(); + const result: APIResponse = await response.json(); - if (result.status == "error") { - setError(result.message); - } - - return result.data.uuid; - } catch (error: unknown) { - throw new Error(`Failed to upload file: ${error instanceof Error ? error.message : 'Unknown error'}`); + if (result.status == "error") { + throw new Error(`Failed to upload file: ${result.message}`); } + + return result.data.uuid; }; /** * 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 ( - uuid: string, - videoMetadata: VideoMetadata, - setError: Function ): Promise => { +const editFile = async (uuid: string, videoMetadata: VideoMetadata) => { const formData = new URLSearchParams(); for (const [key, value] of Object.entries(videoMetadata)) { @@ -40,147 +36,143 @@ const editFile = async ( } } - try { - const response = await fetch(`/api/v1/edit/${uuid}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - body: formData.toString(), - }); + const response = await fetch(`/api/v1/edit/${uuid}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: formData.toString(), + }); - const result: APIResponse = await response.json(); - - if (result.status === "error") { - setError(result.message); - return false; - } - - return true; - } catch (error: unknown) { - console.error('Error editing file:', error); - return false; + if (!response.ok) { + throw new Error(`Failed to edit file: ${response.status}`); } + + const result: APIResponse = await response.json(); + + if (result.status === "error") { + throw new Error(`Failed to edit file: ${result.message}`); + } + }; + /** * Triggers file processing. + * @param uuid - The UUID of the video file to process. */ -const processFile = async ( - uuid: string, - setError: Function): Promise => { - try { - const response = await fetch(`/api/v1/process/${uuid}`); +const processFile = async (uuid: string) => { + const response = await fetch(`/api/v1/process/${uuid}`); - const result: APIResponse = await response.json(); - if (result.status === "error") { - setError(result.message); - return false; - } + if (!response.ok) { + throw new Error(`Failed to process file: ${response.status}`); + } - return response.ok; - } catch (error: unknown) { - console.error('Error processing file:', error); - return false; + const result: APIResponse = await response.json(); + + if (result.status === "error") { + throw new Error("Failed to process file: " + result.message); } }; /** * Fetches the processing progress percentage. + * @param uuid - The UUID of the video file. */ -const getProgress = async ( - uuid: string): Promise => { - try { - const response = await fetch(`/api/v1/progress/${uuid}`); +const getProgress = async (uuid: string): Promise => { + const response = await fetch(`/api/v1/progress/${uuid}`); - if (!response.ok) { - console.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; + if (!response.ok) { + throw new Error(`Failed to fetch progress: ${response.status}`); } + + 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. + * @param uuid - The UUID of the video file. */ -const getMetadata = async ( - uuid: string): Promise => { - try { - const response = await fetch(`/api/v1/metadata/original/${uuid}`); +const getMetadata = async (uuid: string): Promise => { + const response = await fetch(`/api/v1/metadata/original/${uuid}`); - if (!response.ok) { - 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, - }; + if (!response.ok) { + throw new Error(`Failed to fetch metadata: ${response.status}`); } + + 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 => { - 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(); - return result.data; - } catch (error: unknown) { - console.error('Error fetching user:', error); + if (!response.ok) { 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 => { + 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 { - 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(); return result.data; - - } catch (error: unknown) { - console.error('Error fetching clips:', error); - setError('Failed to fetch clips'); - return []; + } catch { + throw new Error('Failed to parse response'); } } +/** + * Fetches a clip by its ID. + * @param id + */ const getClipById = async (id: string): Promise => { - try { - const response = await fetch(`/api/v1/clips/${id}`, {credentials: "include",}); + const response = await fetch(`/api/v1/clips/${id}`, {credentials: "include",}); - if (!response.ok) { - console.error('Failed to fetch clip:', response.status); - return null; - } + if (!response.ok) { + throw new Error(`Failed to fetch clip: ${response.status}`); + } + try{ const result: APIResponse = await response.json(); return result.data; } catch (error: unknown) { - console.error('Error fetching clip:', error); - return null; + throw new Error(`Failed to parse clip response: + ${error instanceof Error ? error.message : 'Unknown error'}`); } };