mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-12 04:42:16 +00:00
upload file and proceed to filter controls done
This commit is contained in:
1 parent
6e6a442ed8
commit
f6dc1fda6a
7 files changed
+184
-63
No files matched your search
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import { useLocalize } from "hooks";
|
||||
export default function Error({message}:{message?:string}){
|
||||
const {t} = useLocalize("App")
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<h1>{message ? message : t("error.unknownError")}</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import Button from "./Button";
|
||||
import Checkbox from "./Checkbox";
|
||||
import Container from "./Container";
|
||||
import CoverImageInput from "./CoverImageInput";
|
||||
import ErrorMessage from "./ErrorMessage"
|
||||
import FileActions from "./FileActions";
|
||||
import FileDetails from "./FileDetails";
|
||||
import FileWrapper from "./FileWrapper";
|
||||
@@ -28,6 +29,7 @@ import TempInput from "./TempInput";
|
||||
import TempSelect from "./TempSelect";
|
||||
import TempTextArea from "./TempTextArea";
|
||||
import TintSpinner from "./TintSpinner";
|
||||
import VideoInput from "./VideoInput";
|
||||
|
||||
export {
|
||||
AudioBlobPreview,
|
||||
@@ -37,6 +39,7 @@ export {
|
||||
Checkbox,
|
||||
Container,
|
||||
CoverImageInput,
|
||||
ErrorMessage,
|
||||
FileActions,
|
||||
FileDetails,
|
||||
FileWrapper,
|
||||
@@ -59,5 +62,6 @@ export {
|
||||
TempInput,
|
||||
TempSelect,
|
||||
TempTextArea,
|
||||
TintSpinner
|
||||
TintSpinner,
|
||||
VideoInput
|
||||
};
|
||||
@@ -1,17 +1,13 @@
|
||||
import React, {useReducer } from 'react';
|
||||
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
|
||||
import { useInferenceJobs, useLocalize } from "hooks";
|
||||
import { useLocalize } from "hooks";
|
||||
import { FrontendInferenceJobType, InferenceJob } from '@storyteller/components/src/jobs/InferenceJob';
|
||||
|
||||
import { BasicVideo, Button, Container, Panel, Tabs } from "components/common";
|
||||
import { Container, ErrorMessage } from "components/common";
|
||||
import PageHeader from "components/layout/PageHeader";
|
||||
|
||||
import TabContentUpload from "./components/tabContentUpload";
|
||||
import TabContentLibrary from "./components/tabContentLibrary";
|
||||
|
||||
import PageVideoProvision from './components/pageVideoProvision';
|
||||
import PageFilterControls from './components/pageFilterControls';
|
||||
import { states, reducer } from "./storytellerFilterReducer";
|
||||
|
||||
|
||||
@@ -23,26 +19,28 @@ export default function StorytellerFilter(props:{
|
||||
inferenceJobs: Array<InferenceJob>;
|
||||
inferenceJobsByCategory: Map<FrontendInferenceJobType, Array<InferenceJob>>;
|
||||
}){
|
||||
const debug=true;
|
||||
const { t } = useLocalize("StorytellerFilter");
|
||||
const { NO_FILE, FILE_UPLOADING, FILE_LOADED } = states;
|
||||
const { NO_FILE, FILE_STAGED, FILE_UPLOADING, FILE_UPLOADED, FILE_LOADING, FILE_LOADED } = states;
|
||||
const [pageState, dispatchPageState] = useReducer(reducer, {
|
||||
status: NO_FILE,
|
||||
});
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
label: t("tabTitle.upload"),
|
||||
content: <TabContentUpload {...{ t, pageState, dispatchPageState }} />,
|
||||
to: "/storyteller-filter/upload",
|
||||
padding: true,
|
||||
},
|
||||
{
|
||||
label: t("tabTitle.library"),
|
||||
content: <TabContentLibrary {...{ t, pageState, dispatchPageState }} />,
|
||||
to: "/storyteller-filter/select-media",
|
||||
padding: true,
|
||||
},
|
||||
];
|
||||
const pagePicker = () => {
|
||||
switch (pageState.status){
|
||||
case NO_FILE:
|
||||
case FILE_STAGED:
|
||||
case FILE_UPLOADING:
|
||||
return <PageVideoProvision {...{debug, t, pageState, dispatchPageState}}/>
|
||||
case FILE_UPLOADED:
|
||||
case FILE_LOADING:
|
||||
case FILE_LOADED:
|
||||
return <PageFilterControls {...{debug, t, pageState, dispatchPageState}}/>
|
||||
default:
|
||||
return <ErrorMessage/>
|
||||
}
|
||||
}
|
||||
const currPage = pagePicker();
|
||||
|
||||
return(
|
||||
<Container type="panel" className="mb-5">
|
||||
@@ -51,23 +49,7 @@ export default function StorytellerFilter(props:{
|
||||
subText={t("headings.subtitle")}
|
||||
// imageUrl="/images/header/video-mocap.png"
|
||||
/>
|
||||
<Panel>
|
||||
<div className="row g-0">
|
||||
<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={t("video.sample")}
|
||||
src="/videos/face-animator-instruction-en.mp4"
|
||||
/>
|
||||
</Panel>
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
{currPage}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
import React from "react";
|
||||
import { useMedia } from "hooks";
|
||||
import { BucketConfig } from "@storyteller/components/src/api/BucketConfig";
|
||||
import { states, Action, State } from "../storytellerFilterReducer";
|
||||
import { BasicVideo, ErrorMessage, Panel, Spinner } from "components/common";
|
||||
|
||||
export default function PageFilterControls({
|
||||
debug=false, t, pageState, dispatchPageState
|
||||
}: {
|
||||
debug?: boolean;
|
||||
t: Function;
|
||||
pageState: State;
|
||||
dispatchPageState: (action: Action) => void;
|
||||
}) {
|
||||
useMedia({
|
||||
mediaToken: pageState.mediaFileToken,
|
||||
onSuccess: (res: any) => {
|
||||
// ratings.gather({ res, key: "token" });
|
||||
console.log(res)
|
||||
dispatchPageState({
|
||||
type: 'loadFileSuccess',
|
||||
payload: {mediaFile: res}
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
if (pageState.mediaFile){
|
||||
const mediaLink = new BucketConfig().getGcsUrl(pageState.mediaFile.public_bucket_path);
|
||||
if (mediaLink)
|
||||
return(
|
||||
<Panel>
|
||||
<div className="row g-3 p-3">
|
||||
{/* <h1>{t("message.fileUploaded")}</h1> */}
|
||||
{debug && <p>{`File Token: ${pageState.mediaFileToken}`}</p> }
|
||||
<div className="col-6">
|
||||
<BasicVideo src={mediaLink} />
|
||||
</div>
|
||||
<div className="col-6">
|
||||
<BasicVideo src={mediaLink} />
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
);
|
||||
}else if (pageState.status <= states.FILE_LOADING){
|
||||
return (
|
||||
<Panel>
|
||||
{debug && <p>{`File Token: ${pageState.mediaFileToken}`}</p> }
|
||||
<p>Loading Files</p>
|
||||
<Spinner />
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
return <ErrorMessage />;
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
import React from "react";
|
||||
import { Redirect, useLocation } from "react-router-dom";
|
||||
|
||||
import { BasicVideo, Panel, Tabs } from "components/common";
|
||||
|
||||
import { Action, State } from "../storytellerFilterReducer";
|
||||
import TabContentUpload from "./tabContentUpload";
|
||||
import TabContentLibrary from "./tabContentLibrary";
|
||||
|
||||
export default function PageVideoProvision({
|
||||
debug=false, t, pageState, dispatchPageState
|
||||
}: {
|
||||
debug?: boolean;
|
||||
t: Function;
|
||||
pageState: State;
|
||||
dispatchPageState: (action: Action) => void;
|
||||
}) {
|
||||
const tabs = [
|
||||
{
|
||||
label: t("tabTitle.upload"),
|
||||
content: <TabContentUpload {...{
|
||||
debug, t, pageState, dispatchPageState
|
||||
}} />,
|
||||
to: "/storyteller-filter/upload",
|
||||
padding: true,
|
||||
},
|
||||
{
|
||||
label: t("tabTitle.library"),
|
||||
content: <TabContentLibrary {...{
|
||||
debug, t, pageState, dispatchPageState
|
||||
}} />,
|
||||
to: "/storyteller-filter/select-media",
|
||||
padding: true,
|
||||
},
|
||||
];
|
||||
|
||||
//pick default tab using pathname
|
||||
const { pathname } = useLocation();
|
||||
if (pathname === "/storyteller-filter" || pathname === "/storyteller-filter/") {
|
||||
return <Redirect to={"/storyteller-filter/upload"} />;
|
||||
}
|
||||
|
||||
return(
|
||||
<Panel>
|
||||
<div className="row g-0">
|
||||
<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={t("video.sample")}
|
||||
src="/videos/face-animator-instruction-en.mp4"
|
||||
/>
|
||||
</Panel>
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
+15
-9
@@ -3,18 +3,19 @@ import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import { UploadMedia } from "@storyteller/components/src/api/media_files/UploadMedia";
|
||||
import { useFile } from "hooks";
|
||||
|
||||
import VideoInput from "components/common/VideoInput";
|
||||
import { ErrorMessage, VideoInput, Spinner } from "components/common";
|
||||
import { states, Action, State } from "../storytellerFilterReducer";
|
||||
|
||||
export default function TabContentUpload({t, pageState, dispatchPageState}: {
|
||||
export default function TabContentUpload({
|
||||
debug=false, t, pageState, dispatchPageState
|
||||
}: {
|
||||
debug?: boolean;
|
||||
t: Function;
|
||||
pageState: State;
|
||||
dispatchPageState: (action: Action) => void;
|
||||
}) {
|
||||
const videoProps = useFile({});
|
||||
const {NO_FILE, FILE_STAGED} = states;
|
||||
|
||||
const {NO_FILE, FILE_STAGED, FILE_UPLOADING} = states;
|
||||
|
||||
const makeVideoUploadRequest = () => ({
|
||||
uuid_idempotency_token: uuidv4(),
|
||||
@@ -73,12 +74,17 @@ export default function TabContentUpload({t, pageState, dispatchPageState}: {
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
}else if (pageState.status === FILE_UPLOADING){
|
||||
return(
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<h1>{t("message.UnknownError")}</h1>
|
||||
<h1>{t("message.fileUploading")}</h1>
|
||||
</div>
|
||||
<div className="col-12">
|
||||
<Spinner />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
return <ErrorMessage />;
|
||||
}
|
||||
+16
-13
@@ -1,27 +1,29 @@
|
||||
import { MediaFile } from "@storyteller/components/src/api/media_files/GetMediaFile";
|
||||
|
||||
export enum states{
|
||||
NO_FILE,
|
||||
FILE_STAGED,
|
||||
FILE_UPLOADING,
|
||||
FILE_UPLOADED,
|
||||
FILE_LOADING,
|
||||
FILE_LOADED,
|
||||
// MOCAPNET_ENQUEUEING,
|
||||
// MOCAPNET_ENQUEUED,
|
||||
}
|
||||
|
||||
export type State = {
|
||||
status: number;
|
||||
mediaFileToken?: string;
|
||||
mediaFile?: MediaFile;
|
||||
inferenceJobToken?: string;
|
||||
}
|
||||
|
||||
export type Action =
|
||||
| {type: 'uploadFile'}
|
||||
| {type: 'stagedFile'}
|
||||
| {type: 'clearedFile'}
|
||||
| {type: 'uploadFile'}
|
||||
| {type: 'uploadFileSuccess', payload:{ mediaFileToken: string}}
|
||||
// | {type: 'enqueueMocapNet'}
|
||||
// | {type: 'enqueueMocapNetSuccess', payload: {inferenceJobToken: string|undefined}}
|
||||
| {type: 'loadFile'}
|
||||
| {type: 'loadFileSuccess', payload:{mediaFile: MediaFile}}
|
||||
|
||||
|
||||
export function reducer (state: State, action: Action): State {
|
||||
console.log(action);
|
||||
@@ -38,14 +40,15 @@ export function reducer (state: State, action: Action): 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
|
||||
// };
|
||||
case 'loadFile':
|
||||
return {...state, status: states.FILE_LOADING}
|
||||
case 'loadFileSuccess':
|
||||
console.log("LOAD FILE SUCCESS");
|
||||
return {
|
||||
...state,
|
||||
status: states.FILE_LOADED,
|
||||
mediaFile: action.payload.mediaFile
|
||||
}
|
||||
default:
|
||||
return {status: states.NO_FILE};
|
||||
|
||||
|
||||
Reference in new issue
Block a user