diff --git a/packages/fakeyou.com/src/App.tsx b/packages/fakeyou.com/src/App.tsx index f3f71fa77f..aacbd5d7ea 100644 --- a/packages/fakeyou.com/src/App.tsx +++ b/packages/fakeyou.com/src/App.tsx @@ -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 { frontendJobType: FrontendInferenceJobType ) => { const newJob = new InferenceJob(jobToken, frontendJobType); - let inferenceJobs = this.state.inferenceJobs.concat([newJob]); - this.setState({ - inferenceJobs: inferenceJobs, + inferenceJobs: [...this.state.inferenceJobs, newJob], }); }; diff --git a/packages/fakeyou.com/src/components/common/Tabs/Tabs.scss b/packages/fakeyou.com/src/components/common/Tabs/Tabs.scss index 9e5c2bba9d..16337e6dd3 100644 --- a/packages/fakeyou.com/src/components/common/Tabs/Tabs.scss +++ b/packages/fakeyou.com/src/components/common/Tabs/Tabs.scss @@ -32,5 +32,10 @@ background-color: transparent; border-bottom: 4px solid $primary !important; } + + &.disabled{ + color: rgba($white, 0.5) !important; + pointer-events: none; + } } } diff --git a/packages/fakeyou.com/src/components/common/Tabs/Tabs.tsx b/packages/fakeyou.com/src/components/common/Tabs/Tabs.tsx index 8d0277ace4..fec02649f1 100644 --- a/packages/fakeyou.com/src/components/common/Tabs/Tabs.tsx +++ b/packages/fakeyou.com/src/components/common/Tabs/Tabs.tsx @@ -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 (
  • @@ -43,7 +45,7 @@ function TabContent({ children, padding }: TabContentProps) { return
    {children}
    ; } -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} /> ))} diff --git a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/VideoInput/VideoInput.tsx b/packages/fakeyou.com/src/components/common/VideoInput/VideoInput.tsx similarity index 98% rename from packages/fakeyou.com/src/v2/view/pages/video_mocap/components/VideoInput/VideoInput.tsx rename to packages/fakeyou.com/src/components/common/VideoInput/VideoInput.tsx index 3f23c82050..1991fb28d7 100644 --- a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/VideoInput/VideoInput.tsx +++ b/packages/fakeyou.com/src/components/common/VideoInput/VideoInput.tsx @@ -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 { diff --git a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/VideoInput/index.tsx b/packages/fakeyou.com/src/components/common/VideoInput/index.tsx similarity index 100% rename from packages/fakeyou.com/src/v2/view/pages/video_mocap/components/VideoInput/index.tsx rename to packages/fakeyou.com/src/components/common/VideoInput/index.tsx diff --git a/packages/fakeyou.com/src/components/common/VideoInput/videoinput.scss b/packages/fakeyou.com/src/components/common/VideoInput/videoinput.scss new file mode 100644 index 0000000000..37337a34d8 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/VideoInput/videoinput.scss @@ -0,0 +1,5 @@ +@import "scss/colours.scss"; + +.upload-details { + background-color: rgba($panel, .85); +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/layout/InferenceJobsList/InferenceJobsList.tsx b/packages/fakeyou.com/src/components/layout/InferenceJobsList/InferenceJobsList.tsx index d6cf6cda6e..8b33cc9fa8 100644 --- a/packages/fakeyou.com/src/components/layout/InferenceJobsList/InferenceJobsList.tsx +++ b/packages/fakeyou.com/src/components/layout/InferenceJobsList/InferenceJobsList.tsx @@ -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 ?
    -
    { t("core.heading") }
    - { - inferenceJobs.map((job: InferenceJob, key: number) => - console.log(ref), - ...job }} />).reverse() - } -
    : null; + if (inferenceJobs.length){ + return( +
    +
    { t("core.heading") }
    + { + inferenceJobs.map((job: InferenceJob, key: number) => + ).reverse() + } +
    + ) + } + else{ + return null; + } + }; \ No newline at end of file diff --git a/packages/fakeyou.com/src/scss/site-refresh.scss b/packages/fakeyou.com/src/scss/site-refresh.scss index 090b514b7f..26149cb445 100644 --- a/packages/fakeyou.com/src/scss/site-refresh.scss +++ b/packages/fakeyou.com/src/scss/site-refresh.scss @@ -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; diff --git a/packages/fakeyou.com/src/v2/view/pages/video_mocap/VideoMocap.tsx b/packages/fakeyou.com/src/v2/view/pages/video_mocap/VideoMocap.tsx index 1af03e7fac..6181cb6348 100644 --- a/packages/fakeyou.com/src/v2/view/pages/video_mocap/VideoMocap.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/video_mocap/VideoMocap.tsx @@ -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: , + content: , to: "/video-mocap/upload", padding: true, }, { label: t("tabTitle.library"), - content: , + content: , to: "/video-mocap/select-media", padding: true, }, @@ -89,35 +72,34 @@ export default function VideoMotionCapture(props: { />
    - {/*Video Provision Tabs & Job Statuses*/} -
    - {pageState.index === VIDEO_PROVISION && } - {pageState.index === SHOW_JOB_STATUS && ( - - )} -
    - {/*ENDS Video Chooser Tabs*/} - -
    - - - -
    + { pageState.status < FILE_UPLOADING && <> +
    + +
    +
    + + + +
    + } + { pageState.status >= FILE_UPLOADING && pageState.status < MOCAPNET_ENQUEUED && +
    + +
    + } + { pageState.status === MOCAPNET_ENQUEUED && +
    +

    {t("tab.message.mocapNetRequestSucceed")}

    +
    + }
    {/*2nd row*/}
    {/*panel*/} + ); } diff --git a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/VideoInput/style.scss b/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/VideoInput/style.scss deleted file mode 100644 index 0666365c61..0000000000 --- a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/VideoInput/style.scss +++ /dev/null @@ -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); -} \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/pageInferenceStatuses.tsx b/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/pageInferenceStatuses.tsx deleted file mode 100644 index 7448dc5644..0000000000 --- a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/pageInferenceStatuses.tsx +++ /dev/null @@ -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( - <> -

    {t("tab.message.mocapNetRequestSucceed")}

    -

    Job Token: {pageState.jobToken}

    - - Analytics.voiceConversionClickDownload(), - jobType: FrontendInferenceJobType.FaceAnimation, - }}/> - - ) -} \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/pageVideoMocapProgress.tsx b/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/pageVideoMocapProgress.tsx new file mode 100644 index 0000000000..fe1228608b --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/pageVideoMocapProgress.tsx @@ -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 ( +
    +
    +

    {t("tab.message.fileUploading")}

    +
    +
    + +
    +
    + ); + } else if (pageState.status === FILE_UPLOADED) { + return ( +
    +
    +

    {t("tab.message.fileUploaded")}

    +
    +
    + +
    +
    + ); + } else if (pageState.status === MOCAPNET_ENQUEUEING) { + return ( +
    +
    +

    {t("tab.message.mocapNetRequesting")}

    +
    +
    + +
    +
    + ); + } + return( +
    +
    +

    {t("message.UnknownError")}

    +
    +
    + ); +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/pageVideoProvision.tsx b/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/pageVideoProvision.tsx deleted file mode 100644 index 65bb821b75..0000000000 --- a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/pageVideoProvision.tsx +++ /dev/null @@ -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(<> -
      -
    • - -
    • -
    • - -
    • -
    -
    - - -
    - ); -} \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/tabContentLibrary.tsx b/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/tabContentLibrary.tsx index d667216da7..4136300a2e 100644 --- a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/tabContentLibrary.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/tabContentLibrary.tsx @@ -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 (
    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(NO_FILE); - const [token, setToken] = useState(""); + 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 ( -
    + <>
    - 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"}) + } }} />
    @@ -82,7 +63,7 @@ export default function TabContentUpload(props: {
    -
    - ); - } else if (tabState === FILE_UPLOADING) { - return ( -
    -
    -
    -

    {t("tab.message.fileUploading")}

    -
    -
    -
    - ); - } else if (tabState === FILE_UPLOADED) { - return ( -
    -
    -
    -

    {t("tab.message.fileUploaded")}

    -
    -
    - -
    -
    -
    - ); - } else if (tabState === MOCAPNET) { - return ( -
    -
    -
    -

    {t("tab.message.mocapNetRequesting")}

    -
    -
    -
    - ); - } else { - return ( -
    -
    -
    -

    {t("message.UnknownError")}

    -
    -
    -
    + ); } + return ( +
    +
    +

    {t("message.UnknownError")}

    +
    +
    + ); } diff --git a/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/videoMocapJobList.tsx b/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/videoMocapJobList.tsx new file mode 100644 index 0000000000..b98ad4031b --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/video_mocap/components/videoMocapJobList.tsx @@ -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 ( + Analytics.voiceConversionClickDownload(), + jobType: FrontendInferenceJobType.VideoMotionCapture, + }}/> + ); +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/video_mocap/videoMocapReducer.tsx b/packages/fakeyou.com/src/v2/view/pages/video_mocap/videoMocapReducer.tsx new file mode 100644 index 0000000000..a9050fc6a9 --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/video_mocap/videoMocapReducer.tsx @@ -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}; + + } +} \ No newline at end of file