diff --git a/ui/src/gallery/components/AllPromptForm/AllPromptForm.tsx b/ui/src/gallery/components/AllPromptForm/AllPromptForm.tsx index c5dcce4..8ecbb8f 100644 --- a/ui/src/gallery/components/AllPromptForm/AllPromptForm.tsx +++ b/ui/src/gallery/components/AllPromptForm/AllPromptForm.tsx @@ -10,13 +10,18 @@ import { import { FormItemComponent } from "../FormItem/FormItemComponent.tsx"; import { MetaData } from "../../utils.ts"; import { FormItem } from "../FormItem/types.ts"; +import { isInTopField, TopFieldType } from "../MetaBox/MetaBox.tsx"; export default function AllPromptForm({ metaData, updateMetaData, + topFields, + updateTopField, }: { metaData: MetaData; + topFields: TopFieldType[]; updateMetaData: FormItem["updateMetaData"]; + updateTopField?: (field: TopFieldType) => void; }) { const prompt = metaData.prompt; return ( @@ -25,7 +30,12 @@ export default function AllPromptForm({ const promptElement = prompt[promptKey]; const promptInputs = promptElement.inputs; const inputsKeyList = Object.keys(promptInputs).filter( - (v) => !Array.isArray(promptInputs[v]), + (v) => + !Array.isArray(promptInputs[v]) && + !isInTopField(topFields, { + name: v, + promptKey: promptKey, + }), ); if (inputsKeyList.length === 0) return null; return ( @@ -45,6 +55,14 @@ export default function AllPromptForm({ {inputsKeyList?.map((inputsKey) => { const value = promptInputs[inputsKey]; + if ( + isInTopField(topFields, { + name: inputsKey, + promptKey, + }) + ) { + return null; + } return ( ); diff --git a/ui/src/gallery/components/FormItem/FormItemComponent.tsx b/ui/src/gallery/components/FormItem/FormItemComponent.tsx index f0b51a8..66c9e7c 100644 --- a/ui/src/gallery/components/FormItem/FormItemComponent.tsx +++ b/ui/src/gallery/components/FormItem/FormItemComponent.tsx @@ -7,6 +7,9 @@ import { FormItem, FormItemType } from "./types.ts"; import { getNodesInfo } from "../../utils.ts"; import { NoSupport } from "./NoSupport.tsx"; import { CheckboxBase } from "./CheckboxBase.tsx"; +import { Flex, Grid, IconButton } from "@chakra-ui/react"; +import { IconPin, IconPinFilled } from "@tabler/icons-react"; +import { isInTopField } from "../MetaBox/MetaBox.tsx"; const INPUT_TYPE_COMPONENT_MAPPING = { [FormItemType.Input]: InputBase, @@ -69,5 +72,32 @@ function getInputConfigByInfo(props: FormItem): Partial { export const FormItemComponent: FC = (props) => { const configByNodeInfo = getInputConfigByInfo(props); const Com = INPUT_TYPE_COMPONENT_MAPPING[configByNodeInfo.type ?? "Input"]; - return ; + return ( + + + + props?.updateTopField?.({ + name: props.name, + promptKey: props.promptKey, + class_type: props.classType, + }) + } + variant={"text"} + icon={ + isInTopField(props.topFields, { + name: props.name, + promptKey: props.promptKey, + }) ? ( + + ) : ( + + ) + } + aria-label={"pin"} + /> + + + + ); }; diff --git a/ui/src/gallery/components/FormItem/types.ts b/ui/src/gallery/components/FormItem/types.ts index e35ae83..c35bbbe 100644 --- a/ui/src/gallery/components/FormItem/types.ts +++ b/ui/src/gallery/components/FormItem/types.ts @@ -1,3 +1,5 @@ +import { TopFieldType } from "../MetaBox/MetaBox.tsx"; + export enum FormItemType { Input = "Input", InputSlider = "InputSlider", @@ -14,7 +16,9 @@ export type FormItem = { value: string | number; onChange?: (val: any) => void; classType: string; - promptKey: string; + promptKey: string | number; + topFields: TopFieldType[]; + updateTopField?: (field: TopFieldType) => void; updateMetaData?: (data: { promptKey: string; name: string; diff --git a/ui/src/gallery/components/MetaBox/MetaBox.tsx b/ui/src/gallery/components/MetaBox/MetaBox.tsx index 83bf92c..766acda 100644 --- a/ui/src/gallery/components/MetaBox/MetaBox.tsx +++ b/ui/src/gallery/components/MetaBox/MetaBox.tsx @@ -4,12 +4,14 @@ import { Media } from "../../../types/dbTypes.ts"; import TopForm from "../TopForm/TopForm.tsx"; import AllPromptForm from "../AllPromptForm/AllPromptForm.tsx"; import { useState } from "react"; +import { FormItem } from "../FormItem/types.ts"; -export const DEFAULT_TOP_FIELDS: { +export type TopFieldType = { promptKey: string | number; class_type?: string; name: string; -}[] = [ +}; +export const DEFAULT_TOP_FIELDS: TopFieldType[] = [ { promptKey: "4", name: "ckpt_name", @@ -43,6 +45,14 @@ export const DEFAULT_TOP_FIELDS: { name: "cfg", }, ]; +export const isInTopField = ( + topFields: TopFieldType[], + item: Pick, +) => { + return topFields?.some( + (top) => top.promptKey === item?.promptKey && top.name === item?.name, + ); +}; export default function MetaBox({ metaData: oriMetaData, @@ -50,6 +60,7 @@ export default function MetaBox({ metaData: MetaData; media: Media; }) { + const [topFields, setTopFields] = useState(DEFAULT_TOP_FIELDS); const [metaData, setMetaData] = useState( JSON.parse(JSON.stringify(oriMetaData)), ); @@ -77,10 +88,37 @@ export default function MetaBox({ })); }; + const updateTopField = (field: TopFieldType) => { + if ( + isInTopField(topFields, { + name: field.name, + promptKey: field?.promptKey, + }) + ) { + setTopFields((pre) => + pre.filter( + (v) => v.name !== field.name || v.promptKey !== field.promptKey, + ), + ); + } else { + setTopFields((pre) => [...pre, field]); + } + }; + return ( - - + + ); } diff --git a/ui/src/gallery/components/TopForm/TopForm.tsx b/ui/src/gallery/components/TopForm/TopForm.tsx index 83690be..0d20eb1 100644 --- a/ui/src/gallery/components/TopForm/TopForm.tsx +++ b/ui/src/gallery/components/TopForm/TopForm.tsx @@ -1,5 +1,5 @@ import { MetaData } from "../../utils.ts"; -import { DEFAULT_TOP_FIELDS } from "../MetaBox/MetaBox.tsx"; +import { TopFieldType } from "../MetaBox/MetaBox.tsx"; import { Flex } from "@chakra-ui/react"; import { FormItemComponent } from "../FormItem/FormItemComponent.tsx"; import { FormItem } from "../FormItem/types.ts"; @@ -7,16 +7,20 @@ import { FormItem } from "../FormItem/types.ts"; export default function TopForm({ metaData, updateMetaData, + topFields, + updateTopField, }: { metaData: MetaData; + topFields: TopFieldType[]; updateMetaData: FormItem["updateMetaData"]; + updateTopField?: (field: TopFieldType) => void; }) { const prompt = metaData.prompt; return ( <> - {DEFAULT_TOP_FIELDS?.length > 0 && ( + {topFields?.length > 0 && ( - {DEFAULT_TOP_FIELDS?.map((field) => { + {topFields?.map((field) => { if (!prompt?.[field.promptKey]?.inputs) return null; const promptValue = prompt?.[field.promptKey]?.inputs?.[field.name]; return ( @@ -27,6 +31,8 @@ export default function TopForm({ name={field.name} value={promptValue} updateMetaData={updateMetaData} + updateTopField={updateTopField} + topFields={topFields} /> ); })}