diff --git a/packages/components/src/api/ApiConfig.ts b/packages/components/src/api/ApiConfig.ts index d548b60bd9..7d9b4e8135 100644 --- a/packages/components/src/api/ApiConfig.ts +++ b/packages/components/src/api/ApiConfig.ts @@ -15,8 +15,8 @@ export interface ListW2lInferenceResultsForUserArgs { } export interface GetUserRatingArgs { - entity_type: string, - entity_token: string, + entity_type: string; + entity_token: string; } enum Domain { @@ -75,7 +75,7 @@ class ApiConfig { apiHost = "api.dev.fakeyou.com:12345"; useSsl = false; break; - default: + default: if (document.location.host.includes("localhost")) { // NB: `localhost` seems to have problems with cookies. useSsl = document.location.protocol === "https:"; @@ -451,6 +451,10 @@ class ApiConfig { return `${this.getApiOrigin()}/v1/media_uploads/upload`; } + uploadMediaFile(): string { + return `${this.getApiOrigin()}/v1/media_files/upload`; + } + // =============== Voice Conversion =============== listVoiceConversionModels(): string { @@ -490,7 +494,9 @@ class ApiConfig { // =============== User Ratings =============== getUserRating(args: GetUserRatingArgs): string { - return `${this.getApiOrigin()}/v1/user_rating/view/${args.entity_type}/${args.entity_token}`; + return `${this.getApiOrigin()}/v1/user_rating/view/${args.entity_type}/${ + args.entity_token + }`; } setUserRating(): string { diff --git a/packages/components/src/api/media_files/UploadMediaFile.ts b/packages/components/src/api/media_files/UploadMediaFile.ts index 12b3c8326c..db4aa99642 100644 --- a/packages/components/src/api/media_files/UploadMediaFile.ts +++ b/packages/components/src/api/media_files/UploadMediaFile.ts @@ -1,17 +1,69 @@ -import MakeMultipartRequest from "../MakeMultipartRequest"; +import { ApiConfig } from "../ApiConfig"; export interface UploadMediaFileRequest { - uuid_idempotency_token?: string; + uuid_idempotency_token: string; file_name: string; file_bytes: any; - media_source: string; + media_source?: string; } -export interface UploadMediaFileResponse { +export interface UploadMediaFileSuccessResponse { success: boolean; media_file_token: string; } -export const UploadMedia = (thing = "", request: UploadMediaFileRequest) => { - return MakeMultipartRequest("/v1/media_files/upload", request); -}; +export interface UploadMediaFileErrorResponse { + success: boolean; +} + +type UploadMediaFileResponse = + | UploadMediaFileSuccessResponse + | UploadMediaFileErrorResponse; + +export function UploadMediaFileIsOk( + response: UploadMediaFileResponse +): response is UploadMediaFileSuccessResponse { + return response?.success === true; +} + +export function UploadMediaFileIsError( + response: UploadMediaFileResponse +): response is UploadMediaFileErrorResponse { + return response?.success === false; +} + +export async function UploadMediaFile( + request: UploadMediaFileRequest +): Promise { + const endpoint = new ApiConfig().uploadMediaFile(); + + const formData = new FormData(); + + formData.append("uuid_idempotency_token", request.uuid_idempotency_token); + formData.append("file_name", request.file_name); + formData.append("file_bytes", request.file_bytes); + + if (request.media_source !== undefined) { + formData.append("media_source", request.media_source); + } + + return fetch(endpoint, { + method: "POST", + credentials: "include", + headers: { + Accept: "application/json", + }, + body: formData, + }) + .then(res => res.json()) + .then(res => { + if (res && "success" in res) { + return res; + } else { + return { success: false }; + } + }) + .catch(e => { + return { success: false }; + }); +} diff --git a/packages/fakeyou.com/src/v2/view/pages/dev_upload/DevUpload.tsx b/packages/fakeyou.com/src/v2/view/pages/dev_upload/DevUpload.tsx index 978331f29d..8a74c78b1a 100644 --- a/packages/fakeyou.com/src/v2/view/pages/dev_upload/DevUpload.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/dev_upload/DevUpload.tsx @@ -2,24 +2,64 @@ import Panel from "components/common/Panel"; import Container from "components/common/Container"; import PageHeader from "components/layout/PageHeader"; import React, { useState } from "react"; -import { Button, Input, TempInput } from "components/common"; +import { Button, Input } from "components/common"; import { faUpload } from "@fortawesome/pro-solid-svg-icons"; +import { + UploadMediaFile, + UploadMediaFileRequest, +} from "@storyteller/components/src/api/media_files/UploadMediaFile"; +import { v4 as uuidv4 } from "uuid"; interface DevUploadProps {} export default function DevUpload(props: DevUploadProps) { - const [selectedFile, setSelectedFile] = useState(null); + const [selectedFile, setSelectedFile] = useState(null); const handleFileChange = (event: any) => { setSelectedFile(event.target.files[0]); }; - const handleUpload = () => { + const makeRequest = async (): Promise => { + if (!selectedFile) { + return null; + } + + const fileReader = new FileReader(); + fileReader.readAsArrayBuffer(selectedFile); + + return new Promise(resolve => { + fileReader.onload = () => { + const result = fileReader.result; + if (result instanceof ArrayBuffer) { + resolve({ + uuid_idempotency_token: uuidv4(), + file_name: selectedFile.name, + file_bytes: result, + media_source: "file", + }); + } + }; + }); + }; + + const handleUpload = async () => { if (!selectedFile) { alert("Please select a file to upload"); return; } - console.log("Uploading", selectedFile); + + const request = await makeRequest(); + if (request) { + UploadMediaFile(request) + .then(res => { + if (res) { + console.log(res); + } + }) + .catch(error => { + console.error("Upload failed:", error); + }); + } }; return (