mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2024-12-25 00:19:09 +01:00
tags working
This commit is contained in:
parent
96ad8c823a
commit
e5844c926b
@ -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 (
|
||||
<div className={"modifierTag " + hasTag} onClick={_toggleTag}>
|
||||
<div className={[ModifierTagMain, hasTag].join(" ")} onClick={_toggleTag}>
|
||||
<p>{name}</p>
|
||||
<div className={tagPreview}>
|
||||
{previews.map((preview) => {
|
||||
if (preview.name !== previewType) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<img
|
||||
key={preview.name}
|
||||
src={`${API_URL}/media/modifier-thumbnails/${preview.path}`}
|
||||
alt={preview.name}
|
||||
title={preview.name}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -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",
|
||||
});
|
||||
|
@ -5,13 +5,17 @@ import ModifierTag from "../../../../atoms/modifierTag";
|
||||
|
||||
export default function ActiveTags() {
|
||||
const selectedtags = useImageCreate((state) => state.selectedTags());
|
||||
|
||||
console.log("ActiveTags", selectedtags);
|
||||
|
||||
return (
|
||||
<div className="selected-tags">
|
||||
<p>Active Tags</p>
|
||||
<ul>
|
||||
{selectedtags.map((tag) => (
|
||||
<li key={tag}>
|
||||
<ModifierTag name={tag}></ModifierTag>
|
||||
<li key={tag.modifier}>
|
||||
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
|
||||
<ModifierTag category={tag.category!} name={tag.modifier} previews={tag.previews} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
@ -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 */
|
||||
|
@ -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 (
|
||||
<ul className={ModifierListStyle}>
|
||||
{tags.map((tag) => (
|
||||
<li key={tag}>
|
||||
<ModifierTag name={tag} />
|
||||
<li key={tag.modifier}>
|
||||
<ModifierTag category={category} name={tag.modifier} previews={tag.previews} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
@ -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 (
|
||||
<div className={ImageModifierGrouping}>
|
||||
<button type="button" className={MenuButton} onClick={_toggleExpand}>
|
||||
<h4>{title}</h4>
|
||||
</button>
|
||||
{isExpanded && <ModifierList tags={tags} />}
|
||||
{isExpanded && <ModifierList category={category} tags={tags} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -81,11 +85,12 @@ export default function ImageModifers() {
|
||||
{imageModifierIsOpen && (
|
||||
<ul className={ImagerModifierGroups}>
|
||||
{allModifiers.map((item, index) => {
|
||||
|
||||
// console.log('mod item ', item);
|
||||
|
||||
return (
|
||||
// @ts-expect-error
|
||||
<li key={item[0]}>
|
||||
{/* @ts-expect-error */}
|
||||
<ModifierGrouping title={item[0]} tags={item[1]} />
|
||||
<li key={item.category}>
|
||||
<ModifierGrouping title={item.category} category={item.category} tags={item.modifiers} />
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
|
@ -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<string, string[]>;
|
||||
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<ImageCreateState>(
|
||||
// selected tags
|
||||
tags: [] as string[],
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
tagMap: {} as Record<string, string[]>,
|
||||
|
||||
uiOptions: {
|
||||
// TODO proper persistence of all UI / user settings centrally somewhere?
|
||||
// localStorage.getItem('ui:advancedSettingsIsOpen') === 'true',
|
||||
@ -153,7 +172,7 @@ export const useImageCreate = create<ImageCreateState>(
|
||||
isSoundEnabled: false,
|
||||
},
|
||||
|
||||
allModifiers: [[[]]] as ModifiersOptionList,
|
||||
allModifiers: [] as ModifiersOptionList,
|
||||
|
||||
isInpainting: false,
|
||||
|
||||
@ -184,36 +203,78 @@ export const useImageCreate = create<ImageCreateState>(
|
||||
);
|
||||
},
|
||||
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user