From 122f39bd258456150f1e73fdd475ee47892c4958 Mon Sep 17 00:00:00 2001 From: wil Date: Thu, 20 Jun 2024 16:14:06 -0400 Subject: [PATCH] Api2.6/ upload animations expressions (#511) Co-authored-by: wil --- app/Classes/ApiManager/ApiManager.ts | 6 +- app/Classes/ApiManager/MediaUploadApi.ts | 13 +- .../UploadModalMovement/DragAndDropZone.tsx | 2 +- .../UploadModalMovement/UploadAssetError.tsx | 16 +-- .../UploadModalMovement/UploadFile.tsx | 54 +------ .../UploadModalMovement/UploadFiles.tsx | 2 +- .../UploadModalMovement/UploadLoaderError.tsx | 30 ---- .../UploadModalMovement/UploadModal.scss | 16 --- .../UploadModalMovement.tsx | 136 +++++++----------- .../UploadModalMovement/UploadSuccess.tsx | 15 +- .../UploadModalMovement/utils/getFileName.ts | 3 - app/enums/MediaFileAnimationTypes.ts | 14 ++ app/enums/index.ts | 1 + .../SidePanelTabs/itemTabs/AnimationTab.tsx | 8 +- .../SidePanelTabs/itemTabs/ExpressionTab.tsx | 5 +- app/utilities.ts | 5 +- 16 files changed, 99 insertions(+), 227 deletions(-) delete mode 100644 app/components/signaled/UploadModalMovement/UploadLoaderError.tsx delete mode 100644 app/components/signaled/UploadModalMovement/UploadModal.scss delete mode 100644 app/components/signaled/UploadModalMovement/utils/getFileName.ts create mode 100644 app/enums/MediaFileAnimationTypes.ts diff --git a/app/Classes/ApiManager/ApiManager.ts b/app/Classes/ApiManager/ApiManager.ts index 5de0818027..a54fd56f9f 100644 --- a/app/Classes/ApiManager/ApiManager.ts +++ b/app/Classes/ApiManager/ApiManager.ts @@ -137,7 +137,7 @@ export class ApiManager { endpoint: string; formRecord: Record; uuid: string; - blob?: Blob; + blob?: Blob | File; blobFileName?: string; }): Promise { const formData = new FormData(); @@ -150,10 +150,6 @@ export class ApiManager { } else if (blob) { formData.append("file", blob); } - // return this.fetch(endpoint, { - // method: "POST", - // body: formData, - // }); return this.fetchMultipartFormData(endpoint, { method: "POST", body: formData, diff --git a/app/Classes/ApiManager/MediaUploadApi.ts b/app/Classes/ApiManager/MediaUploadApi.ts index d5b26b1966..2240ab20d1 100644 --- a/app/Classes/ApiManager/MediaUploadApi.ts +++ b/app/Classes/ApiManager/MediaUploadApi.ts @@ -1,5 +1,5 @@ import { ApiManager, ApiResponse } from "./ApiManager"; -import { Visibility } from "~/enums"; +import { FilterEngineCategories, Visibility } from "~/enums"; export class MediaUploadApi extends ApiManager { private async Upload({ @@ -10,7 +10,7 @@ export class MediaUploadApi extends ApiManager { options, }: { endpoint: string; - blob: Blob; + blob: Blob | File; fileName: string; uuid: string; options: Record; @@ -87,17 +87,19 @@ export class MediaUploadApi extends ApiManager { } public async UploadNewEngineAsset({ - blob, + file, fileName, uuid, + engine_category, maybe_animation_type, maybe_duration_millis, maybe_title, maybe_visibility = Visibility.Public, }: { - blob: Blob; + file: File; fileName: string; uuid: string; + engine_category: FilterEngineCategories; maybe_animation_type?: string; maybe_duration_millis?: number; maybe_title?: string; @@ -105,12 +107,13 @@ export class MediaUploadApi extends ApiManager { }): Promise> { const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/upload/new_engine_asset`; const options: Record = { + engine_category, maybe_title, maybe_visibility: maybe_visibility?.toString(), maybe_animation_type, maybe_duration_millis, }; - return this.Upload({ endpoint, blob, fileName, uuid, options }); + return this.Upload({ endpoint, blob: file, fileName, uuid, options }); } public async UploadNewScene({ diff --git a/app/components/signaled/UploadModalMovement/DragAndDropZone.tsx b/app/components/signaled/UploadModalMovement/DragAndDropZone.tsx index 8b350728ea..54cc50fc18 100644 --- a/app/components/signaled/UploadModalMovement/DragAndDropZone.tsx +++ b/app/components/signaled/UploadModalMovement/DragAndDropZone.tsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faFileArrowUp, faFileAudio } from "@fortawesome/pro-solid-svg-icons"; import { P } from "~/components"; -import { getFileName } from "./utils/getFileName"; +import { getFileName } from "~/utilities"; interface Props { file: File | null; diff --git a/app/components/signaled/UploadModalMovement/UploadAssetError.tsx b/app/components/signaled/UploadModalMovement/UploadAssetError.tsx index c722d53afa..72a52f4da4 100644 --- a/app/components/signaled/UploadModalMovement/UploadAssetError.tsx +++ b/app/components/signaled/UploadModalMovement/UploadAssetError.tsx @@ -14,21 +14,13 @@ export const UploadAssetError = ({ return ( <> {isAssetError - ? "There was a problem uploading your object." - : "There was a problem creating art for your object"} + ? "There was a problem uploading your file." + : "There was a problem uploading the thumbnail for your file."}
- -
diff --git a/app/components/signaled/UploadModalMovement/UploadFile.tsx b/app/components/signaled/UploadModalMovement/UploadFile.tsx index ca4860ebf3..ab4080ba44 100644 --- a/app/components/signaled/UploadModalMovement/UploadFile.tsx +++ b/app/components/signaled/UploadModalMovement/UploadFile.tsx @@ -1,59 +1,20 @@ import { FileUploader } from "react-drag-drop-files"; -import { Button } from "~/components"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faSpinnerThird } from "@fortawesome/pro-solid-svg-icons"; import { DragAndDropZone } from "./DragAndDropZone"; -import { UploadMediaResponse } from "~/components/signaled/UploadAudioButtonDialogue/utilities"; -import { useState } from "react"; - -enum UploadState { - "init", - "staged", - "uploading", - "uploaded", - "error", -} interface Props { title: string; fileTypes: string[]; - setToken?: (token: string) => void; - uploadFile?: (file: File) => Promise; file: File | null; setFile: (file: File | null) => void; } -export const UploadFile = ({ - fileTypes, - title, - setToken, - uploadFile, - file, - setFile, -}: Props) => { - const [uploadState, setUploadState] = useState(UploadState.init); - - const submitUpload = (file: File | null) => { - if (file && uploadFile) { - setUploadState(UploadState.uploading); - uploadFile(file).then((res: UploadMediaResponse) => { - if ("media_file_token" in res) { - setUploadState(UploadState.uploaded); - setToken && setToken(res.media_file_token); - } else { - setUploadState(UploadState.error); - } - }); - } - }; - +export const UploadFile = ({ fileTypes, title, file, setFile }: Props) => { return (
{title} { setFile(file); - setUploadState(file ? UploadState.staged : UploadState.init); }} name="file" types={fileTypes} @@ -61,19 +22,6 @@ export const UploadFile = ({ > - {!!uploadFile && ( -
- -
- )}
); }; diff --git a/app/components/signaled/UploadModalMovement/UploadFiles.tsx b/app/components/signaled/UploadModalMovement/UploadFiles.tsx index 0e745d6bfe..4dd3454657 100644 --- a/app/components/signaled/UploadModalMovement/UploadFiles.tsx +++ b/app/components/signaled/UploadModalMovement/UploadFiles.tsx @@ -1,7 +1,7 @@ import { Button, H6, Input, ListDropdown } from "~/components"; import { UploadFile } from "./UploadFile"; import { useState } from "react"; -import { MediaFileAnimationType } from "~/api/media_files/UploadNewEngineAsset"; +import { MediaFileAnimationType } from "~/enums"; interface Props { title: string; diff --git a/app/components/signaled/UploadModalMovement/UploadLoaderError.tsx b/app/components/signaled/UploadModalMovement/UploadLoaderError.tsx deleted file mode 100644 index 60b784f23e..0000000000 --- a/app/components/signaled/UploadModalMovement/UploadLoaderError.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { Button } from "~/components"; - -interface Props { - onCancel: () => void; - onRetry: () => void; -} - -export const UploadLoaderError = ({ onCancel, onRetry }: Props) => { - return ( - <> - There was a problem loading your object. Try another. -
- - -
- - ); -}; diff --git a/app/components/signaled/UploadModalMovement/UploadModal.scss b/app/components/signaled/UploadModalMovement/UploadModal.scss deleted file mode 100644 index e6e3471016..0000000000 --- a/app/components/signaled/UploadModalMovement/UploadModal.scss +++ /dev/null @@ -1,16 +0,0 @@ -.obj-uploader-modal-load-view { - .uploader-dots { - background: transparent; - margin-bottom: 1rem; - } - .uploader-message { - width: 100%; - opacity: 0.5; - text-align: center; - } -} - -.object-preview-canvas { - width: 100%; - overflow: hidden; -} diff --git a/app/components/signaled/UploadModalMovement/UploadModalMovement.tsx b/app/components/signaled/UploadModalMovement/UploadModalMovement.tsx index 37d22b2b54..8b6cd3260e 100644 --- a/app/components/signaled/UploadModalMovement/UploadModalMovement.tsx +++ b/app/components/signaled/UploadModalMovement/UploadModalMovement.tsx @@ -1,28 +1,23 @@ -import { useCallback, useState } from "react"; +import { useEffect, useState } from "react"; +import { v4 as uuidv4 } from "uuid"; + import { TransitionDialogue, LoadingDots } from "~/components"; -import "./UploadModal.scss"; -import { UploadLoaderError } from "./UploadLoaderError"; + import { UploadAssetError } from "./UploadAssetError"; import { UploadSuccess } from "./UploadSuccess"; import { UploadFiles } from "./UploadFiles"; -import { - MediaFileAnimationType, - MediaFileEngineCategory, - UploadNewEngineAsset, -} from "~/api/media_files/UploadNewEngineAsset"; -import { v4 as uuidv4 } from "uuid"; -import { UploadMedia } from "~/api/media_files/UploadMedia"; -import { EditCoverImage } from "~/api/media_files/EditCoverImage"; +import { MediaFilesApi, MediaUploadApi } from "~/Classes/ApiManager"; +import { FilterEngineCategories, MediaFileAnimationType } from "~/enums"; +import { getFileName } from "~/utilities"; interface Props { - closeModal: () => void; onClose: () => void; onSuccess: () => void; isOpen: boolean; title: string; fileTypes: string[]; typeOptions: { [key: string]: string }[]; - type: MediaFileEngineCategory; + type: FilterEngineCategories; } enum UploaderState { @@ -34,11 +29,9 @@ enum UploaderState { assetError, coverCreateError, coverSetError, - loaderError, } export function UploadModalMovement({ - closeModal, isOpen, onClose, onSuccess, @@ -49,9 +42,15 @@ export function UploadModalMovement({ }: Props) { const [objUploadStatus, setObjUploadStatus] = useState(UploaderState.ready); - const resetModalState = useCallback(() => { + const resetModalState = () => { setObjUploadStatus(UploaderState.ready); - }, []); + }; + + useEffect(() => { + if (isOpen) { + resetModalState(); + } + }, [isOpen]); const onSubmit = async ({ title, @@ -66,54 +65,62 @@ export function UploadModalMovement({ length: number; thumbnailFile: File | null; }) => { - const res = await UploadNewEngineAsset({ - engine_category: type, + setObjUploadStatus(UploaderState.uploadingAsset); + const mediaUploadApi = new MediaUploadApi(); + const assetReponse = await mediaUploadApi.UploadNewEngineAsset({ file: assetFile, - maybe_animation_type: typeOption as MediaFileAnimationType, + fileName: assetFile.name, + engine_category: type, + maybe_animation_type: typeOption, maybe_duration_millis: length, maybe_title: title, - uuid_idempotency_token: uuidv4(), + uuid: uuidv4(), }); - if (!("media_file_token" in res)) { + + if (!assetReponse.success || !assetReponse.data) { setObjUploadStatus(UploaderState.assetError); return; } - const assetToken = res.media_file_token; + const assetToken = assetReponse.data; if (!thumbnailFile) { setObjUploadStatus(UploaderState.success); return; } - const resp = await UploadMedia({ - uuid_idempotency_token: uuidv4(), - file: thumbnailFile, - source: title, + + setObjUploadStatus(UploaderState.uploadingCover); + const thumbnailResponse = await mediaUploadApi.UploadImage({ + uuid: uuidv4(), + blob: thumbnailFile, + fileName: getFileName(thumbnailFile), + maybe_title: "thumbnail_" + title, }); - if (!("media_file_token" in resp)) { - setObjUploadStatus(UploaderState.uploadingCover); + if (!thumbnailResponse.success || !thumbnailResponse.data) { + setObjUploadStatus(UploaderState.coverCreateError); return; } - const thumbnailToken = resp.media_file_token; - const editRes = await EditCoverImage(assetToken, { - cover_image_media_file_token: thumbnailToken, + + setObjUploadStatus(UploaderState.settingCover); + const thumbnailToken = thumbnailResponse.data; + const mediaFilesApi = new MediaFilesApi(); + const setThumbnailResponse = await mediaFilesApi.UpdateCoverImage({ + mediaFileToken: assetToken, + imageToken: thumbnailToken, }); - if (!editRes.success) { - setObjUploadStatus(UploaderState.uploadingCover); + if (!setThumbnailResponse.success) { + setObjUploadStatus(UploaderState.coverSetError); return; } setObjUploadStatus(UploaderState.success); }; - const objUploaderContent = () => { + const ObjUploaderContent = () => { switch (objUploadStatus) { case UploaderState.ready: return ( { - closeModal(); - onClose(); - }} + onClose={onClose} typeOptions={typeOptions} onSubmit={onSubmit} /> @@ -122,20 +129,18 @@ export function UploadModalMovement({ case UploaderState.uploadingCover: case UploaderState.settingCover: return ( -
- -
Uploading...
-
+ <> + +
Uploading...
+ ); case UploaderState.success: return ( { - closeModal(); - onClose(); onSuccess(); - setTimeout(() => setObjUploadStatus(UploaderState.ready), 0); + onClose(); }} /> ); @@ -144,50 +149,19 @@ export function UploadModalMovement({ case UploaderState.coverSetError: return ( { - closeModal(); - onClose(); - setTimeout(() => setObjUploadStatus(UploaderState.ready), 0); - }} + onCancel={onClose} onRetry={() => { - switch (objUploadStatus) { - case UploaderState.assetError: { - break; - } - case UploaderState.coverCreateError: { - break; - } - } - }} - isAssetError={objUploadStatus === UploaderState.assetError} - /> - ); - case UploaderState.loaderError: - return ( - { - closeModal(); - onClose(); - setTimeout(() => setObjUploadStatus(UploaderState.ready), 0); - }} - onRetry={() => { - setObjUploadStatus(UploaderState.ready); resetModalState(); }} + isAssetError={objUploadStatus === UploaderState.assetError} /> ); } }; return ( - - {objUploaderContent()} + + ); } diff --git a/app/components/signaled/UploadModalMovement/UploadSuccess.tsx b/app/components/signaled/UploadModalMovement/UploadSuccess.tsx index b751a2d4ce..d1045075a1 100644 --- a/app/components/signaled/UploadModalMovement/UploadSuccess.tsx +++ b/app/components/signaled/UploadModalMovement/UploadSuccess.tsx @@ -7,20 +7,13 @@ interface Props { export const UploadSuccess = ({ title, onOk }: Props) => { return ( -
-
{`Added ${title} to objects`}
+ <> +
{`Added ${title} to your library`}
-
-
+ ); }; diff --git a/app/components/signaled/UploadModalMovement/utils/getFileName.ts b/app/components/signaled/UploadModalMovement/utils/getFileName.ts deleted file mode 100644 index 73e833b8cb..0000000000 --- a/app/components/signaled/UploadModalMovement/utils/getFileName.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const getFileName = (file: File) => { - return file.name.split(".")[0] || ""; -}; diff --git a/app/enums/MediaFileAnimationTypes.ts b/app/enums/MediaFileAnimationTypes.ts new file mode 100644 index 0000000000..27a7c94d77 --- /dev/null +++ b/app/enums/MediaFileAnimationTypes.ts @@ -0,0 +1,14 @@ +export enum MediaFileAnimationType { + ArKit = "ar_kit", + MikuMikuDance = "miku_miku_dance", + MikuMikuDanceArKit = "miku_miku_dance_ar_kit", + Mixamo = "mixamo", + MixamoArKit = "mixamo_ar_kit", + MocapNet = "mocap_net", + MocapNetArKit = "mocap_net_ar_kit", + MoveAi = "move_ai", + MoveAiArKit = "move_ai_ar_kit", + Rigify = "rigify", + RigifyArKit = "rigify_ar_kit", + Rokoko = "rokoko", +} diff --git a/app/enums/index.ts b/app/enums/index.ts index 5b25ee2916..0c1b3a5a74 100644 --- a/app/enums/index.ts +++ b/app/enums/index.ts @@ -7,6 +7,7 @@ export * from "./ClipGroup"; export * from "./ClipType"; export * from "./FileTypes"; export * from "./JobStatus"; +export * from "./MediaFileAnimationTypes"; export * from "./QueryFilters"; export * from "./toasts"; export * from "./Visibility"; diff --git a/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/AnimationTab.tsx b/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/AnimationTab.tsx index 7841d8a0b1..acf5c170e8 100644 --- a/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/AnimationTab.tsx +++ b/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/AnimationTab.tsx @@ -8,18 +8,17 @@ import { AssetFilterOption, AssetType, FilterEngineCategories, + MediaFileAnimationType, ToastTypes, } from "~/enums"; import { animationFilter, animationItems } from "~/pages/PageEnigma/signals"; import { addToast } from "~/signals"; -import { MediaFileAnimationType } from "~/api/media_files/UploadNewEngineAsset"; -import { MediaFileEngineCategory } from "~/api/media_files/UploadEngineAsset"; - import { ItemElements } from "~/pages/PageEnigma/comps/SidePanelTabs/itemTabs/ItemElements"; import { Button, UploadModalMovement } from "~/components"; import { TabTitle } from "~/pages/PageEnigma/comps/SidePanelTabs/comps/TabTitle"; + import { MediaFilesApi } from "~/Classes/ApiManager"; export const AnimationTab = () => { @@ -127,7 +126,6 @@ export const AnimationTab = () => { /> setOpen(false)} onClose={() => setOpen(false)} onSuccess={refetchAnimations} isOpen={open} @@ -140,7 +138,7 @@ export const AnimationTab = () => { { Rigify: MediaFileAnimationType.Rigify }, { Rokoko: MediaFileAnimationType.Rokoko }, ]} - type={MediaFileEngineCategory.Animation} + type={FilterEngineCategories.ANIMATION} /> ); diff --git a/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/ExpressionTab.tsx b/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/ExpressionTab.tsx index b5b6f90e2f..30defe39be 100644 --- a/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/ExpressionTab.tsx +++ b/app/pages/PageEnigma/comps/SidePanelTabs/itemTabs/ExpressionTab.tsx @@ -8,11 +8,10 @@ import { AssetType, FilterEngineCategories, ToastTypes, + MediaFileAnimationType, } from "~/enums"; import { expressionFilter } from "~/pages/PageEnigma/signals"; -import { MediaFileEngineCategory } from "~/api/media_files/UploadEngineAsset"; -import { MediaFileAnimationType } from "~/api/media_files/UploadNewEngineAsset"; import { ItemElements } from "~/pages/PageEnigma/comps/SidePanelTabs/itemTabs/ItemElements"; import { @@ -170,7 +169,7 @@ export const ExpressionTab = () => { fileTypes={["CSV"]} title="Upload Expression" typeOptions={[{ ARKit: MediaFileAnimationType.ArKit }]} - type={MediaFileEngineCategory.Expression} + type={FilterEngineCategories.EXPRESSION} /> ); diff --git a/app/utilities.ts b/app/utilities.ts index d74a8598af..686a53ab48 100644 --- a/app/utilities.ts +++ b/app/utilities.ts @@ -31,7 +31,10 @@ export const isJobStatusTerminal = (curr: JobStatus) => { }; export const getFileName = (file: File) => { - return file.name.split(".")[0] || ""; + return file.name.substring(0, file.name.lastIndexOf(".")); +}; +export const getFileExtension = (file: File) => { + return file.name.substring(file.name.lastIndexOf(".")); }; export const getFileTypesFromEnum = (enumOfTypes: object) => {