mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-06 02:00:46 +00:00
Merge branch 'feature/mvp' into feature/select-modal
This commit is contained in:
17 files changed
+294
-291
No files matched your search
@@ -206,6 +206,7 @@ function initInferenceJobsByCategoryMap(): Map<
|
||||
[]
|
||||
);
|
||||
inferenceJobsByCategory.set(FrontendInferenceJobType.VoiceDesignerTts, []);
|
||||
inferenceJobsByCategory.set(FrontendInferenceJobType.VideoMotionCapture, []);
|
||||
return inferenceJobsByCategory;
|
||||
}
|
||||
|
||||
@@ -485,10 +486,8 @@ class App extends React.Component<Props, State> {
|
||||
frontendJobType: FrontendInferenceJobType
|
||||
) => {
|
||||
const newJob = new InferenceJob(jobToken, frontendJobType);
|
||||
let inferenceJobs = this.state.inferenceJobs.concat([newJob]);
|
||||
|
||||
this.setState({
|
||||
inferenceJobs: inferenceJobs,
|
||||
inferenceJobs: [...this.state.inferenceJobs, newJob],
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -32,5 +32,10 @@
|
||||
background-color: transparent;
|
||||
border-bottom: 4px solid $primary !important;
|
||||
}
|
||||
|
||||
&.disabled{
|
||||
color: rgba($white, 0.5) !important;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,12 @@ interface TabProps {
|
||||
content?: React.ReactNode;
|
||||
icon?: IconDefinition;
|
||||
padding?: boolean;
|
||||
disabled?:boolean;
|
||||
}
|
||||
|
||||
interface TabsProps {
|
||||
tabs: TabProps[];
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
interface TabContentProps {
|
||||
@@ -22,12 +24,12 @@ interface TabContentProps {
|
||||
padding?: boolean;
|
||||
}
|
||||
|
||||
function Tab({ to, label, icon, onClick }: TabProps & { onClick: () => void }) {
|
||||
function Tab({ to, label, icon, onClick, disabled }: TabProps & { onClick: () => void }) {
|
||||
return (
|
||||
<li className="nav-item">
|
||||
<NavLink
|
||||
to={to}
|
||||
className="nav-link fs-6 px-3 px-lg-4"
|
||||
className={"nav-link fs-6 px-3 px-lg-4" + (disabled?" disabled":"")}
|
||||
activeClassName="active"
|
||||
onClick={onClick}
|
||||
>
|
||||
@@ -43,7 +45,7 @@ function TabContent({ children, padding }: TabContentProps) {
|
||||
return <div className={`tab-content ${paddingClasses}`}>{children}</div>;
|
||||
}
|
||||
|
||||
function Tabs({ tabs }: TabsProps) {
|
||||
function Tabs({ tabs, disabled }: TabsProps) {
|
||||
const location = useLocation();
|
||||
const currentPath = location.pathname;
|
||||
const initialTab = tabs.find(tab => tab.to === currentPath) || tabs[0];
|
||||
@@ -83,6 +85,7 @@ function Tabs({ tabs }: TabsProps) {
|
||||
label={tab.label}
|
||||
onClick={() => handleTabClick(tab.to)}
|
||||
icon={tab.icon}
|
||||
disabled={disabled || tab.disabled}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import React, { useEffect } from "react";
|
||||
import { useSpring } from "@react-spring/web";
|
||||
import { FileDetails, FileWrapper, FileLabel } from "components/common";
|
||||
import { faFileVideo, faVideo } from "@fortawesome/pro-solid-svg-icons";
|
||||
import "./style.scss";
|
||||
import "./videoinput.scss";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
interface Props {
|
||||
File renamed without changes.
@@ -0,0 +1,5 @@
|
||||
@import "scss/colours.scss";
|
||||
|
||||
.upload-details {
|
||||
background-color: rgba($panel, .85);
|
||||
}
|
||||
+22
-15
@@ -18,19 +18,26 @@ export default function InferenceJobsList({ failures, jobType, onSelect }: JobsL
|
||||
// let height = 0;
|
||||
// const transitions = useTransition(inferenceJobs,{ not right now });
|
||||
|
||||
return inferenceJobs.length ? <div {...{ className: "face-animator-jobs panel" }}>
|
||||
<h5>{ t("core.heading") }</h5>
|
||||
{
|
||||
inferenceJobs.map((job: InferenceJob, key: number) =>
|
||||
<JobItem {...{
|
||||
failures,
|
||||
jobStatusDescription,
|
||||
jobType,
|
||||
key,
|
||||
onSelect,
|
||||
t,
|
||||
// refSet: (ref: any) => console.log(ref),
|
||||
...job }} />).reverse()
|
||||
}
|
||||
</div> : null;
|
||||
if (inferenceJobs.length){
|
||||
return(
|
||||
<div className="face-animator-jobs panel">
|
||||
<h5>{ t("core.heading") }</h5>
|
||||
{
|
||||
inferenceJobs.map((job: InferenceJob, key: number) =>
|
||||
<JobItem {...{
|
||||
failures,
|
||||
jobStatusDescription,
|
||||
jobType,
|
||||
key,
|
||||
onSelect,
|
||||
t,
|
||||
...job }} />).reverse()
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
else{
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -12,6 +12,16 @@ styles with important tags:
|
||||
// Once the rollout is complete, this outer wrapper class can be removed.
|
||||
|
||||
.fakeyou-refresh {
|
||||
|
||||
//- BS5 classnames -//
|
||||
.object-fit-cover{
|
||||
object-fit: cover;
|
||||
}
|
||||
.ratio-1x1 {
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
//-end--//
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: rgba($secondary, 1);
|
||||
border-radius: 0.5rem;
|
||||
@@ -196,6 +206,9 @@ styles with important tags:
|
||||
color: #ffe600;
|
||||
}
|
||||
|
||||
.fill-secondary {
|
||||
fill: $secondary;
|
||||
}
|
||||
.alert-pricing {
|
||||
font-weight: 500 !important;
|
||||
font-size: 18px !important;
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useReducer, useEffect } from "react";
|
||||
import { Redirect, useLocation } from "react-router-dom";
|
||||
|
||||
import { useLocalize } from "hooks";
|
||||
import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper";
|
||||
import {
|
||||
FrontendInferenceJobType,
|
||||
InferenceJob,
|
||||
} from "@storyteller/components/src/jobs/InferenceJob";
|
||||
|
||||
// import { PageVideoProvision } from "./components/pageVideoProvision";
|
||||
import { PageInferenceStatuses } from "./components/pageInferenceStatuses";
|
||||
import { BasicVideo, Container, Panel } from "components/common";
|
||||
import PageHeader from "components/layout/PageHeader";
|
||||
import Tabs from "components/common/Tabs";
|
||||
import { Redirect, useLocation } from "react-router-dom";
|
||||
import { useLocalize } from "hooks";
|
||||
|
||||
import TabContentUpload from "./components/tabContentUpload";
|
||||
import TabContentLibrary from "./components/tabContentLibrary";
|
||||
import PageVideoMocapProgress from "./components/pageVideoMocapProgress";
|
||||
import VideoMocapJobList from "./components/videoMocapJobList";
|
||||
import {states, reducer} from './videoMocapReducer';
|
||||
|
||||
export default function VideoMotionCapture(props: {
|
||||
sessionSubscriptionsWrapper: SessionSubscriptionsWrapper;
|
||||
enqueueInferenceJob: (
|
||||
jobToken: string,
|
||||
frontendInferenceJobType: FrontendInferenceJobType
|
||||
@@ -27,39 +27,22 @@ export default function VideoMotionCapture(props: {
|
||||
}) {
|
||||
const { enqueueInferenceJob } = props;
|
||||
const { t } = useLocalize("VideoMotionCapture");
|
||||
enum pageStates {
|
||||
VIDEO_PROVISION,
|
||||
SHOW_JOB_STATUS,
|
||||
}
|
||||
const { VIDEO_PROVISION, SHOW_JOB_STATUS } = pageStates;
|
||||
const [pageState, setPageState] = useState<{
|
||||
index: number;
|
||||
inputMediaToken: string;
|
||||
jobToken: string;
|
||||
resultMediaToken: string;
|
||||
}>({
|
||||
index: VIDEO_PROVISION,
|
||||
inputMediaToken: "",
|
||||
jobToken: "",
|
||||
resultMediaToken: "",
|
||||
});
|
||||
const { NO_FILE, FILE_UPLOADING, MOCAPNET_ENQUEUED } = states;
|
||||
const [pageState, dispatchPageState] = useReducer(reducer, {status: NO_FILE});
|
||||
|
||||
const handlePageState = ({
|
||||
tokenType,
|
||||
token,
|
||||
}: {
|
||||
tokenType: string;
|
||||
token: string | undefined;
|
||||
}) => {
|
||||
if (token && tokenType === "jobToken") {
|
||||
setPageState({
|
||||
...pageState,
|
||||
index: SHOW_JOB_STATUS,
|
||||
jobToken: token,
|
||||
useEffect(()=>{
|
||||
if (pageState.status === states.MOCAPNET_ENQUEUED && pageState.inferenceJobToken){
|
||||
enqueueInferenceJob(
|
||||
pageState.inferenceJobToken,
|
||||
FrontendInferenceJobType.VideoMotionCapture
|
||||
);
|
||||
dispatchPageState({
|
||||
type: 'enqueueMocapNetSuccess',
|
||||
payload:{inferenceJobToken: undefined}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}, [pageState, enqueueInferenceJob])
|
||||
const { pathname } = useLocation();
|
||||
|
||||
if (pathname === `/video-mocap` || pathname === `/video-mocap/`) {
|
||||
@@ -69,13 +52,13 @@ export default function VideoMotionCapture(props: {
|
||||
const tabs = [
|
||||
{
|
||||
label: t("tabTitle.upload"),
|
||||
content: <TabContentUpload t={t} pageStateCallback={handlePageState} />,
|
||||
content: <TabContentUpload {...{t, pageState, dispatchPageState}} />,
|
||||
to: "/video-mocap/upload",
|
||||
padding: true,
|
||||
},
|
||||
{
|
||||
label: t("tabTitle.library"),
|
||||
content: <TabContentLibrary t={t} pageStateCallback={handlePageState} />,
|
||||
content: <TabContentLibrary {...{t, pageState, dispatchPageState}} />,
|
||||
to: "/video-mocap/select-media",
|
||||
padding: true,
|
||||
},
|
||||
@@ -89,35 +72,34 @@ export default function VideoMotionCapture(props: {
|
||||
/>
|
||||
<Panel>
|
||||
<div className="row g-0">
|
||||
{/*Video Provision Tabs & Job Statuses*/}
|
||||
<div className="col-12 col-md-6">
|
||||
{pageState.index === VIDEO_PROVISION && <Tabs tabs={tabs} />}
|
||||
{pageState.index === SHOW_JOB_STATUS && (
|
||||
<PageInferenceStatuses
|
||||
{...{
|
||||
t,
|
||||
enqueueInferenceJob,
|
||||
pageStates,
|
||||
pageState,
|
||||
pageStateCallback: handlePageState,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{/*ENDS Video Chooser Tabs*/}
|
||||
|
||||
<div className="col-12 col-md-6">
|
||||
<Panel padding={true} clear={true}>
|
||||
<BasicVideo
|
||||
title="Video -> Mocap Sample"
|
||||
src="/videos/face-animator-instruction-en.mp4"
|
||||
/>
|
||||
</Panel>
|
||||
</div>
|
||||
{ pageState.status < FILE_UPLOADING && <>
|
||||
<div className="col-12 col-md-6">
|
||||
<Tabs tabs={tabs}/>
|
||||
</div>
|
||||
<div className="col-12 col-md-6">
|
||||
<Panel padding={true} clear={true}>
|
||||
<BasicVideo
|
||||
title="Video -> Mocap Sample"
|
||||
src="/videos/face-animator-instruction-en.mp4"
|
||||
/>
|
||||
</Panel>
|
||||
</div>
|
||||
</>}
|
||||
{ pageState.status >= FILE_UPLOADING && pageState.status < MOCAPNET_ENQUEUED &&
|
||||
<div className="col-12" >
|
||||
<PageVideoMocapProgress {...{t, pageState, dispatchPageState}} />
|
||||
</div>
|
||||
}
|
||||
{ pageState.status === MOCAPNET_ENQUEUED &&
|
||||
<div className="col-12" >
|
||||
<h2 className="p-3 m-0">{t("tab.message.mocapNetRequestSucceed")}</h2>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
{/*2nd row*/}
|
||||
</Panel>
|
||||
{/*panel*/}
|
||||
<VideoMocapJobList />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
@import "scss/colours.scss";
|
||||
@import "scss/_breakpoint.scss";
|
||||
|
||||
//TODO: PUSH TO TOP
|
||||
.fill-secondary {
|
||||
fill: $secondary;
|
||||
}
|
||||
|
||||
//TODO: PUSH TO TOP, given in BS5
|
||||
.object-fit-cover{
|
||||
object-fit: cover;
|
||||
}
|
||||
.ratio-1x1 {
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
//-end--//
|
||||
|
||||
.upload-details {
|
||||
background-color: rgba($panel, .85);
|
||||
}
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
import React, { useEffect } from 'react'
|
||||
|
||||
import { Analytics } from "common/Analytics";
|
||||
import InferenceJobsList from "components/layout/InferenceJobsList";
|
||||
import { FrontendInferenceJobType } from "@storyteller/components/src/jobs/InferenceJob";
|
||||
|
||||
export function PageInferenceStatuses (props:{
|
||||
t: Function,
|
||||
pageStates: Object,
|
||||
pageState: {
|
||||
index:number,
|
||||
inputMediaToken: string,
|
||||
jobToken: string,
|
||||
resultMediaToken: string
|
||||
},
|
||||
enqueueInferenceJob: (
|
||||
jobToken: string,
|
||||
frontendInferenceJobType: FrontendInferenceJobType
|
||||
) => void,
|
||||
pageStateCallback: (data:{tokenType:string, token:string | undefined}) => void
|
||||
}){
|
||||
const { t, pageState, enqueueInferenceJob } = props;
|
||||
useEffect(()=>{
|
||||
console.log("ENQUEUE INFERENCE JOB>>")
|
||||
enqueueInferenceJob(
|
||||
props.pageState.jobToken,
|
||||
FrontendInferenceJobType.FaceAnimation
|
||||
);
|
||||
}, [props.pageState.jobToken, enqueueInferenceJob])
|
||||
|
||||
const failures = (fail = "") => {
|
||||
switch (fail) {
|
||||
case "sample case":
|
||||
return "Sample Case, this should not have been shown";
|
||||
default:
|
||||
return "Uknown failure";
|
||||
}
|
||||
};
|
||||
|
||||
return(
|
||||
<>
|
||||
<h2>{t("tab.message.mocapNetRequestSucceed")}</h2>
|
||||
<h4>Job Token: {pageState.jobToken}</h4>
|
||||
|
||||
<InferenceJobsList {...{
|
||||
failures,
|
||||
onSelect: () => Analytics.voiceConversionClickDownload(),
|
||||
jobType: FrontendInferenceJobType.FaceAnimation,
|
||||
}}/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
import React from 'react';
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import { EnqueueVideoMotionCapture } from "@storyteller/components/src/api/video_mocap";
|
||||
|
||||
import { states, Action, State } from "../videoMocapReducer";
|
||||
import { Spinner } from 'components/common/';
|
||||
|
||||
export default function PageVideoMocapProgress ({t, pageState, dispatchPageState}: {
|
||||
t: Function;
|
||||
pageState: State;
|
||||
dispatchPageState: (action: Action) => void;
|
||||
}){
|
||||
const {FILE_UPLOADING, FILE_UPLOADED, MOCAPNET_ENQUEUEING} = states;
|
||||
|
||||
const handleEnqueueMocapNet = () => {
|
||||
if (pageState.mediaFileToken){
|
||||
const request = {
|
||||
video_source: pageState.mediaFileToken,
|
||||
uuid_idempotency_token: uuidv4(),
|
||||
};
|
||||
EnqueueVideoMotionCapture(request).then(res => {
|
||||
if(res.success && res.inference_job_token ){
|
||||
dispatchPageState({
|
||||
type: 'enqueueMocapNetSuccess',
|
||||
payload:{
|
||||
inferenceJobToken: res.inference_job_token,
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
dispatchPageState({type: 'enqueueMocapNet'})
|
||||
}
|
||||
};
|
||||
|
||||
if (pageState.status === FILE_UPLOADING) {
|
||||
return (
|
||||
<div className="row p-4 g-4">
|
||||
<div className="col-12 d-flex justify-content-center">
|
||||
<h2 className="flex-basis">{t("tab.message.fileUploading")}</h2>
|
||||
</div>
|
||||
<div className="col-12 d-flex justify-content-center">
|
||||
<Spinner />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else if (pageState.status === FILE_UPLOADED) {
|
||||
return (
|
||||
<div className="row p-4 g-4">
|
||||
<div className="col-12 d-flex justify-content-center">
|
||||
<h2>{t("tab.message.fileUploaded")}</h2>
|
||||
</div>
|
||||
<div className="col-12 d-flex justify-content-center">
|
||||
<button className="btn btn-primary" onClick={handleEnqueueMocapNet}>
|
||||
{t("button.generate")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else if (pageState.status === MOCAPNET_ENQUEUEING) {
|
||||
return (
|
||||
<div className="row p-4 g-4">
|
||||
<div className="col-12 d-flex justify-content-center">
|
||||
<h2>{t("tab.message.mocapNetRequesting")}</h2>
|
||||
</div>
|
||||
<div className="col-12 d-flex justify-content-center">
|
||||
<Spinner />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return(
|
||||
<div className="row p-4 g-4">
|
||||
<div className="col-12 d-flex justify-content-center">
|
||||
<h2>{t("message.UnknownError")}</h2>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import React from "react";
|
||||
import TabContentUpload from "./tabContentUpload";
|
||||
import TabContentLibrary from "./tabContentLibrary";
|
||||
|
||||
export function PageVideoProvision (props:{
|
||||
t: Function
|
||||
pageStateCallback: (data:{tokenType:string, token:string | undefined}) => void
|
||||
}){
|
||||
const {t} = props;
|
||||
return(<>
|
||||
<ul className="nav nav-tabs" id="vmcTab">
|
||||
<li className="nav-item">
|
||||
<button
|
||||
className="nav-link active"
|
||||
id="vmcUploadTab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#vmcUpload"
|
||||
>
|
||||
{t("tabTitle.upload")}
|
||||
</button>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<button
|
||||
disabled
|
||||
className="nav-link"
|
||||
id="vmcLibraryTab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#vmcLibrary"
|
||||
>
|
||||
{t("tabTitle.library")}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="tab-content" id="vmcTabContent">
|
||||
<TabContentUpload {...props}/>
|
||||
<TabContentLibrary {...props}/>
|
||||
</div>
|
||||
</>);
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import SelectModal from "components/common/SelectModal/SelectModal";
|
||||
import React from "react";
|
||||
import { Action, State } from "../videoMocapReducer";
|
||||
|
||||
export default function TabContentLibrary(props: {
|
||||
t: Function;
|
||||
pageStateCallback: Function;
|
||||
}) {
|
||||
pageState: State;
|
||||
dispatchPageState: (action: Action) => void;
|
||||
}){
|
||||
return (
|
||||
<div>
|
||||
<SelectModal
|
||||
|
||||
+35
-92
@@ -1,34 +1,22 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React from "react";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import { UploadMedia } from "@storyteller/components/src/api/media_files/UploadMedia";
|
||||
import { EnqueueVideoMotionCapture } from "@storyteller/components/src/api/video_mocap";
|
||||
import { useFile } from "hooks";
|
||||
|
||||
import VideoInput from "v2/view/pages/video_mocap/components/VideoInput";
|
||||
import VideoInput from "components/common/VideoInput";
|
||||
import { states, Action, State } from "../videoMocapReducer";
|
||||
|
||||
export default function TabContentUpload(props: {
|
||||
export default function TabContentUpload({t, pageState, dispatchPageState}: {
|
||||
t: Function;
|
||||
pageStateCallback: (data: {
|
||||
tokenType: string;
|
||||
token: string | undefined;
|
||||
}) => void;
|
||||
pageState: State;
|
||||
dispatchPageState: (action: Action) => void;
|
||||
}) {
|
||||
const { t, pageStateCallback } = props;
|
||||
const videoProps = useFile({});
|
||||
enum tabStates {
|
||||
NO_FILE,
|
||||
FILE_STAGED,
|
||||
FILE_UPLOADING,
|
||||
FILE_UPLOADED,
|
||||
MOCAPNET,
|
||||
}
|
||||
const { NO_FILE, FILE_STAGED, FILE_UPLOADING, FILE_UPLOADED, MOCAPNET } =
|
||||
tabStates;
|
||||
const [tabState, setTabState] = useState<number>(NO_FILE);
|
||||
const [token, setToken] = useState<string>("");
|
||||
const {NO_FILE, FILE_STAGED} = states;
|
||||
|
||||
const makeRequest = () => ({
|
||||
|
||||
const makeVideoUploadRequest = () => ({
|
||||
uuid_idempotency_token: uuidv4(),
|
||||
file: videoProps.file,
|
||||
source: "file",
|
||||
@@ -36,42 +24,35 @@ export default function TabContentUpload(props: {
|
||||
});
|
||||
|
||||
const handleUploadVideo = () => {
|
||||
setTabState(FILE_UPLOADING);
|
||||
UploadMedia(makeRequest()).then(res => {
|
||||
if (res.success && "media_file_token" in res) {
|
||||
setToken(res.media_file_token);
|
||||
dispatchPageState({type: 'uploadFile'});
|
||||
UploadMedia(makeVideoUploadRequest()).then(res => {
|
||||
if (res.success && res.media_file_token) {
|
||||
dispatchPageState({
|
||||
type: 'uploadFileSuccess',
|
||||
payload:{
|
||||
mediaFileToken :res.media_file_token
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
if (token !== "") setTabState(FILE_UPLOADED);
|
||||
}, [token, FILE_UPLOADED]);
|
||||
|
||||
const handleEnqueueMocapNet = () => {
|
||||
const request = {
|
||||
video_source: token,
|
||||
uuid_idempotency_token: uuidv4(),
|
||||
};
|
||||
EnqueueVideoMotionCapture(request).then(res => {
|
||||
pageStateCallback({
|
||||
tokenType: "jobToken",
|
||||
token: res.inference_job_token,
|
||||
});
|
||||
});
|
||||
setTabState(MOCAPNET);
|
||||
};
|
||||
// contains upload inout state and controls, see docs
|
||||
if (tabState === NO_FILE || tabState === FILE_STAGED) {
|
||||
if (pageState.status === NO_FILE || pageState.status === FILE_STAGED) {
|
||||
return (
|
||||
<div>
|
||||
<>
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<VideoInput
|
||||
{...{
|
||||
t,
|
||||
...videoProps,
|
||||
onStateChange: () =>
|
||||
setTabState(videoProps.file ? FILE_STAGED : NO_FILE),
|
||||
onStateChange: () =>{
|
||||
if (pageState.status === NO_FILE && videoProps.file)
|
||||
dispatchPageState({type: "stagedFile"})
|
||||
else if (pageState.status === FILE_STAGED && !videoProps.file)
|
||||
dispatchPageState({type: "clearedFile"})
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -82,7 +63,7 @@ export default function TabContentUpload(props: {
|
||||
<div className="d-flex justify-content-end gap-3">
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
disabled={tabState !== FILE_STAGED}
|
||||
disabled={pageState.status !== FILE_STAGED}
|
||||
onClick={handleUploadVideo}
|
||||
>
|
||||
{t("button.upload")}
|
||||
@@ -90,52 +71,14 @@ export default function TabContentUpload(props: {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else if (tabState === FILE_UPLOADING) {
|
||||
return (
|
||||
<div className="tab-pane fade show active py-4" id="vmcUpload">
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<h2>{t("tab.message.fileUploading")}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else if (tabState === FILE_UPLOADED) {
|
||||
return (
|
||||
<div className="tab-pane fade show active py-4" id="vmcUpload">
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<h2>{t("tab.message.fileUploaded")}</h2>
|
||||
</div>
|
||||
<div className="col-12">
|
||||
<button className="btn btn-primary" onClick={handleEnqueueMocapNet}>
|
||||
{t("button.generate")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else if (tabState === MOCAPNET) {
|
||||
return (
|
||||
<div className="tab-pane fade show active py-4" id="vmcUpload">
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<h2>{t("tab.message.mocapNetRequesting")}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="tab-pane fade show active py-4" id="vmcUpload">
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<h1>{t("message.UnknownError")}</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<h1>{t("message.UnknownError")}</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react'
|
||||
|
||||
import { Analytics } from "common/Analytics";
|
||||
import InferenceJobsList from "components/layout/InferenceJobsList";
|
||||
import { FrontendInferenceJobType } from "@storyteller/components/src/jobs/InferenceJob";
|
||||
|
||||
export default function VideoMocapJobList(){
|
||||
const failures = (fail = "") => {
|
||||
switch (fail) {
|
||||
case "sample case":
|
||||
return "Sample Case, this should not have been shown";
|
||||
default:
|
||||
return "Unknown failure";
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<InferenceJobsList {...{
|
||||
failures,
|
||||
onSelect: () => Analytics.voiceConversionClickDownload(),
|
||||
jobType: FrontendInferenceJobType.VideoMotionCapture,
|
||||
}}/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
export enum states{
|
||||
NO_FILE,
|
||||
FILE_STAGED,
|
||||
FILE_UPLOADING,
|
||||
FILE_UPLOADED,
|
||||
MOCAPNET_ENQUEUEING,
|
||||
MOCAPNET_ENQUEUED,
|
||||
}
|
||||
|
||||
export type State = {
|
||||
status: number;
|
||||
mediaFileToken?: string;
|
||||
inferenceJobToken?: string;
|
||||
}
|
||||
|
||||
export type Action =
|
||||
| {type: 'uploadFile'}
|
||||
| {type: 'stagedFile'}
|
||||
| {type: 'clearedFile'}
|
||||
| {type: 'uploadFileSuccess', payload:{ mediaFileToken: string}}
|
||||
| {type: 'enqueueMocapNet'}
|
||||
| {type: 'enqueueMocapNetSuccess', payload: {inferenceJobToken: string|undefined}}
|
||||
|
||||
export function reducer (state: State, action: Action): State {
|
||||
console.log(action);
|
||||
switch(action.type){
|
||||
case 'stagedFile':
|
||||
return {...state, status: states.FILE_STAGED}
|
||||
case 'clearedFile':
|
||||
return {...state, status: states.NO_FILE}
|
||||
case 'uploadFile':
|
||||
return {...state,status: states.FILE_UPLOADING};
|
||||
case 'uploadFileSuccess':
|
||||
return {
|
||||
...state,
|
||||
status: states.FILE_UPLOADED,
|
||||
mediaFileToken: action.payload.mediaFileToken
|
||||
}
|
||||
case 'enqueueMocapNet':
|
||||
return {...state, status:states.MOCAPNET_ENQUEUEING}
|
||||
case 'enqueueMocapNetSuccess':
|
||||
return {
|
||||
...state,
|
||||
status: states.MOCAPNET_ENQUEUED,
|
||||
inferenceJobToken: action.payload.inferenceJobToken
|
||||
};
|
||||
default:
|
||||
return {status: states.NO_FILE};
|
||||
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user