From 83226f2d2f04712f08ba5411fb4be166208005ed Mon Sep 17 00:00:00 2001 From: wil Date: Sun, 4 Feb 2024 00:46:39 -0500 Subject: [PATCH 1/7] input Seed component --- .../fakeyou.com/src/scss/site-refresh.scss | 14 ++++ .../components/inputSeed.tsx | 67 +++++++++++++++++++ .../components/pageFilterControls.tsx | 11 ++- 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/inputSeed.tsx diff --git a/packages/fakeyou.com/src/scss/site-refresh.scss b/packages/fakeyou.com/src/scss/site-refresh.scss index dc32fc7c6b..58af52afc2 100644 --- a/packages/fakeyou.com/src/scss/site-refresh.scss +++ b/packages/fakeyou.com/src/scss/site-refresh.scss @@ -36,6 +36,20 @@ styles with important tags: .ratio-1x1 { aspect-ratio: 1/1; } + /* Chrome, Safari, Edge, Opera */ + .numberInputNoArrows input::-webkit-outer-spin-button, + .numberInputNoArrows input::-webkit-inner-spin-button, + input.numberInputNoArrows::-webkit-outer-spin-button, + input.numberInputNoArrows::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + /* Firefox */ + .numberInputNoArrows input[type=number], + input.numberInputNoArrows[type=number] { + -moz-appearance: textfield; + } + //-end--// ::-webkit-scrollbar-thumb { diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/inputSeed.tsx b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/inputSeed.tsx new file mode 100644 index 0000000000..1ad61f4e27 --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/inputSeed.tsx @@ -0,0 +1,67 @@ +import React, {useState} from 'react'; +import { + Input, + SegmentButtons +} from "components/common"; + +export default function InputSeet({ + label, + onChange : onChangeCallback +}:{ + label:string + onChange: (newSeed: string)=>void +}){ + function generateRandomSeed(){ + return Math.floor(Math.random() * Math.pow(2, 32)).toString(); + }; + + const [inputType, setInputType] = useState<"random"|"custom">("random"); + const [seedValue, setSeedValue] = useState(generateRandomSeed()); + + const handleInputTypeChange = (e:any) => { + console.log(typeof e); + const newValue = e.target.value; + if (newValue === "custom") { + setInputType("custom"); + } else { + const newRandom = generateRandomSeed(); + setInputType("random"); + setSeedValue(newRandom); + onChangeCallback(newRandom); + } + }; + const handleSeedChange = (event: any) => { + const customSeed = event.target.value; + setInputType("custom"); + setSeedValue(customSeed); + onChangeCallback(customSeed); + }; + + const seedOpts = [ + { label: "Random", value: "random" }, + { label: "Custom", value: "custom" }, + ]; + + return( +
+ +
+ + +
+
+ ) +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx index 0d90ab03b9..fe0e32151e 100644 --- a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx @@ -1,4 +1,4 @@ -import React, {useState, useEffect} from "react"; +import React, {useState, useEffect, useRef} from "react"; import { useParams } from "react-router-dom"; import { useMedia } from "hooks"; @@ -14,7 +14,7 @@ import { Spinner, TextAreaV2 } from "components/common"; - +import InputSeed from "./inputSeed"; import { faChevronRight } from "@fortawesome/pro-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -45,7 +45,8 @@ export default function PageFilterControls({ posPrompt: "", negPrompt: "", firstPass: 15, - upScalePass: 15 + upScalePass: 15, + seed: "", }); useEffect(()=>{ if(debug) console.log(filterState) @@ -57,6 +58,7 @@ export default function PageFilterControls({ if (pageState.mediaFile){ const mediaLink = new BucketConfig().getGcsUrl(pageState.mediaFile.public_bucket_path); + if (mediaLink) return( <> @@ -142,6 +144,9 @@ export default function PageFilterControls({ required: false, }} /> + handleOnChange("seed", val) + }/> From 5f4b74cb08cf25f6b64476dd1c66730486ed4473 Mon Sep 17 00:00:00 2001 From: wil Date: Sun, 4 Feb 2024 02:15:01 -0500 Subject: [PATCH 2/7] UI visuals done --- .../common/NumberSliderV2/NumberSliderV2.tsx | 2 +- .../components/pageFilterControls.tsx | 338 +++++++++++++++--- .../storytellerFilterReducer.tsx | 7 +- 3 files changed, 302 insertions(+), 45 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/NumberSliderV2/NumberSliderV2.tsx b/packages/fakeyou.com/src/components/common/NumberSliderV2/NumberSliderV2.tsx index 4796403494..74519c1364 100644 --- a/packages/fakeyou.com/src/components/common/NumberSliderV2/NumberSliderV2.tsx +++ b/packages/fakeyou.com/src/components/common/NumberSliderV2/NumberSliderV2.tsx @@ -56,7 +56,7 @@ export default function NumberSlider({ }: Props) { const step = stepProps && stepProps <= max-min ? stepProps : max-min >= 1 ? 1 : (max-min) / 10; - const initialValue = initialValueProps && initialValueProps <= max && initialValueProps >= min ? initialValueProps + const initialValue = initialValueProps !== undefined && initialValueProps <= max && initialValueProps >= min ? initialValueProps : max-min === step ? min : roundToStep((max+min)/2, step); function handleInputOnChange(e: React.ChangeEvent){ diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx index fe0e32151e..572eceebb2 100644 --- a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx @@ -7,7 +7,9 @@ import { states, Action, State } from "../storytellerFilterReducer"; import { Accordion, BasicVideo, + Checkbox, ErrorMessage, + Input, NumberSliderV2, Panel, SelectModal, @@ -27,26 +29,36 @@ export default function PageFilterControls({ dispatchPageState: (action: Action) => void; }) { const { mediaToken } = useParams(); - useMedia({ mediaToken: pageState.mediaFileToken || mediaToken, onSuccess: (res: any) => { // ratings.gather({ res, key: "token" }); dispatchPageState({ type: 'loadFileSuccess', - payload: {mediaFile: res} + payload: { + mediaFile: res, + mediaFileToken: pageState.mediaFileToken || mediaToken + } }) }, }); const [filterState, setFilterState] = useState({ + seed: "", sdModelToken: "", loraModelToken: "", posPrompt: "", negPrompt: "", - firstPass: 15, - upScalePass: 15, - seed: "", + firstPass: 1, + upscalePass: 0.42, + motionScale:1, + upscaleMultiplier: 1.5, + useEmptyLatent: false, + useFaceDetailer: false, + denoiseFaceDetailer: 0.45, + useLCM: false, + lcmCFG: 2, + lcmSteps: 8 }); useEffect(()=>{ if(debug) console.log(filterState) @@ -77,7 +89,7 @@ export default function PageFilterControls({ - +
+
+
- handleOnChange("posPrompt", val), - value: filterState.posPrompt, - required: false, - }} - /> - handleOnChange("negPrompt", val), - value: filterState.negPrompt, - required: false, - }} - /> +
+
+
+ handleOnChange("posPrompt", val), + value: filterState.posPrompt, + required: false, + }} + /> +
+
+ handleOnChange("negPrompt", val), + value: filterState.negPrompt, + required: false, + }} + /> +
+
+
handleOnChange("seed", val) }/>
+
- +
- {handleOnChange("firstPass",val)} +
+ {handleOnChange("firstPass",val)} + }}/> +
+
+ {handleOnChange("upscalePass", val)} }}/> - {handleOnChange("upScalePass", val)} - }}/> -
+
+
+
+
+ {handleOnChange("motionScale", val)} + }}/> +
+
+ {handleOnChange("upscaleMultiplier", val)} + }}/> +
+
+
+
+ {handleOnChange("useEmptyLatent", e.target.checked)}} + /> +
+
+ {handleOnChange("useFaceDetailer", e.target.checked)}} + /> +
+
+
+
+ +
+
+ {handleOnChange("denoiseFaceDetailer", val)} + }}/> +
+
+
+ {handleOnChange("useLCM", e.target.checked)}} + /> +
+
+
+ {handleOnChange("lcmCFG", val)} + }}/> +
+
+ {handleOnChange("lcmSteps", val)} + }}/> +
+
+
+ +
+ { + console.log(`Use Control Nets: ${e.target.checked}`) + }} + /> +
+
+
+ {console.log(`Canny: ${val}`)} + }}/> +
+
+ {console.log(`Line Art Anime: ${val}`)} + }}/> +
+
+
+
+ {console.log(`Depth: ${val}`)} + }}/> +
+
+ {console.log(`OpenPose: ${val}`)} + }}/> +
+
+
+
+ {console.log(`Media Pipe Face: ${val}`)} + }}/> +
+
+ {console.log(`Sparse Scribble: ${val}`)} + }}/> +
+
+
+
+ {console.log(`Video CN: ${val}`)} + }}/> +
+
+ {console.log(`Tile CN: ${val}`)} + }}/> +
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterReducer.tsx b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterReducer.tsx index 7da0a9e6cd..87f44546a9 100644 --- a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterReducer.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterReducer.tsx @@ -24,7 +24,9 @@ export type Action = | {type: 'uploadFile'} | {type: 'uploadFileSuccess', payload:{ mediaFileToken: string}} | {type: 'loadFile'} - | {type: 'loadFileSuccess', payload:{mediaFile: MediaFile}} + | {type: 'loadFileSuccess', payload:{ + mediaFileToken: string, mediaFile: MediaFile + }} export function reducer (state: State, action: Action): State { @@ -55,7 +57,8 @@ export function reducer (state: State, action: Action): State { return { ...state, status: states.FILE_LOADED, - mediaFile: action.payload.mediaFile + mediaFile: action.payload.mediaFile, + mediaFileToken : action.payload.mediaFileToken, } default: return {status: states.NO_FILE}; From dab490779b4f4e78c1f22fa881d3d63ac5931fbf Mon Sep 17 00:00:00 2001 From: wil Date: Sun, 4 Feb 2024 02:23:31 -0500 Subject: [PATCH 3/7] fixing for netlify --- .../pages/storyteller_filter/components/pageFilterControls.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx index 572eceebb2..c49c18f257 100644 --- a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx @@ -1,4 +1,4 @@ -import React, {useState, useEffect, useRef} from "react"; +import React, {useState, useEffect} from "react"; import { useParams } from "react-router-dom"; import { useMedia } from "hooks"; From 10993a48dbf0f6a9dee7a3b305415445087b73bf Mon Sep 17 00:00:00 2001 From: wil Date: Sun, 4 Feb 2024 09:27:39 -0500 Subject: [PATCH 4/7] input seed now is bubbled up to become a common component --- .../src/components/common/InputSeed/index.tsx | 1 + .../common/InputSeed}/inputSeed.tsx | 33 +++++++++++-------- .../src/components/common/index.tsx | 2 ++ .../src/resources/generateRandomSeed.tsx | 3 ++ .../components/pageFilterControls.tsx | 2 +- 5 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 packages/fakeyou.com/src/components/common/InputSeed/index.tsx rename packages/fakeyou.com/src/{v2/view/pages/storyteller_filter/components => components/common/InputSeed}/inputSeed.tsx (63%) create mode 100644 packages/fakeyou.com/src/resources/generateRandomSeed.tsx diff --git a/packages/fakeyou.com/src/components/common/InputSeed/index.tsx b/packages/fakeyou.com/src/components/common/InputSeed/index.tsx new file mode 100644 index 0000000000..9dd299f773 --- /dev/null +++ b/packages/fakeyou.com/src/components/common/InputSeed/index.tsx @@ -0,0 +1 @@ +export { default } from "./inputSeed"; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/inputSeed.tsx b/packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx similarity index 63% rename from packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/inputSeed.tsx rename to packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx index 1ad61f4e27..7b29255b55 100644 --- a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/inputSeed.tsx +++ b/packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx @@ -1,25 +1,32 @@ -import React, {useState} from 'react'; +import React, {useState, useEffect, memo} from 'react'; import { Input, SegmentButtons } from "components/common"; -export default function InputSeet({ +import generateRandomSeed from 'resources/generateRandomSeed'; + +export default memo (function InputSeed({ label, + initialValue : initialValueProps, onChange : onChangeCallback }:{ - label:string - onChange: (newSeed: string)=>void + label:string; + initialValue?: string; + onChange: (newSeed: string)=>void; }){ - function generateRandomSeed(){ - return Math.floor(Math.random() * Math.pow(2, 32)).toString(); - }; - const [inputType, setInputType] = useState<"random"|"custom">("random"); - const [seedValue, setSeedValue] = useState(generateRandomSeed()); + const [seedValue, setSeedValue] = useState(initialValueProps || ""); + useEffect(()=>{ + // console.log('should run only once when mount') + if (!initialValueProps && seedValue===""){ + const newRandom = generateRandomSeed(); + setSeedValue(newRandom); + onChangeCallback(newRandom); + } + },[initialValueProps, onChangeCallback, seedValue]); const handleInputTypeChange = (e:any) => { - console.log(typeof e); const newValue = e.target.value; if (newValue === "custom") { setInputType("custom"); @@ -30,8 +37,8 @@ export default function InputSeet({ onChangeCallback(newRandom); } }; - const handleSeedChange = (event: any) => { - const customSeed = event.target.value; + const handleSeedChange = (e: any) => { + const customSeed = e.target.value; setInputType("custom"); setSeedValue(customSeed); onChangeCallback(customSeed); @@ -64,4 +71,4 @@ export default function InputSeet({ ) -} \ No newline at end of file +}); \ No newline at end of file diff --git a/packages/fakeyou.com/src/components/common/index.tsx b/packages/fakeyou.com/src/components/common/index.tsx index a974ceb528..40186126df 100644 --- a/packages/fakeyou.com/src/components/common/index.tsx +++ b/packages/fakeyou.com/src/components/common/index.tsx @@ -14,6 +14,7 @@ import FileWrapper from "./FileWrapper"; import FileLabel from "./FileLabel"; import ImageInput from "./ImageInput"; import Input from "./Input"; +import InputSeed from "./InputSeed"; import Label from "./Label"; import MocapInput from "./MocapInput"; import Modal from "./Modal"; @@ -55,6 +56,7 @@ export { FileLabel, ImageInput, Input, + InputSeed, Label, MocapInput, Modal, diff --git a/packages/fakeyou.com/src/resources/generateRandomSeed.tsx b/packages/fakeyou.com/src/resources/generateRandomSeed.tsx new file mode 100644 index 0000000000..8dffb33037 --- /dev/null +++ b/packages/fakeyou.com/src/resources/generateRandomSeed.tsx @@ -0,0 +1,3 @@ +export default function generateRandomSeed(){ + return Math.floor(Math.random() * Math.pow(2, 32)).toString(); +}; \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx index c49c18f257..8707a78f16 100644 --- a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageFilterControls.tsx @@ -10,13 +10,13 @@ import { Checkbox, ErrorMessage, Input, + InputSeed, NumberSliderV2, Panel, SelectModal, Spinner, TextAreaV2 } from "components/common"; -import InputSeed from "./inputSeed"; import { faChevronRight } from "@fortawesome/pro-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; From 457cef55b6a56e66686286bb57f0b415a1e03734 Mon Sep 17 00:00:00 2001 From: wil Date: Mon, 5 Feb 2024 10:45:05 -0500 Subject: [PATCH 5/7] improved input seed to fit bombay's uiux spec --- .../components/common/InputSeed/inputSeed.tsx | 65 +++++++++++++------ 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx b/packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx index 7b29255b55..a5e4e6e4a3 100644 --- a/packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx +++ b/packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx @@ -1,4 +1,5 @@ import React, {useState, useEffect, memo} from 'react'; +import { useLocalize } from 'hooks'; import { Input, SegmentButtons @@ -7,46 +8,67 @@ import { import generateRandomSeed from 'resources/generateRandomSeed'; export default memo (function InputSeed({ + t: tProps, label, initialValue : initialValueProps, onChange : onChangeCallback }:{ + t?: Function label:string; initialValue?: string; onChange: (newSeed: string)=>void; }){ - const [inputType, setInputType] = useState<"random"|"custom">("random"); - const [seedValue, setSeedValue] = useState(initialValueProps || ""); + const {t:tHook} = useLocalize("SeedInput"); + const t = tProps ? tProps : tHook; + const[{firstLoad, inputType, seedValue}, setState] = useState<{ + firstLoad: boolean; + inputType: "random" | "custom"; + seedValue: string; + }>({ + firstLoad: false, + inputType: "random", + seedValue: "" + }) + const setNewRandomSeed = (newType:"custom"|"random")=>{ + const newRandom = generateRandomSeed(); + setState({ + firstLoad: true, + inputType: newType, + seedValue: newRandom + }); + onChangeCallback(newRandom); + }; useEffect(()=>{ - // console.log('should run only once when mount') - if (!initialValueProps && seedValue===""){ - const newRandom = generateRandomSeed(); - setSeedValue(newRandom); - onChangeCallback(newRandom); + if (!initialValueProps && !firstLoad){ + setNewRandomSeed("random"); } - },[initialValueProps, onChangeCallback, seedValue]); + },[initialValueProps, setNewRandomSeed]); + const handleInputTypeChange = (e:any) => { const newValue = e.target.value; if (newValue === "custom") { - setInputType("custom"); + setNewRandomSeed("custom"); } else { - const newRandom = generateRandomSeed(); - setInputType("random"); - setSeedValue(newRandom); - onChangeCallback(newRandom); + setNewRandomSeed("random"); } }; const handleSeedChange = (e: any) => { const customSeed = e.target.value; - setInputType("custom"); - setSeedValue(customSeed); + setState({ + firstLoad: true, + inputType: "custom", + seedValue: customSeed + }) onChangeCallback(customSeed); }; - + const handleOnBlur = () => { + if(inputType==="custom" && seedValue==="") + setNewRandomSeed(inputType); + } const seedOpts = [ - { label: "Random", value: "random" }, - { label: "Custom", value: "custom" }, + { label: t("random"), value: "random" }, + { label: t("custom"), value: "custom" }, ]; return( @@ -55,7 +77,7 @@ export default memo (function InputSeed({
From a9b5abdbcf0842d9a68b036f92416d2d8529e62a Mon Sep 17 00:00:00 2001 From: wil Date: Mon, 5 Feb 2024 10:48:39 -0500 Subject: [PATCH 6/7] dealing with react warning --- .../src/components/common/InputSeed/inputSeed.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx b/packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx index a5e4e6e4a3..93c91d64af 100644 --- a/packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx +++ b/packages/fakeyou.com/src/components/common/InputSeed/inputSeed.tsx @@ -1,4 +1,4 @@ -import React, {useState, useEffect, memo} from 'react'; +import React, {useState, useEffect, useCallback, memo} from 'react'; import { useLocalize } from 'hooks'; import { Input, @@ -29,7 +29,7 @@ export default memo (function InputSeed({ inputType: "random", seedValue: "" }) - const setNewRandomSeed = (newType:"custom"|"random")=>{ + const setNewRandomSeed = useCallback((newType:"custom"|"random")=>{ const newRandom = generateRandomSeed(); setState({ firstLoad: true, @@ -37,12 +37,12 @@ export default memo (function InputSeed({ seedValue: newRandom }); onChangeCallback(newRandom); - }; + }, [onChangeCallback]); useEffect(()=>{ if (!initialValueProps && !firstLoad){ setNewRandomSeed("random"); } - },[initialValueProps, setNewRandomSeed]); + },[initialValueProps, firstLoad, setNewRandomSeed]); const handleInputTypeChange = (e:any) => { From 0dd87a9a6fcbe7149d2dd9f3a360edc3bbb2d34d Mon Sep 17 00:00:00 2001 From: wil Date: Mon, 5 Feb 2024 17:59:38 -0500 Subject: [PATCH 7/7] completed UI flow --- packages/components/src/api/ApiConfig.ts | 5 + .../EnqueueStorytellerFilter.tsx | 68 ++++++ .../src/api/storyteller_filter/index.ts | 7 + packages/components/src/jobs/InferenceJob.ts | 3 +- packages/fakeyou.com/src/App.tsx | 1 + .../src/components/common/Input/Input.tsx | 4 +- .../storyteller_filter/StorytellerFilter.tsx | 24 +- .../components/pageFilterControls.tsx | 211 ++++++++++-------- .../components/pageJobList.tsx | 49 ++++ .../storytellerFilterReducer.tsx | 15 ++ .../storytellerFilterRoutes.tsx | 4 + 11 files changed, 296 insertions(+), 95 deletions(-) create mode 100644 packages/components/src/api/storyteller_filter/EnqueueStorytellerFilter.tsx create mode 100644 packages/components/src/api/storyteller_filter/index.ts create mode 100644 packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageJobList.tsx diff --git a/packages/components/src/api/ApiConfig.ts b/packages/components/src/api/ApiConfig.ts index 103a13eb4e..59df11f2ba 100644 --- a/packages/components/src/api/ApiConfig.ts +++ b/packages/components/src/api/ApiConfig.ts @@ -496,6 +496,11 @@ class ApiConfig { return `${this.getApiOrigin()}/v1/mocap/mocapnet/create`; } + // =============== Storyteller Filter =============== + enqueueStorytellerFilter(): string { + return `${this.getApiOrigin()}/v1/workflow/comfy/create`; + } + // =============== Convert FBX to glTF =============== enqueueFbxToGltf(): string { return `${this.getApiOrigin()}/v1/conversion/enqueue_fbx_to_gltf`; diff --git a/packages/components/src/api/storyteller_filter/EnqueueStorytellerFilter.tsx b/packages/components/src/api/storyteller_filter/EnqueueStorytellerFilter.tsx new file mode 100644 index 0000000000..1da9000fc3 --- /dev/null +++ b/packages/components/src/api/storyteller_filter/EnqueueStorytellerFilter.tsx @@ -0,0 +1,68 @@ +import { ApiConfig } from "@storyteller/components"; + +export interface EnqueueStorytellerFilterRequest { + "uuid_idempotency_token": string, + + "maybe_sd_model": string, + "maybe_workflow_config": string, + "maybe_input_file": string, + "maybe_output_path": string, + "maybe_json_modifications": { + "$.510.inputs.Text": string, + "$.8.inputs.text": string, + "$.173.inputs.seed": string, + "$.401.inputs.Value": number, + "$.918.inputs.Value": number, + "$.137.inputs.Value": number, + "$.186.inputs.Value": number, + "$.140.inputs.Value":number, + "$.154.inputs.Value": number, + "$.445.inputs.number": number, + "$.947.inputs.Value": number, + "$.800.inputs.Value": number, + "$.797.inputs.Value": number, + "$.796.inputs.Value": number, + "$.772.inputs.Value": number, + "$.771.inputs.Value": number, + "$.527.inputs.Value": number, + "$.403.inputs.Value": number, + } +} + +export interface EnqueueStorytellerFilterResponse { + success: boolean, + inference_job_token?: string, +} + +export async function EnqueueStorytellerFilter(request: EnqueueStorytellerFilterRequest) : Promise +{ + // const endpoint = "/v1/workflow/comfy/create"; + + const endpoint = new ApiConfig().enqueueStorytellerFilter(); + + return await fetch(endpoint, { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + credentials: 'include', + body: JSON.stringify(request), + }) + .then(res => res.json()) + .then(res => { + if (!res) { + return { success : false }; + } + + if (res && 'success' in res) { + return res; + } else { + return { success : false }; + } + }) + .catch(e => { + return { success : false }; + }); +} + diff --git a/packages/components/src/api/storyteller_filter/index.ts b/packages/components/src/api/storyteller_filter/index.ts new file mode 100644 index 0000000000..aebe56e156 --- /dev/null +++ b/packages/components/src/api/storyteller_filter/index.ts @@ -0,0 +1,7 @@ +export type { + EnqueueStorytellerFilterRequest, EnqueueStorytellerFilterResponse, +} from './EnqueueStorytellerFilter'; + +export { + EnqueueStorytellerFilter +} from './EnqueueStorytellerFilter'; \ No newline at end of file diff --git a/packages/components/src/jobs/InferenceJob.ts b/packages/components/src/jobs/InferenceJob.ts index 53aa9ae0f7..88388e07b2 100644 --- a/packages/components/src/jobs/InferenceJob.ts +++ b/packages/components/src/jobs/InferenceJob.ts @@ -11,7 +11,8 @@ export enum FrontendInferenceJobType { ImageGeneration, VideoMotionCapture, ConvertFbxtoGltf, - EngineComposition + EngineComposition, + StorytellerFilter, } // NB: Many of these fields are optional despite the response payload containing them diff --git a/packages/fakeyou.com/src/App.tsx b/packages/fakeyou.com/src/App.tsx index 12e574f6ff..e6b7de0e21 100644 --- a/packages/fakeyou.com/src/App.tsx +++ b/packages/fakeyou.com/src/App.tsx @@ -210,6 +210,7 @@ function initInferenceJobsByCategoryMap(): Map< inferenceJobsByCategory.set(FrontendInferenceJobType.VideoMotionCapture, []); inferenceJobsByCategory.set(FrontendInferenceJobType.ImageGeneration, []); inferenceJobsByCategory.set(FrontendInferenceJobType.ConvertFbxtoGltf, []); + inferenceJobsByCategory.set(FrontendInferenceJobType.StorytellerFilter, []) return inferenceJobsByCategory; } diff --git a/packages/fakeyou.com/src/components/common/Input/Input.tsx b/packages/fakeyou.com/src/components/common/Input/Input.tsx index edfaef74c0..b9fe5ca2fb 100644 --- a/packages/fakeyou.com/src/components/common/Input/Input.tsx +++ b/packages/fakeyou.com/src/components/common/Input/Input.tsx @@ -5,14 +5,14 @@ import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; interface InputProps extends React.InputHTMLAttributes { icon?: IconDefinition; label?: string; - textArea?: boolean; + // textArea?: boolean; className?: string; } export default function Input({ label, icon, - textArea, + // textArea, className, ...rest }: InputProps) { diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/StorytellerFilter.tsx b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/StorytellerFilter.tsx index 5ee9447359..624df75df1 100644 --- a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/StorytellerFilter.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/StorytellerFilter.tsx @@ -1,6 +1,6 @@ -import React, {useReducer } from 'react'; +import React, {useReducer, useEffect } from 'react'; -import { useLocalize } from "hooks"; +import { useInferenceJobs, useLocalize } from "hooks"; import { FrontendInferenceJobType, InferenceJob } from '@storyteller/components/src/jobs/InferenceJob'; import { Container } from "components/common"; @@ -24,6 +24,26 @@ export default function StorytellerFilter(props:{ status: NO_FILE, }); + const { enqueueInferenceJob } = props; + useInferenceJobs( + FrontendInferenceJobType.StorytellerFilter + ); + useEffect(() => { + if ( + pageState.status === states.FILTER_ENQUEUED && + pageState.inferenceJobToken + ) { + enqueueInferenceJob( + pageState.inferenceJobToken, + FrontendInferenceJobType.StorytellerFilter + ); + dispatchPageState({ + type: "enqueueFilterSuccess", + payload: { inferenceJobToken: undefined }, + }); + } + }, [pageState, enqueueInferenceJob]); + return( { - // ratings.gather({ res, key: "token" }); dispatchPageState({ type: 'loadFileSuccess', payload: { @@ -44,6 +47,8 @@ export default function PageFilterControls({ }); const [filterState, setFilterState] = useState({ + outputPath: "vid2vid/SparseUpscaleInterp_00001.mp4", + workflowConfig: "weight_q8sz47gmfw2zx02snrbz88ns9", seed: "", sdModelToken: "", loraModelToken: "", @@ -58,16 +63,74 @@ export default function PageFilterControls({ denoiseFaceDetailer: 0.45, useLCM: false, lcmCFG: 2, - lcmSteps: 8 + lcmSteps: 8, + framesCap:16, + skipFrames:0, + nthFrames:2, + inputFps: 24, + interpolationMutiplier: 2, + cnTile: 0, + cnCanny: 0, + cnLinearAnime: 0, + cnLinearRealistic: 0, + cnDepth: 0, + cnOpenPose: 0, + cnPipeFace: 0, + cnSparse: 0.7, }); - useEffect(()=>{ - if(debug) console.log(filterState) - },[filterState, debug]) const handleOnChange = (key: string, newValue:any,) => { setFilterState((curr)=>({...curr, [key]: newValue})); } + const history = useHistory(); + const handleGenerate = ()=>{ + console.log("filterState:") + console.log(filterState) + + const request = { + "uuid_idempotency_token": uuidv4(), + "maybe_sd_model": filterState.sdModelToken, + "maybe_workflow_config": filterState.workflowConfig, + "maybe_input_file": pageState.mediaFileToken || mediaToken, + "maybe_output_path": filterState.outputPath, + "maybe_json_modifications": { + "$.510.inputs.Text": filterState.posPrompt, + "$.8.inputs.text": filterState.negPrompt, + "$.173.inputs.seed": filterState.seed, + "$.401.inputs.Value": filterState.firstPass, + "$.918.inputs.Value": filterState.motionScale, + "$.137.inputs.Value": filterState.framesCap, + "$.186.inputs.Value": filterState.skipFrames, + "$.140.inputs.Value": filterState.nthFrames, + "$.154.inputs.Value": filterState.inputFps, + "$.445.inputs.number": filterState.interpolationMutiplier, + "$.947.inputs.Value": filterState.cnTile, + "$.800.inputs.Value": filterState.cnCanny, + "$.797.inputs.Value": filterState.cnLinearAnime, + "$.796.inputs.Value": filterState.cnLinearRealistic, + "$.772.inputs.Value": filterState.cnDepth, + "$.771.inputs.Value": filterState.cnOpenPose, + "$.527.inputs.Value": filterState.cnPipeFace, + "$.403.inputs.Value": filterState.cnSparse + }, + } + EnqueueStorytellerFilter(request).then(res => { + if (res.success && res.inference_job_token) { + dispatchPageState({ + type: 'enqueueFilterSuccess', + payload: { + inferenceJobToken: res.inference_job_token + } + }) + }else{ + console.log(res); + } + }) + dispatchPageState({type: 'enqueueFilter'}) + history.push("/storyteller-filter/jobs"); + } + if (pageState.mediaFile){ const mediaLink = new BucketConfig().getGcsUrl(pageState.mediaFile.public_bucket_path); @@ -76,7 +139,6 @@ export default function PageFilterControls({ <>
- {debug &&

{`File Token: ${pageState.mediaFileToken}`}

}
@@ -143,22 +205,22 @@ export default function PageFilterControls({
- handleOnChange("posPrompt", val), + onChange: (e:React.ChangeEvent)=>handleOnChange("posPrompt", e.target.value), value: filterState.posPrompt, required: false, }} />
- handleOnChange("negPrompt", val), + onChange: (e:React.ChangeEvent)=>handleOnChange("negPrompt", e.target.value), value: filterState.negPrompt, required: false, }} @@ -176,9 +238,7 @@ export default function PageFilterControls({
-
- { - console.log(`Use Control Nets: ${e.target.checked}`) - }} - /> -
{console.log(`Canny: ${val}`)} + onChange: (val)=>{handleOnChange("cnCanny", val)} }}/>
{console.log(`Line Art Anime: ${val}`)} + onChange: (val)=>{handleOnChange("cnLinearAnime", val)} }}/>
{console.log(`Depth: ${val}`)} + onChange: (val)=>{handleOnChange("cnDepth", val)} }}/>
{console.log(`OpenPose: ${val}`)} + onChange: (val)=>{handleOnChange("cnOpenPose", val)} }}/>
{console.log(`Media Pipe Face: ${val}`)} + onChange: (val)=>{handleOnChange("cnPipeFace", val)} }}/>
{console.log(`Sparse Scribble: ${val}`)} + onChange: (val)=>{handleOnChange("cnSparse", val)} }}/>
{console.log(`Video CN: ${val}`)} + onChange: (val)=>{handleOnChange("cnLinearRealistic", val)} }}/>
{console.log(`Tile CN: ${val}`)} + onChange: (val)=>{handleOnChange("cnTile", val)} }}/>
@@ -414,7 +437,7 @@ export default function PageFilterControls({
- +
@@ -426,12 +449,20 @@ export default function PageFilterControls({
+
+
+
+
); }else if (pageState.status <= states.FILE_LOADING){ return ( - {debug &&

{`File Token: ${pageState.mediaFileToken}`}

}

Loading Files

diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageJobList.tsx b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageJobList.tsx new file mode 100644 index 0000000000..b907495487 --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/components/pageJobList.tsx @@ -0,0 +1,49 @@ +import React from 'react' + +import { Analytics } from "common/Analytics"; +import InferenceJobsList from "components/layout/InferenceJobsList"; +import { FrontendInferenceJobType } from "@storyteller/components/src/jobs/InferenceJob"; +import { states, Action, State } from "../storytellerFilterReducer"; +import { Spinner } from 'components/common'; + +function StorytellerJobList(){ + 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.StorytellerFilter, + }}/> + ); +} + +export default function PageJobList({ + t, pageState, dispatchPageState +}: { + debug?: boolean; + t: Function; + pageState: State; + dispatchPageState: (action: Action) => void; +}) { + console.log(pageState); + return( + <> +

Jobs

+ {pageState.status === states.FILTER_ENQUEUEING && +
+

Requesting Filter Job

+ +
+ } + + + ); +} \ No newline at end of file diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterReducer.tsx b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterReducer.tsx index 87f44546a9..229eace4b2 100644 --- a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterReducer.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterReducer.tsx @@ -8,6 +8,8 @@ export enum states{ FILE_UPLOADED, FILE_LOADING, FILE_LOADED, + FILTER_ENQUEUEING, + FILTER_ENQUEUED } export type State = { @@ -27,6 +29,8 @@ export type Action = | {type: 'loadFileSuccess', payload:{ mediaFileToken: string, mediaFile: MediaFile }} + | {type: 'enqueueFilter'} + | {type: 'enqueueFilterSuccess', payload: {inferenceJobToken: string|undefined}} export function reducer (state: State, action: Action): State { @@ -60,6 +64,17 @@ export function reducer (state: State, action: Action): State { mediaFile: action.payload.mediaFile, mediaFileToken : action.payload.mediaFileToken, } + case 'enqueueFilter': + return { + ...state, + status: states.FILTER_ENQUEUEING + } + case 'enqueueFilterSuccess': + return { + ...state, + status: states.FILTER_ENQUEUED, + inferenceJobToken: action.payload.inferenceJobToken + } default: return {status: states.NO_FILE}; diff --git a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterRoutes.tsx b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterRoutes.tsx index ce67ca1a19..cc4f7c516b 100644 --- a/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterRoutes.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/storyteller_filter/storytellerFilterRoutes.tsx @@ -2,6 +2,7 @@ import React from "react"; import {Switch, Route, useRouteMatch, Redirect} from "react-router-dom"; import PageFilterControls from "./components/pageFilterControls"; import PageVideoProvision from "./components/pageVideoProvision"; +import PageJobList from "./components/pageJobList"; import {State,Action} from "./storytellerFilterReducer"; export default function SubRoutes ({ @@ -25,6 +26,9 @@ export default function SubRoutes ({ + + +