From e5844c926bf2e7986c8e3d0d3802c9639d971bda Mon Sep 17 00:00:00 2001 From: caranicas Date: Tue, 27 Sep 2022 13:37:28 -0400 Subject: [PATCH] tags working --- .../components/atoms/modifierTag/index.tsx | 41 +++++++- .../atoms/modifierTag/modifierTags.css.ts | 43 +++++++++ .../basicCreation/activeTags/index.tsx | 8 +- .../organisms/creationPanel/creationPanel.css | 4 +- .../creationPanel/imageModifiers/index.tsx | 29 +++--- .../build_src/src/stores/imageCreateStore.ts | 95 +++++++++++++++---- 6 files changed, 182 insertions(+), 38 deletions(-) create mode 100644 ui/frontend/build_src/src/components/atoms/modifierTag/modifierTags.css.ts diff --git a/ui/frontend/build_src/src/components/atoms/modifierTag/index.tsx b/ui/frontend/build_src/src/components/atoms/modifierTag/index.tsx index 62e9f638..c076bc59 100644 --- a/ui/frontend/build_src/src/components/atoms/modifierTag/index.tsx +++ b/ui/frontend/build_src/src/components/atoms/modifierTag/index.tsx @@ -1,23 +1,54 @@ import React from "react"; -import { useImageCreate } from "../../../stores/imageCreateStore"; +import { + ModifierPreview, + useImageCreate +} from "../../../stores/imageCreateStore"; + +import { API_URL } from "../../../api"; + +import { + ModifierTagMain, + tagPreview + // @ts-expect-error +} from "./modifierTags.css.ts"; interface ModifierTagProps { name: string; + category: string; + previews: ModifierPreview[]; } -export default function ModifierTag({ name }: ModifierTagProps) { - const hasTag = useImageCreate((state) => state.hasTag(name)) +export default function ModifierTag({ name, category, previews }: ModifierTagProps) { + + const previewType: 'portrait' | 'landscape' = "portrait"; + + const hasTag = useImageCreate((state) => state.hasTag(category, name)) ? "selected" : ""; const toggleTag = useImageCreate((state) => state.toggleTag); const _toggleTag = () => { - toggleTag(name); + toggleTag(category, name); }; return ( -
+

{name}

+
+ {previews.map((preview) => { + if (preview.name !== previewType) { + return null; + } + return ( + {preview.name} + ); + })} +
); } diff --git a/ui/frontend/build_src/src/components/atoms/modifierTag/modifierTags.css.ts b/ui/frontend/build_src/src/components/atoms/modifierTag/modifierTags.css.ts new file mode 100644 index 00000000..e446dc38 --- /dev/null +++ b/ui/frontend/build_src/src/components/atoms/modifierTag/modifierTags.css.ts @@ -0,0 +1,43 @@ +import { style, globalStyle } from "@vanilla-extract/css"; + +// .modifierTag.selected { +// background-color: rgb(131, 11, 121); +// } + + +export const ModifierTagMain = style({ + display: "inline-block", + padding: "6px", + backgroundColor: "rgb(38, 77, 141)", + color: "#fff", + borderRadius: "5px", + margin: "5px", +}); + +// export const ModifierTagSelected = style({ +// backgroundColor: "rgb(131, 11, 121)", +// }); + +globalStyle(`${ModifierTagMain}.selected`, { + backgroundColor: "rgb(131, 11, 121)", +}) + +globalStyle(`${ModifierTagMain} p`, { + margin: 0, + textAlign: "center", + marginBottom: "2px", +}); + + +export const tagPreview = style({ + display: 'flex', + justifyContent: 'center', +}); + +globalStyle(`${tagPreview} img`, { + width: "90px", + height: "100%", + objectFit: "cover", + objectPosition: "center", +}); + diff --git a/ui/frontend/build_src/src/components/organisms/creationPanel/basicCreation/activeTags/index.tsx b/ui/frontend/build_src/src/components/organisms/creationPanel/basicCreation/activeTags/index.tsx index 61b3af7e..6b5689ec 100644 --- a/ui/frontend/build_src/src/components/organisms/creationPanel/basicCreation/activeTags/index.tsx +++ b/ui/frontend/build_src/src/components/organisms/creationPanel/basicCreation/activeTags/index.tsx @@ -5,13 +5,17 @@ import ModifierTag from "../../../../atoms/modifierTag"; export default function ActiveTags() { const selectedtags = useImageCreate((state) => state.selectedTags()); + + console.log("ActiveTags", selectedtags); + return (

Active Tags

    {selectedtags.map((tag) => ( -
  • - +
  • + {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} +
  • ))}
diff --git a/ui/frontend/build_src/src/components/organisms/creationPanel/creationPanel.css b/ui/frontend/build_src/src/components/organisms/creationPanel/creationPanel.css index 6a56d5ba..f22af7af 100644 --- a/ui/frontend/build_src/src/components/organisms/creationPanel/creationPanel.css +++ b/ui/frontend/build_src/src/components/organisms/creationPanel/creationPanel.css @@ -33,7 +33,7 @@ li { padding: 0; } -.modifierTag { +/* .modifierTag { display: inline-block; padding: 6px; background-color: rgb(38, 77, 141); @@ -48,7 +48,7 @@ li { .modifierTag p { margin: 0; -} +} */ input[type="file"] { /* Dont show the file name */ diff --git a/ui/frontend/build_src/src/components/organisms/creationPanel/imageModifiers/index.tsx b/ui/frontend/build_src/src/components/organisms/creationPanel/imageModifiers/index.tsx index 7bba5fce..437eef99 100644 --- a/ui/frontend/build_src/src/components/organisms/creationPanel/imageModifiers/index.tsx +++ b/ui/frontend/build_src/src/components/organisms/creationPanel/imageModifiers/index.tsx @@ -10,21 +10,22 @@ import { ModifierListStyle, //@ts-expect-error } from "./imageModifiers.css.ts"; -import { useImageCreate } from "../../../../stores/imageCreateStore"; +import { ModifierObject, useImageCreate } from "../../../../stores/imageCreateStore"; import { useCreateUI } from "../creationPanelUIStore"; import ModifierTag from "../../../atoms/modifierTag"; interface ModifierListProps { - tags: string[]; + category: string; + tags: ModifierObject[]; } -function ModifierList({ tags }: ModifierListProps) { +function ModifierList({ tags, category }: ModifierListProps) { return (
    {tags.map((tag) => ( -
  • - +
  • +
  • ))}
@@ -33,10 +34,11 @@ function ModifierList({ tags }: ModifierListProps) { interface ModifierGroupingProps { title: string; - tags: string[]; + category: string; + tags: ModifierObject[]; } -function ModifierGrouping({ title, tags }: ModifierGroupingProps) { +function ModifierGrouping({ title, category, tags }: ModifierGroupingProps) { // doing this localy for now, but could move to a store // and persist if we wanted to const [isExpanded, setIsExpanded] = useState(false); @@ -45,12 +47,14 @@ function ModifierGrouping({ title, tags }: ModifierGroupingProps) { setIsExpanded(!isExpanded); }; + // console.log("ModifierGrouping", tags); + return (
- {isExpanded && } + {isExpanded && }
); } @@ -81,11 +85,12 @@ export default function ImageModifers() { {imageModifierIsOpen && (
    {allModifiers.map((item, index) => { + + // console.log('mod item ', item); + return ( - // @ts-expect-error -
  • - {/* @ts-expect-error */} - +
  • +
  • ); })} diff --git a/ui/frontend/build_src/src/stores/imageCreateStore.ts b/ui/frontend/build_src/src/stores/imageCreateStore.ts index d2aca528..a696ac4a 100644 --- a/ui/frontend/build_src/src/stores/imageCreateStore.ts +++ b/ui/frontend/build_src/src/stores/imageCreateStore.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/strict-boolean-expressions */ import create from "zustand"; import produce from "immer"; import { devtools } from "zustand/middleware"; @@ -75,15 +76,30 @@ export interface ImageRequest { stream_image_progress: boolean; } -type ModifiersList = string[]; -type ModifiersOptions = string | ModifiersList[]; -type ModifiersOptionList = ModifiersOptions[]; +export interface ModifierPreview { + name: string; + path: string; +} + +export interface ModifierObject { + category?: string; + modifier: string; + previews: ModifierPreview[]; +} + +interface ModifiersList { + category: string; + modifiers: ModifierObject[]; +} + +type ModifiersOptionList = ModifiersList[]; interface ImageCreateState { parallelCount: number; requestOptions: ImageRequest; allModifiers: ModifiersOptionList; tags: string[]; + tagMap: Record; isInpainting: boolean; setParallelCount: (count: number) => void; @@ -92,9 +108,9 @@ interface ImageCreateState { setAllModifiers: (modifiers: ModifiersOptionList) => void; setModifierOptions: (key: string, value: any) => void; - toggleTag: (tag: string) => void; - hasTag: (tag: string) => boolean; - selectedTags: () => string[]; + toggleTag: (category: string, tag: string) => void; + hasTag: (category: string, tag: string) => boolean; + selectedTags: () => ModifierObject[]; builtRequest: () => ImageRequest; uiOptions: ImageCreationUiOptions; @@ -145,6 +161,9 @@ export const useImageCreate = create( // selected tags tags: [] as string[], + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + tagMap: {} as Record, + uiOptions: { // TODO proper persistence of all UI / user settings centrally somewhere? // localStorage.getItem('ui:advancedSettingsIsOpen') === 'true', @@ -153,7 +172,7 @@ export const useImageCreate = create( isSoundEnabled: false, }, - allModifiers: [[[]]] as ModifiersOptionList, + allModifiers: [] as ModifiersOptionList, isInpainting: false, @@ -184,36 +203,78 @@ export const useImageCreate = create( ); }, - toggleTag: (tag: string) => { + toggleTag: (category: string, tag: string) => { set( produce((state) => { - const index = state.tags.indexOf(tag); - if (index > -1) { - state.tags.splice(index, 1); + + if (Object.keys(state.tagMap).includes(category)) { + if (state.tagMap[category].includes(tag)) { + state.tagMap[category] = state.tagMap[category].filter((t: string) => t !== tag); + } else { + state.tagMap[category].push(tag); + } } else { - state.tags.push(tag); + state.tagMap[category] = [tag]; } + + + // const index = state.tags.indexOf(tag); + // if (index > -1) { + // state.tags.splice(index, 1); + // } else { + // state.tags.push(tag); + // } + + }) ); }, - hasTag: (tag: string) => { - return get().tags.includes(tag); + hasTag: (category: string, tag: string) => { + return get().tagMap[category]?.includes(tag); }, selectedTags: () => { - return get().tags; + // get all the modifiers and all the tags + const allModifiers = get().allModifiers; + const selectedTags = get().tagMap; + let selected: ModifierObject[] = []; + + // for each mappped tag + for (const [category, tags] of Object.entries(selectedTags)) { + // find the modifier + const modifier = allModifiers.find((m) => m.category === category); + if (modifier) { + // for each tag in the modifier + for (const tag of tags) { + // find the tag + const tagObject = modifier.modifiers.find((m) => m.modifier === tag); + if (tagObject) { + // add the previews to the selected list + selected = selected.concat({ + ...tagObject, + category: modifier.category + }); + } + } + } + } + return selected; }, + + // the request body to send to the server // this is a computed value, just adding the tags to the request builtRequest: () => { const state = get(); const requestOptions = state.requestOptions; - const tags = state.tags; + const selectedTags = get().selectedTags(); + const tags = selectedTags.map((t: ModifierObject) => t.modifier); // join all the tags with a comma and add it to the prompt - const prompt = `${requestOptions.prompt} ${tags.join(",")}`; + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + const prompt = `${requestOptions.prompt}, ${tags.join(",")}`; const request = { ...requestOptions,