Merge pull request #499 from storytold/fixes/select_modal_overhaul

Fixes/select modal overhaul
This commit is contained in:
wil authored and GitHub committed 2024-02-20 17:53:13 -05:00
commit 60ed1ff03e
20 files changed
+679 -85

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
import {
MediaFileType,
GetMediaByUser
} from "./media_files";
import {
Weight,
ListWeights
} from "./weights";
import {
GetBookmarksByUser
} from "./bookmarks/GetBookmarksByUser";
export type{
MediaFileType,
Weight
}
export {
GetBookmarksByUser,
GetMediaByUser,
ListWeights
};
@@ -0,0 +1,10 @@
import { MediaFile } from "./GetMediaFile";
import { GetMediaByUser } from "./GetMediaByUser";
export type{
MediaFile as MediaFileType
}
export {
GetMediaByUser
}
@@ -0,0 +1,5 @@
import { ListWeights } from "./ListWeights";
import { Weight } from "./GetWeight";
export type { Weight };
export { ListWeights };
@@ -1 +1,10 @@
export { default } from "./Card";
import MediaCards from "./MediaCards";
import WeightsCards from "./WeightsCards";
import SkeletonCard from "./SkeletonCard";
import Card from "./Card";
export {
Card as default,
MediaCards,
SkeletonCard,
WeightsCards
};
@@ -13,9 +13,11 @@ interface PaginationComponentProps {
pageCount: number
}
export default function Pagination({ currentPage, onPageChange, pageCount }: PaginationComponentProps) {
// const pageCount = Math.ceil(totalItems / itemsPerPage);
export default function Pagination({
currentPage,
onPageChange,
pageCount
}: PaginationComponentProps) {
return (
<ReactPaginate
previousLabel={<FontAwesomeIcon icon={faChevronLeft} />}
@@ -0,0 +1,101 @@
import React, {
memo,
ReactNode,
useEffect,
useState,
} from "react";
import {
Button,
TempInput as Input,
Modal,
} from "components/common";
import { faTrash } from "@fortawesome/free-solid-svg-icons";
export type SelectModalData = {
token: string;
title: string;
}
interface SelectModalProps {
label?: string;
modalTitle?: string;
value?: string;
onClear: () => void;
required?: boolean;
children: ReactNode
}
export default memo(function SelectModal ({
label,
// tabs,
modalTitle = "Select",
onClear,
value = "",
required,
children
}: SelectModalProps) {
const [isModalOpen, setModalOpen] = useState(false
)
const openModal = () => {
setModalOpen(true);
};
const closeModal = () => {
setModalOpen(false);
};
useEffect(closeModal, [value]);
return (
<>
<div>
{label && (
<label className={`sub-title ${required && "required"}`.trim()}>
{label}
</label>
)}
<div className="d-flex gap-2 position-relative">
<div
className="position-absolute w-100 h-100"
style={{"cursor": "pointer"}}
onClick={openModal}
/>
<Input
disabled={true}
wrapperClassName="w-100"
placeholder="None selected"
onClick={openModal}
value={value}
/>
<Button label={value !== "" ? "Change" : "Select"} onClick={openModal} />
{value && (
<Button
square={true}
variant="danger"
icon={faTrash}
onClick={onClear}
tooltip="Remove"
/>
)}
</div>
</div>
<Modal
show={isModalOpen}
handleClose={closeModal}
title={modalTitle}
content={()=>{return(<>{children}</>)}}
showButtons={false}
padding={false}
large={true}
position="top"
mobileFullscreen={true}
/>
</>
);
}
);
@@ -1 +1,5 @@
export { default } from "./SelectModal";
import SelectModal from "./SelectModal";
import SelectModalV2, { SelectModalData } from "./SelectModalV2";
export type { SelectModalData };
export { SelectModal as default, SelectModalV2 };
@@ -0,0 +1,141 @@
import React, { memo, useRef, useState } from "react";
import { useListContent, useSession } from "hooks";
import {
MediaFileType,
GetMediaByUser
} from "@storyteller/components/src/api";
import {
MasonryGrid,
MediaCards,
Pagination,
SkeletonCard,
NonRouteTabs
} from "components/common";
import { SelectModalData, SelectModalV2} from "../SelectModal";
import prepFilter from "resources/prepFilter";
export default memo(function SelectModalWrapper({
debug = false,
value = "",
modalTitle,
inputLabel,
onSelect
}: {
debug?: boolean;
value?: string;
modalTitle: string;
inputLabel: string;
onSelect: (data:SelectModalData) => void;
}) {
const tabs = [{
label: "All Videos",
content: (
<div className="searcher-container in-modal m-4" id="allVideos">
<VideoTabsContent debug={debug} onSelect={onSelect}/>
</div>
)
}]
return (
<SelectModalV2
modalTitle={modalTitle}
label={inputLabel}
value={value}
onClear={()=>{onSelect({title:"",token:""})}}
>
<NonRouteTabs tabs={tabs} />
</SelectModalV2>
);
});
function VideoTabsContent({
debug=false,
onSelect
}:{
debug?: boolean
onSelect: (data:SelectModalData) => void;
}){
const gridContainerRef = useRef<HTMLDivElement | null>(null);
const [list, listSet] = useState<MediaFileType[]>([]);
const { user } = useSession();
const media = useListContent({
addQueries: {
page_size: 9,
...prepFilter("video", "filter_media_type"),
},
urlUpdate: false,
debug: debug ? "Video List" : undefined,
fetcher: GetMediaByUser,
list,
listSet,
requestList: true,
urlParam: user?.username || ""
});
const handlePageClick = (selectedItem: { selected: number }) => {
media.pageChange(selectedItem.selected);
};
const paginationProps = {
onPageChange: handlePageClick,
pageCount: media.pageCount+1, // account for index 0
currentPage: media.page,
};
if (media.isLoading){
return (
<div className="row gx-3 gy-3">
{Array.from({ length: 12 }).map((_, index) => (
<SkeletonCard key={index} />
))}
</div>
);
}else if (media.list.length === 0 && media.status === 3){
return(
<div className="text-center m-4 opacity-75">
No media created yet.
</div>
);
}else {
return(
<>
{paginationProps.pageCount > 1 &&
<div className="d-flex justify-content-end mb-4">
<Pagination {...paginationProps} />
</div>
}
<MasonryGrid
gridRef={gridContainerRef}
onLayoutComplete={() => {if (debug) console.log("Layout complete!")}}
>
{media.list.map((data: MediaFileType, key: number) => {
let props = {
data,
showCreator: true,
type: "media",
inSelectModal: true,
onResultSelect: onSelect,
};
return (
<div
{...{
className: "col-12 col-sm-6 col-xl-4 grid-item",
key,
}}
>
<MediaCards {...{ type: data.media_type, props }} />
</div>
);
})}
</MasonryGrid>
{paginationProps.pageCount > 1 &&
<div className="d-flex justify-content-end mt-4">
<Pagination {...paginationProps} />
</div>
}
</>
);
}
}
@@ -0,0 +1 @@
export { default } from "./SelectModalVideoTabs";
@@ -0,0 +1,51 @@
import React, { memo } from "react";
import { NonRouteTabs } from "components/common";
import { SelectModalData, SelectModalV2} from "../SelectModal";
import TabAllWeights from "./tabAllWeights";
import TabBookmarkedWeights from "./tabBookmarkedWeights"
export default memo(function SelectModalWrapper({
debug = false,
value = {title:"",token:""},
modalTitle,
inputLabel,
weightType,
onSelect
}: {
debug?: boolean;
value?: SelectModalData;
modalTitle: string;
inputLabel: string;
weightType: "sd_1.5" | "loRA";
onSelect: (data:SelectModalData) => void;
}) {
const tabs = [{
label: "All Weights",
content: (
<div className="searcher-container in-modal m-4" id="allWeights">
<TabAllWeights {...{debug, onSelect, weightType}}/>
</div>
)
},
{
label: "Bookmarked Weights",
content: (
<div className="searcher-container in-modal m-4" id="allWeights">
<TabBookmarkedWeights {...{debug, onSelect, weightType}}/>
</div>
)
}
]
return (
<SelectModalV2
modalTitle={modalTitle}
label={inputLabel}
value={value.title || value.token}
onClear={()=>{onSelect({title:"",token:""})}}
>
<NonRouteTabs tabs={tabs} />
</SelectModalV2>
);
});
@@ -0,0 +1 @@
export { default } from "./SelectModalWeightsTabs";
@@ -0,0 +1,124 @@
import React, {useRef, useState} from 'react';
import {
useBookmarks,
useLazyLists,
useRatings,
// useSession
} from "hooks";
import {
Weight as WeightI,
ListWeights
} from "@storyteller/components/src/api";
import { SelectModalData } from "../SelectModal";
import prepFilter from "resources/prepFilter";
import {
MasonryGrid,
WeightsCards,
Pagination,
SkeletonCard,
} from "components/common";
export default function WeightsTabsContent({
debug=false,
weightType,
onSelect
}:{
debug?: boolean
weightType: "sd_1.5" | "loRA";
onSelect: (data:SelectModalData) => void;
}){
const gridContainerRef = useRef<HTMLDivElement | null>(null);
const bookmarks = useBookmarks();
const ratings = useRatings();
const [list, listSet] = useState<WeightI[]>([]);
const [pages, setPages] = useState<{
currPageWeights: any[],
lookup: string[]
}>({
currPageWeights: [],
lookup: []
});
const weights = useLazyLists({
addQueries: {
page_size: 9,
...prepFilter(weightType, "weight_type"),
},
fetcher: ListWeights,
onSuccess: (res)=>{
setPages((curr)=>{
return{
currPageWeights: [...res.results],
lookup: [...curr.lookup, res.pagination.maybe_next]
}
})
},
list,
listSet,
requestList: true,
urlUpdate: false,
});
const handlePageClick = (selectedItem: { selected: number }) => {
weights.getMore();
};
const paginationProps = {
onPageChange: handlePageClick,
pageCount: pages.lookup.length+1,
currentPage: 0,
};
if (weights.isLoading){
return (
<div className="row gx-3 gy-3">
{Array.from({ length: 12 }).map((_, index) => (
<SkeletonCard key={index} />
))}
</div>
);
}else if (weights.list.length === 0 && weights.status === 3){
return(
<div className="text-center m-4 opacity-75">
No weights created yet.
</div>
);
}else {
return(
<>
<div className="d-flex justify-content-end mb-4">
<Pagination {...paginationProps} />
</div>
<MasonryGrid
gridRef={gridContainerRef}
// onLayoutComplete={() => console.log("Layout complete!")}
>
{pages.currPageWeights.map((data: any, key: number) => {
let props = {
data,
ratings,
bookmarks,
showCreator: true,
type: "weights",
inSelectModal: true,
onResultSelect: onSelect,
};
return (
<div
{...{
className: "col-12 col-sm-6 col-xl-4 grid-item",
key,
}}
>
<WeightsCards {...{ type: data.weight_category, props }} />
</div>
);
})}
</MasonryGrid>
<div className="d-flex justify-content-end mt-4">
<Pagination {...paginationProps} />
</div>
</>
);
}
}
@@ -0,0 +1,116 @@
import React, {useRef, useState} from 'react';
import {
// useBookmarks,
useListContent,
useRatings,
useSession
} from "hooks";
import {
Weight as WeightI,
GetBookmarksByUser
} from "@storyteller/components/src/api";
import { SelectModalData } from "../SelectModal";
import prepFilter from "resources/prepFilter";
import {
MasonryGrid,
WeightsCards,
Pagination,
SkeletonCard,
} from "components/common";
export default function WeightsTabsContent({
debug=false,
weightType,
onSelect
}:{
debug?: boolean;
weightType: "sd_1.5" | "loRA";
onSelect: (data:SelectModalData) => void;
}){
const gridContainerRef = useRef<HTMLDivElement | null>(null);
// const bookmarks = useBookmarks();
const ratings = useRatings();
const [list, listSet] = useState<WeightI[]>([]);
const { user } = useSession();
const weights = useListContent({
addQueries: {
page_size: 9,
...prepFilter(weightType, "weight_type"),
},
urlUpdate: false,
debug: debug ? "Bookmarked Weights" : undefined,
fetcher: GetBookmarksByUser,
list,
listSet,
requestList: true,
urlParam: user?.username || ""
});
const handlePageClick = (selectedItem: { selected: number }) => {
weights.pageChange(selectedItem.selected);
};
console.log("BOOKMARKED");
console.log(weights);
const paginationProps = {
onPageChange: handlePageClick,
pageCount: weights.pageCount + 1,
currentPage: weights.page,
};
if (weights.isLoading){
return (
<div className="row gx-3 gy-3">
{Array.from({ length: 12 }).map((_, index) => (
<SkeletonCard key={index} />
))}
</div>
);
}else if (weights.list.length === 0 && weights.status === 3){
return(
<div className="text-center m-4 opacity-75">
No weights created yet.
</div>
);
}else {
return(
<>
{paginationProps.pageCount > 1 &&
<div className="d-flex justify-content-end mb-4">
<Pagination {...paginationProps} />
</div>
}
<MasonryGrid
gridRef={gridContainerRef}
onLayoutComplete={() => console.log("Layout complete!")}
>
{weights.list.map((data: any, key: number) => {
//TODO: data should be TYPED
let props = {
data,
ratings,
// bookmarks,
showCreator: true,
type: "weights",
inSelectModal: true,
onResultSelect: onSelect,
};
return (
<div
{...{
className: "col-12 col-sm-6 col-xl-4 grid-item",
key,
}}
>
<WeightsCards {...{
type: data.details.maybe_weight_data.weight_category, props }} />
</div>
);
})}
</MasonryGrid>
{paginationProps.pageCount > 1 &&
<div className="d-flex justify-content-end mt-4">
<Pagination {...paginationProps} />
</div>
}
</>
);
}
}
@@ -1 +1,3 @@
export { default } from "./Tabs";
import Tabs from "./Tabs";
import NonRouteTabs from "./NonRouteTabs";
export { Tabs as default, NonRouteTabs };
@@ -5,6 +5,11 @@ import Badge from "./Badge";
import Button from "./Button";
import ButtonRevertToDefault from "./ButtonRevertToDefault";
import Checkbox from "./Checkbox";
import {
MediaCards,
SkeletonCard,
WeightsCards,
} from "./Card";
import Container from "./Container";
import CoverImageInput from "./CoverImageInput";
import ErrorMessage from "./ErrorMessage"
@@ -18,12 +23,14 @@ import InputSeed from "./InputSeed";
import Label from "./Label";
import LikeButton from "./LikeButton";
import MocapInput from "./MocapInput";
import MasonryGrid from "./MasonryGrid/MasonryGrid";
import Modal from "./Modal";
import NumberSlider from "./NumberSlider";
import NumberSliderV2 from "./NumberSliderV2";
import Pagination from "./Pagination";
import Panel from "./Panel";
import Radio from "./Radio";
import Searcher from "./Searcher";
import SegmentButtons from "./SegmentButtons";
import Select from "./Select";
import SelectModal from "./SelectModal";
@@ -31,7 +38,7 @@ import Skeleton from "./Skeleton";
import Slider from "./Slider";
import Spinner from "./Spinner";
import SplitPanel from "./SplitPanel";
import Tabs from "./Tabs";
import Tabs, {NonRouteTabs} from "./Tabs";
import TempAudioPlayer from "./TempAudioPlayer";
import TempInput from "./TempInput";
import TempSelect from "./TempSelect";
@@ -49,6 +56,11 @@ export {
AudioInput,
Badge,
Button,
//Cards
MediaCards,
SkeletonCard,
WeightsCards,
//End Cards
ButtonRevertToDefault,
Checkbox,
Container,
@@ -64,13 +76,16 @@ export {
Label,
LikeButton,
MocapInput,
MasonryGrid,
Modal,
NonRouteTabs,
NumberSlider,
NumberSliderV2,
Pagination,
Panel,
Radio,
SegmentButtons,
Searcher,
Select,
SelectModal,
Skeleton,
@@ -16,6 +16,8 @@ import {
TextArea
} from "components/common";
import SelectModalWeightsTabs from "components/common/SelectModalWeightsTabs";
import SectionControlNets, {ControlNetsInitialValues as CnIvs} from "./sectionControlNets";
import SectionVideoSettings, {VideoSettingsInitialValues as VideoIvs} from "./sectionVideoSettings";
import SectionAdvanceOptions, {AdvanceOptionsInitialValues as AdvIvs} from "./sectionAdvanceOptions";
@@ -63,8 +65,8 @@ export default function PageFilterControls({
...CnIvs
});
const handleOnChange = (key: string, newValue:any,) => {
setWorkflowValues((curr)=>({...curr, [key]: newValue}));
const handleOnChange = (val:{[key: string]: number|string|boolean|undefined}) => {
setWorkflowValues((curr)=>({...curr, ...val}));
}
const handleReset = ()=>{
setWorkflowValues((curr)=>({
@@ -132,7 +134,7 @@ export default function PageFilterControls({
<div className="col-6">
<SectionVideoSettings
workflowValues={workflowValues}
onChange={(key,val)=>handleOnChange(key,val)}
onChange={handleOnChange}
videoElement={videoRef?.current}
/>
<div className="d-flex my-3 justify-content-end">
@@ -164,37 +166,32 @@ export default function PageFilterControls({
<Accordion className="mt-4">
<Accordion.Item title={"Basics"} defaultOpen>
<div className="row g-3 p-3">
<SelectModal
<SelectModalWeightsTabs
modalTitle="Select a Stable Diffusion Weight"
label="Select a Stable Diffusion Weight"
onSelect={({token})=>{
handleOnChange("sdModelToken", token);
inputLabel="Select a Stable Diffusion Weight"
weightType="sd_1.5"
onSelect={({title,token})=>{
handleOnChange({
"sdModelTitle": title,
"sdModelToken": token,
});
}}
value={{
token:workflowValues.sdModelToken,
title:""
}}
tabs={[
{
label: "All Weights",
tabKey: "allWeights",
typeFilter: "sd_1.5",
searcher: true,
type: "weights",
},
{
label: "Bookmarked",
tabKey: "bookmarkedWeights",
typeFilter: "sd_1.5",
searcher: false,
type: "weights",
},
]}
/>
</div>
<div className="row g-3 p-3">
<SelectModal
modalTitle="Select a LoRA Weight"
label="Additional LoRA Weight"
onSelect={({token})=>{
onSelect={({title,token})=>{
console.log(`calling from select modal result select ${token}`);
handleOnChange("loraModelToken", token);
handleOnChange({
"loraModelTitle": title,
"loraModelToken": token
});
}}
tabs={[
{
@@ -220,7 +217,7 @@ export default function PageFilterControls({
{...{
label: "Prompt",
placeholder: "Enter a prompt",
onChange: (e:React.ChangeEvent<HTMLTextAreaElement>)=>handleOnChange("posPrompt", e.target.value),
onChange: (e:React.ChangeEvent<HTMLTextAreaElement>)=>handleOnChange({"posPrompt": e.target.value}),
value: workflowValues.posPrompt,
required: false,
}}
@@ -231,7 +228,7 @@ export default function PageFilterControls({
{...{
label: "Negative Prompt",
placeholder: "Enter Negative Prompt",
onChange: (e:React.ChangeEvent<HTMLTextAreaElement>)=>handleOnChange("negPrompt", e.target.value),
onChange: (e:React.ChangeEvent<HTMLTextAreaElement>)=>handleOnChange({"negPrompt": e.target.value}),
value: workflowValues.negPrompt,
required: false,
}}
@@ -240,7 +237,7 @@ export default function PageFilterControls({
</div>
<div className="row g-3 p-3">
<InputSeed label="Seed" onChange={
(val:string)=>handleOnChange("seed", val)
(val:string)=>handleOnChange({seed: val})
}/>
</div>
@@ -248,13 +245,13 @@ export default function PageFilterControls({
<Accordion.Item title="Advance" defaultOpen>
<SectionAdvanceOptions
workflowValues={workflowValues}
onChange={(key,val)=>handleOnChange(key,val)}
onChange={handleOnChange}
/>
</Accordion.Item>
<Accordion.Item title="Control Nets" defaultOpen>
<SectionControlNets
workflowValues={workflowValues}
onChange={(key,val)=>handleOnChange(key,val)}
onChange={handleOnChange}
/>
</Accordion.Item>
</Accordion>
@@ -23,7 +23,7 @@ export default memo( function SectionAdvanceOptions({
onChange : handleOnChange
} : {
workflowValues : WorkflowValuesType
onChange: (key:string, val:number|boolean)=>void}
onChange: (val:{[key: string]: number|string|boolean})=>void}
){
return(
@@ -35,7 +35,7 @@ export default memo( function SectionAdvanceOptions({
initialValue: wfVal.firstPass,
label: " Denoise First Pass",
thumbTip: "Denoise First Pass",
onChange: (val)=>{handleOnChange("firstPass",val)}
onChange: (val)=>{handleOnChange({firstPass:val})}
}}/>
</div>
<div className="col-md-6">
@@ -44,7 +44,7 @@ export default memo( function SectionAdvanceOptions({
initialValue: wfVal.upscalePass,
label: "Denoise Upscale Pass",
thumbTip: "Denoise Upscale Pass",
onChange: (val)=>{handleOnChange("upscalePass", val)}
onChange: (val)=>{handleOnChange({upscalePass: val})}
}}/>
</div>
</div>
@@ -55,7 +55,7 @@ export default memo( function SectionAdvanceOptions({
initialValue: wfVal.motionScale,
label: "Motion Scale",
thumbTip: "Motion Scale",
onChange: (val)=>{handleOnChange("motionScale", val)}
onChange: (val)=>{handleOnChange({motionScale: val})}
}}/>
</div>
<div className="col-md-6">
@@ -64,7 +64,7 @@ export default memo( function SectionAdvanceOptions({
initialValue: wfVal.upscaleMultiplier,
label: "Upscale Multiplier",
thumbTip: "Upscale Multiplier",
onChange: (val)=>{handleOnChange("upscaleMultiplier", val)}
onChange: (val)=>{handleOnChange({upscaleMultiplier: val})}
}}/>
</div>
</div>
@@ -73,14 +73,14 @@ export default memo( function SectionAdvanceOptions({
<Checkbox
label="Use Empty Latent"
checked={wfVal.useEmptyLatent}
onChange={(e:{target:{ checked: boolean, name:string, type: string }})=>{handleOnChange("useEmptyLatent", e.target.checked)}}
onChange={(e:{target:{ checked: boolean, name:string, type: string }})=>{handleOnChange({useEmptyLatent: e.target.checked})}}
/>
</div>
<div className="col-md-6">
<Checkbox
label="Use Face Detailer"
checked={wfVal.useFaceDetailer}
onChange={(e:{target:{ checked: boolean, name:string, type: string }})=>{handleOnChange("useFaceDetailer", e.target.checked)}}
onChange={(e:{target:{ checked: boolean, name:string, type: string }})=>{handleOnChange({useFaceDetailer: e.target.checked})}}
/>
</div>
</div>
@@ -94,7 +94,7 @@ export default memo( function SectionAdvanceOptions({
initialValue: wfVal.denoiseFaceDetailer,
label: "Denoise Face Detailer",
thumbTip: "Denoise Face Detailer",
onChange: (val)=>{handleOnChange("denoiseFaceDetailer", val)}
onChange: (val)=>{handleOnChange({denoiseFaceDetailer: val})}
}}/>
</div>
</div>
@@ -102,7 +102,7 @@ export default memo( function SectionAdvanceOptions({
<Checkbox
label="Use LCM"
checked={wfVal.useLCM}
onChange={(e:{target:{ checked: boolean, name:string, type: string }})=>{handleOnChange("useLCM", e.target.checked)}}
onChange={(e:{target:{ checked: boolean, name:string, type: string }})=>{handleOnChange({useLCM: e.target.checked})}}
/>
</div>
<div className="row g-3 p-3">
@@ -113,7 +113,7 @@ export default memo( function SectionAdvanceOptions({
withRevert: true,
label: "LCM CFG",
thumbTip: "LCM CFG",
onChange: (val)=>{handleOnChange("lcmCFG", val)}
onChange: (val)=>{handleOnChange({lcmCFG: val})}
}}/>
</div>
<div className="col-md-6">
@@ -122,7 +122,7 @@ export default memo( function SectionAdvanceOptions({
initialValue: wfVal.lcmSteps,
label: "LCM Steps",
thumbTip: "LCM Steps",
onChange: (val)=>{handleOnChange("lcmSteps", val)}
onChange: (val)=>{handleOnChange({lcmSteps: val})}
}}/>
</div>
</div>
@@ -18,7 +18,7 @@ export default memo( function SectionControlNets({
onChange : handleOnChange
} : {
workflowValues : WorkflowValuesType
onChange: (key:string, val:number)=>void}
onChange: (val:{[key: string]: number|string|boolean})=>void}
){
return(
@@ -30,7 +30,7 @@ export default memo( function SectionControlNets({
initialValue: wfVal.cnCanny,
label: "Canny",
thumbTip: "Canny",
onChange: (val)=>{handleOnChange("cnCanny", val)}
onChange: (val)=>{handleOnChange({cnCanny: val})}
}}/>
</div>
<div className="col-md-6">
@@ -39,7 +39,7 @@ export default memo( function SectionControlNets({
initialValue: wfVal.cnLinearAnime,
label: "Line Art Anime",
thumbTip: "Line Art Anime",
onChange: (val)=>{handleOnChange("cnLinearAnime", val)}
onChange: (val)=>{handleOnChange({cnLinearAnime: val})}
}}/>
</div>
</div>
@@ -50,7 +50,7 @@ export default memo( function SectionControlNets({
initialValue: wfVal.cnDepth,
label: "Depth",
thumbTip: "Depth",
onChange: (val)=>{handleOnChange("cnDepth", val)}
onChange: (val)=>{handleOnChange({cnDepth: val})}
}}/>
</div>
<div className="col-md-6">
@@ -59,7 +59,7 @@ export default memo( function SectionControlNets({
initialValue: wfVal.cnOpenPose,
label: "OpenPose",
thumbTip: "OpenPose",
onChange: (val)=>{handleOnChange("cnOpenPose", val)}
onChange: (val)=>{handleOnChange({cnOpenPose: val})}
}}/>
</div>
</div>
@@ -70,7 +70,7 @@ export default memo( function SectionControlNets({
initialValue: wfVal.cnPipeFace,
label: "Media Pipe Face",
thumbTip: "Media Pipe Face",
onChange: (val)=>{handleOnChange("cnPipeFace", val)}
onChange: (val)=>{handleOnChange({cnPipeFace: val})}
}}/>
</div>
<div className="col-md-6">
@@ -79,7 +79,7 @@ export default memo( function SectionControlNets({
initialValue: wfVal.cnSparse,
label: "Sparse Scribble",
thumbTip: "Sparse Scribble",
onChange: (val)=>{handleOnChange("cnSparse", val)}
onChange: (val)=>{handleOnChange({cnSparse: val})}
}}/>
</div>
</div>
@@ -90,7 +90,7 @@ export default memo( function SectionControlNets({
initialValue: wfVal.cnLinearRealistic,
label: "Video CN (Linear Realistic)",
thumbTip: "Video CN",
onChange: (val)=>{handleOnChange("cnLinearRealistic", val)}
onChange: (val)=>{handleOnChange({cnLinearRealistic: val})}
}}/>
</div>
<div className="col-md-6">
@@ -99,7 +99,7 @@ export default memo( function SectionControlNets({
initialValue: wfVal.cnTile,
label: "Tile CN",
thumbTip: "Tile CN",
onChange: (val)=>{handleOnChange("cnTile", val)}
onChange: (val)=>{handleOnChange({cnTile: val})}
}}/>
</div>
</div>
@@ -18,7 +18,7 @@ export default memo( function SectionVideoSettings({
workflowValues: wfVal,
videoElement: ve
} : {
onChange: (key:string, val:number)=>void,
onChange: (val:{[key: string]: number|string|boolean|undefined})=>void,
workflowValues: WorkflowValuesType,
videoElement: HTMLVideoElement | null,
}){
@@ -26,33 +26,32 @@ export default memo( function SectionVideoSettings({
const handleFramesCap = (newValue: number)=>{
if(newValue - wfVal.skipFrames >= 16)
handleOnChange("framesCap",newValue);
handleOnChange({framesCap:newValue});
}
const handleSkipFrames = (newValue: number)=>{
if(wfVal.framesCap - newValue >= 16)
handleOnChange("skipFrames",newValue);
handleOnChange({skipFrames:newValue});
}
if(ve && ve!==null){
ve.onloadedmetadata = () =>{
const newValues : {
width?: number;
height?: number;
maxFrames?: number;
framesCap?: number;
} = {};
if (ve.videoWidth && ve.videoHeight) {
const aspectRatio = ve.videoWidth/ve.videoHeight
if (aspectRatio > 1){
handleOnChange("width",960);
}
else if (aspectRatio < 1) {
handleOnChange("height",960);
}else{
console.log(`aspectRaio: ${aspectRatio}`);
}
if (aspectRatio > 1) newValues.width = 960;
else if (aspectRatio < 1) newValues.height = 960
else console.log(`aspectRaio: ${aspectRatio}`);
}
if(ve.duration){
handleOnChange("maxFrames",
Math.floor(ve.duration)*wfVal.inputFps
);
newValues.maxFrames = Math.floor(ve.duration)*wfVal.inputFps;
newValues.framesCap = newValues.maxFrames;
}
//TODO: Optimizer to make ONE handleOnChange only
//TODO: deal with maxFrames with more reliable math
handleOnChange(newValues);
}
}
return(
@@ -2,7 +2,8 @@ import React from "react";
import { NavLink } from "react-router-dom";
import { states, Action, State } from "../videoWorkflowReducer";
import { Button } from "components/common";
import SelectModal, { SelectModalData } from "components/common/SelectModal/SelectModal";
import SelectModalVideoTabs from "components/common/SelectModalVideoTabs";
import { SelectModalData } from "components/common/SelectModal/SelectModalV2";
import VideoFakeyou from "components/common/VideoFakeyou";
export default function TabContentLibrary({
@@ -29,19 +30,11 @@ export default function TabContentLibrary({
return (
<div className="row g-3">
<div className="col-12">
<SelectModal
<SelectModalVideoTabs
value={pageState.mediaFileToken}
modalTitle="Select a Video"
label="Select a Video"
inputLabel="Select a Video"
onSelect={handleOnSelect}
tabs={[
{
label: "All Videos",
tabKey: "allVideos",
typeFilter: "video",
searcher: false,
type: "media",
},
]}
/>
{pageState.mediaFileToken &&
<VideoFakeyou mediaToken={pageState.mediaFileToken} />