forked from extern/easydiffusion
working positive and negative prompts
This commit is contained in:
parent
84b291a57a
commit
2607ef5fe0
@ -60,6 +60,7 @@ export const toggleBetaConfig = async (branch: string) => {
|
||||
export interface ImageRequest {
|
||||
session_id: string;
|
||||
prompt: string;
|
||||
negative_prompt: string;
|
||||
seed: number;
|
||||
num_outputs: number;
|
||||
num_inference_steps: number;
|
||||
|
@ -47,9 +47,9 @@ export const buttonStyle = recipe({
|
||||
},
|
||||
accent: {
|
||||
// @ts-expect-error
|
||||
'--button-hue': vars.backgroundAccentMain,
|
||||
'--button-base-saturation': vars.colorMod.saturation.normal,
|
||||
'--button-base-lightness': vars.colorMod.lightness.normal,
|
||||
'--button-hue': vars.backgroundAccentHue,
|
||||
'--button-base-saturation': vars.backgroundAccentSaturation,
|
||||
'--button-base-lightness': vars.backgroundAccentLightness,
|
||||
},
|
||||
clear: {
|
||||
backgroundColor: "transparent",
|
||||
@ -58,8 +58,8 @@ export const buttonStyle = recipe({
|
||||
|
||||
type: {
|
||||
fill: {
|
||||
backgroundColor: `hsl(var(--button-hue),${vars.colorMod.saturation.normal},${vars.colorMod.lightness.normal})`,
|
||||
border: `1px solid hsl(var(--button-hue),${vars.colorMod.saturation.normal},${vars.colorMod.lightness.normal})`,
|
||||
backgroundColor: `hsl(var(--button-hue),var(--button-base-saturation),${vars.colorMod.lightness.normal})`,
|
||||
border: `1px solid hsl(var(--button-hue),var(--button-base-saturation),${vars.colorMod.lightness.normal})`,
|
||||
":hover": {
|
||||
backgroundColor: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.normal})`,
|
||||
border: `1px solid hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.normal})`,
|
||||
@ -81,7 +81,7 @@ export const buttonStyle = recipe({
|
||||
},
|
||||
outline: {
|
||||
backgroundColor: "transparent",
|
||||
border: `1px solid hsl(var(--button-hue),${vars.colorMod.saturation.normal},${vars.colorMod.lightness.normal})`,
|
||||
border: `1px solid hsl(var(--button-hue),var(--button-base-saturation),${vars.colorMod.lightness.normal})`,
|
||||
":hover": {
|
||||
borderColor: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.normal})`,
|
||||
},
|
||||
@ -100,7 +100,7 @@ export const buttonStyle = recipe({
|
||||
},
|
||||
action: {
|
||||
backgroundColor: "transparent",
|
||||
color: `hsl(var(--button-hue),${vars.colorMod.saturation.normal},${vars.colorMod.lightness.normal})`,
|
||||
color: `hsl(var(--button-hue),var(--button-base-saturation),${vars.colorMod.lightness.normal})`,
|
||||
textDecoration: "underline",
|
||||
":hover": {
|
||||
color: `hsl(var(--button-hue),${vars.colorMod.saturation.bright},${vars.colorMod.lightness.normal})`,
|
||||
@ -121,6 +121,10 @@ export const buttonStyle = recipe({
|
||||
},
|
||||
|
||||
size: {
|
||||
slim: {
|
||||
padding: vars.spacing.min,
|
||||
fontSize: vars.fonts.sizes.Caption,
|
||||
},
|
||||
large: {
|
||||
width: "100%",
|
||||
fontSize: vars.fonts.sizes.Headline,
|
||||
|
@ -20,6 +20,7 @@ export const card = recipe({
|
||||
background: vars.backgroundDark,
|
||||
},
|
||||
},
|
||||
|
||||
rounded: {
|
||||
true: {
|
||||
borderRadius: vars.trim.smallBorderRadius,
|
||||
|
@ -250,7 +250,6 @@ export default function MakeButton() {
|
||||
return;
|
||||
}
|
||||
|
||||
debugger;
|
||||
makeImages(options).catch((e) => {
|
||||
console.log('HAS QUEUE ERROR');
|
||||
console.log(e);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import {
|
||||
ModifierPreview,
|
||||
useImageCreate
|
||||
@ -6,9 +7,16 @@ import {
|
||||
|
||||
import { API_URL } from "../../../api";
|
||||
|
||||
import {
|
||||
IconFont,
|
||||
} from "../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
ModifierTagMain,
|
||||
tagPreview
|
||||
ModifierActions,
|
||||
tagPreview,
|
||||
TagText,
|
||||
TagToggle,
|
||||
} from "./modifierTags.css";
|
||||
|
||||
interface ModifierTagProps {
|
||||
@ -21,6 +29,25 @@ export default function ModifierTag({ name, category, previews }: ModifierTagPro
|
||||
|
||||
const previewType: 'portrait' | 'landscape' = "portrait";
|
||||
|
||||
const [showActions, setShowActions] = useState(false);
|
||||
|
||||
const handleHover = () => {
|
||||
setShowActions(true);
|
||||
};
|
||||
|
||||
const handleLeave = () => {
|
||||
setShowActions(false);
|
||||
};
|
||||
|
||||
const addCreateTag = useImageCreate((state) => state.addCreateTag);
|
||||
const setPositivePrompt = () => {
|
||||
addCreateTag({ id: uuidv4(), name, type: 'positive' });
|
||||
}
|
||||
const setNegativePrompt = () => {
|
||||
addCreateTag({ id: uuidv4(), name, type: 'negative' });
|
||||
}
|
||||
|
||||
|
||||
const hasTag = useImageCreate((state) => state.hasTag(category, name))
|
||||
? "selected"
|
||||
: "";
|
||||
@ -30,10 +57,23 @@ export default function ModifierTag({ name, category, previews }: ModifierTagPro
|
||||
toggleTag(category, name);
|
||||
};
|
||||
|
||||
// , hasTag].join(" ")
|
||||
return (
|
||||
<div className={[ModifierTagMain, hasTag].join(" ")} onClick={_toggleTag}>
|
||||
<p>{name}</p>
|
||||
<div className={tagPreview}>
|
||||
<div className={ModifierTagMain}
|
||||
onMouseEnter={handleHover}
|
||||
onMouseLeave={handleLeave}>
|
||||
<p className={!showActions ? TagText : TagToggle}>{name}</p>
|
||||
{showActions && (
|
||||
<div className={ModifierActions}>
|
||||
<button onClick={setPositivePrompt}>
|
||||
<i className={[IconFont, 'fa-solid', 'fa-plus'].join(" ")}></i>
|
||||
</button>
|
||||
<button onClick={setNegativePrompt}>
|
||||
<i className={[IconFont, 'fa-solid', 'fa-minus'].join(" ")}></i>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{/* <div className={tagPreview}>
|
||||
{previews.map((preview) => {
|
||||
if (preview.name !== previewType) {
|
||||
return null;
|
||||
@ -47,7 +87,7 @@ export default function ModifierTag({ name, category, previews }: ModifierTagPro
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,22 +1,20 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
import { vars } from '../../../styles/theme/index.css';
|
||||
|
||||
// .modifierTag.selected {
|
||||
// background-color: rgb(131, 11, 121);
|
||||
// }
|
||||
import { card } from '../../_recipes/card.css';
|
||||
|
||||
|
||||
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)",
|
||||
// });
|
||||
export const ModifierTagMain = style([
|
||||
card({
|
||||
backing: 'normal',
|
||||
level: 1,
|
||||
info: true
|
||||
}), {
|
||||
position: "relative",
|
||||
width: "fit-content",
|
||||
borderColor: `hsl(${vars.brandHue}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
padding: vars.spacing.small,
|
||||
}
|
||||
]);
|
||||
|
||||
globalStyle(`${ModifierTagMain}.selected`, {
|
||||
backgroundColor: "rgb(131, 11, 121)",
|
||||
@ -29,6 +27,34 @@ globalStyle(`${ModifierTagMain} p`, {
|
||||
});
|
||||
|
||||
|
||||
export const TagText = style({
|
||||
opacity: 1,
|
||||
});
|
||||
|
||||
export const TagToggle = style({
|
||||
opacity: 0.3,
|
||||
});
|
||||
|
||||
|
||||
export const ModifierActions = style({
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
left: "0",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
});
|
||||
|
||||
globalStyle(`${ModifierActions} button`, {
|
||||
flexGrow: 1,
|
||||
backgroundColor: "transparent",
|
||||
border: "none",
|
||||
boxShadow: `inset 0 0 24px 0px rgb(255 255 255 / 50%)`,
|
||||
borderRadius: "5px",
|
||||
padding: "0",
|
||||
});
|
||||
|
||||
export const tagPreview = style({
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
|
@ -0,0 +1,68 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { useImageCreate } from "../../../stores/imageCreateStore";
|
||||
|
||||
import {
|
||||
IconFont,
|
||||
} from "../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
PromptTagMain,
|
||||
TagToggle,
|
||||
TagRemoveButton,
|
||||
PromptTagText,
|
||||
PromptTagToggle
|
||||
} from "./promptTag.css";
|
||||
|
||||
interface PromptTagProps {
|
||||
id: string;
|
||||
name: string;
|
||||
category?: string;
|
||||
previews?: string[];
|
||||
type: string;
|
||||
};
|
||||
|
||||
export default function PromptTag({ id, name, category, previews, type }: PromptTagProps) {
|
||||
|
||||
const [showToggle, setShowToggle] = useState(false);
|
||||
|
||||
const removeCreateTag = useImageCreate((state) => state.removeCreateTag);
|
||||
const changeCreateTagType = useImageCreate((state) => state.changeCreateTagType);
|
||||
|
||||
const handleHover = () => {
|
||||
setShowToggle(true);
|
||||
};
|
||||
|
||||
const handleLeave = () => {
|
||||
setShowToggle(false);
|
||||
};
|
||||
|
||||
const toggleType = () => {
|
||||
if (type === 'positive') {
|
||||
changeCreateTagType(id, 'negative');
|
||||
}
|
||||
else {
|
||||
changeCreateTagType(id, 'positive');
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemove = () => {
|
||||
console.log('remove');
|
||||
removeCreateTag(id);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
onMouseEnter={handleHover}
|
||||
onMouseLeave={handleLeave}
|
||||
className={[PromptTagMain, type].join(' ')}>
|
||||
<p className={!showToggle ? PromptTagText : PromptTagToggle}>{name}</p>
|
||||
{showToggle && <button className={TagToggle} onClick={toggleType}>
|
||||
{type === 'positive' ? <i className={[IconFont, 'fa-solid', 'fa-minus'].join(" ")}></i> : <i className={[IconFont, 'fa-solid', 'fa-plus'].join(" ")}></i>}
|
||||
</button>}
|
||||
{showToggle && <button className={TagRemoveButton} onClick={handleRemove}>
|
||||
<i className={[IconFont, 'fa-solid', 'fa-close'].join(" ")}></i>
|
||||
</button>}
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,55 @@
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
import { style, globalStyle } from '@vanilla-extract/css';
|
||||
|
||||
import { XButton } from "../../../styles/shared.css";
|
||||
import { vars } from '../../../styles/theme/index.css';
|
||||
import { card } from '../../_recipes/card.css';
|
||||
|
||||
|
||||
export const PromptTagMain = style([
|
||||
card({
|
||||
backing: 'normal',
|
||||
level: 1,
|
||||
info: true
|
||||
}), {
|
||||
position: "relative",
|
||||
width: "fit-content",
|
||||
backgroundColor: `hsl(${vars.backgroundLight}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
padding: vars.spacing.small,
|
||||
}
|
||||
]);
|
||||
|
||||
export const PromptTagText = style({
|
||||
opacity: 1,
|
||||
fontSize: vars.fonts.sizes.Plain,
|
||||
});
|
||||
|
||||
export const PromptTagToggle = style({
|
||||
opacity: 0.3,
|
||||
fontSize: vars.fonts.sizes.Plain,
|
||||
});
|
||||
|
||||
globalStyle(`${PromptTagMain}.positive`, {
|
||||
borderColor: `hsl(${vars.brandHue}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
});
|
||||
|
||||
globalStyle(`${PromptTagMain}.negative`, {
|
||||
borderColor: `hsl(${vars.errorHue}, ${vars.colorMod.saturation.normal}, ${vars.colorMod.lightness.normal})`,
|
||||
});
|
||||
|
||||
export const TagToggle = style({
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
right: "0",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
border: "none",
|
||||
backgroundColor: "transparent",
|
||||
boxShadow: `inset 0 0 24px 0px rgb(255 255 255 / 50%)`,
|
||||
});
|
||||
|
||||
export const TagRemoveButton = style([XButton, {
|
||||
top: '-4px',
|
||||
left: '4px',
|
||||
padding: '0',
|
||||
}]);
|
@ -8,5 +8,5 @@ export const AdvancedSettingsList = style({
|
||||
});
|
||||
|
||||
export const AdvancedSettingGrouping = style({
|
||||
marginTop: vars.spacing.medium,
|
||||
marginTop: vars.spacing.small,
|
||||
});
|
||||
|
@ -66,7 +66,7 @@ export default function ImprovementSettings() {
|
||||
})}
|
||||
onClick={toggleImprovementOpen}
|
||||
>
|
||||
<h4>Improvement Settings</h4>
|
||||
Improvement Settings
|
||||
</button>
|
||||
{improvementOpen && (
|
||||
<>
|
||||
|
@ -79,7 +79,7 @@ export default function PropertySettings() {
|
||||
type: 'action',
|
||||
color: 'accent',
|
||||
})} onClick={togglePropertyOpen}>
|
||||
<h4>Property Settings</h4>
|
||||
Property Settings
|
||||
</button>
|
||||
{propertyOpen && (
|
||||
<>
|
||||
|
@ -36,7 +36,7 @@ export default function WorkflowSettings() {
|
||||
type: 'action',
|
||||
color: 'accent',
|
||||
})} onClick={toggleWorkflowOpen}>
|
||||
<h4>Workflow Settings</h4>
|
||||
Workflow Settings
|
||||
</button>
|
||||
{workflowOpen && (
|
||||
<>
|
||||
|
@ -1,22 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
import { useImageCreate } from "../../../../../stores/imageCreateStore";
|
||||
import ModifierTag from "../../../../molecules/modifierTag";
|
||||
|
||||
export default function ActiveTags() {
|
||||
const selectedtags = useImageCreate((state) => state.selectedTags());
|
||||
|
||||
return (
|
||||
<div className="selected-tags">
|
||||
<p>Active Tags</p>
|
||||
<ul>
|
||||
{selectedtags.map((tag) => (
|
||||
<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>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -13,20 +13,8 @@ export const CreationBasicMain = style([
|
||||
}]
|
||||
);
|
||||
|
||||
globalStyle(`${CreationBasicMain} > *`, {
|
||||
marginBottom: "10px",
|
||||
});
|
||||
|
||||
export const PromptDisplay = style({});
|
||||
|
||||
globalStyle(`${PromptDisplay} > p`, {
|
||||
fontSize: "1.5em",
|
||||
fontWeight: "bold",
|
||||
marginBottom: "10px",
|
||||
});
|
||||
|
||||
globalStyle(`${PromptDisplay} > textarea`, {
|
||||
width: "100%",
|
||||
resize: "vertical",
|
||||
height: "100px",
|
||||
globalStyle(`${CreationBasicMain} > *`, {
|
||||
marginBottom: '10px'
|
||||
});
|
||||
|
@ -1,13 +0,0 @@
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
import { vars } from "../../../../../styles/theme/index.css";
|
||||
|
||||
export const CreationActionMain = style({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
marginTop: vars.spacing.medium,
|
||||
});
|
||||
|
||||
globalStyle(`${CreationActionMain} button`, {
|
||||
marginBottom: vars.spacing.medium,
|
||||
});
|
@ -1,18 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
import MakeButton from "../../../../molecules/makeButton";
|
||||
|
||||
import ShowQueue from "../showQueue";
|
||||
|
||||
import {
|
||||
CreationActionMain
|
||||
} from "./creationActions.css";
|
||||
|
||||
export default function CreationActions() {
|
||||
return (
|
||||
<div className={CreationActionMain}>
|
||||
<MakeButton></MakeButton>
|
||||
{/* <ShowQueue></ShowQueue> */}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -6,13 +6,12 @@ import {
|
||||
PromptDisplay,
|
||||
} from "./basicCreation.css";
|
||||
|
||||
// import MakeButton from "./makeButton";
|
||||
// import StopButton from "./stopButton";
|
||||
// import ClearQueue from "./clearQueue";
|
||||
import CreationActions from "./creationActions";
|
||||
import SeedImage from "./seedImage";
|
||||
import ActiveTags from "./activeTags";
|
||||
import MakeButton from "../../../molecules/makeButton";
|
||||
|
||||
import PromptCreator from "./promptCreator";
|
||||
// import CreationActions from "./creationActions";
|
||||
import SeedImage from "./seedImage";
|
||||
import ActiveTags from "./promptCreator/activeTags";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@ -30,15 +29,9 @@ export default function BasicCreation() {
|
||||
|
||||
return (
|
||||
<div className={CreationBasicMain}>
|
||||
<div className={PromptDisplay}>
|
||||
<p>{t("home.editor-title")}</p>
|
||||
<textarea value={promptText} onChange={handlePromptChange}></textarea>
|
||||
</div>
|
||||
|
||||
<CreationActions></CreationActions>
|
||||
|
||||
<MakeButton></MakeButton>
|
||||
<PromptCreator></PromptCreator>
|
||||
<SeedImage></SeedImage>
|
||||
<ActiveTags></ActiveTags>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
import { vars } from '../../../../../../styles/theme/index.css';
|
||||
export const ActiveTagListMain = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: '10px',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
overflow: 'visible',
|
||||
scrollbarWidth: 'none',
|
||||
msOverflowStyle: 'none',
|
||||
'::-webkit-scrollbar': {
|
||||
display: 'none',
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -0,0 +1,39 @@
|
||||
import React from "react";
|
||||
|
||||
import { useImageCreate } from "../../../../../../stores/imageCreateStore";
|
||||
import ModifierTag from "../../../../../molecules/modifierTag";
|
||||
|
||||
// import {
|
||||
// card
|
||||
// } from '../../../../../_recipes/card.css';
|
||||
|
||||
|
||||
|
||||
import PromptTag from "../../../../../molecules/promptTag";
|
||||
|
||||
import {
|
||||
ActiveTagListMain
|
||||
} from "./activeTags.css";
|
||||
|
||||
|
||||
export default function ActiveTags() {
|
||||
const selectedtags = useImageCreate((state) => state.selectedTags());
|
||||
|
||||
const createTags = useImageCreate((state) => state.createTags);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ul className={ActiveTagListMain}>
|
||||
{createTags.map((tag) => {
|
||||
console.log(tag);
|
||||
return (
|
||||
<li key={tag.id}>
|
||||
{/* @ts-expect-error */}
|
||||
<PromptTag id={tag.id} name={tag.name} category={tag?.category} previews={tag?.previews} type={tag.type} />
|
||||
</li>)
|
||||
}
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
import React, { useState, ChangeEvent, KeyboardEventHandler, Fragment } from "react";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { Switch } from '@headlessui/react'
|
||||
|
||||
import { useImageCreate } from "../../../../../stores/imageCreateStore";
|
||||
|
||||
import ActiveTags from "./activeTags";
|
||||
|
||||
import {
|
||||
IconFont,
|
||||
} from "../../../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
buttonStyle,
|
||||
} from "../../../../_recipes/button.css";
|
||||
|
||||
import {
|
||||
PromptCreatorMain,
|
||||
ToggleGroupMain,
|
||||
ToggleMain,
|
||||
ToggleLabel,
|
||||
ToggleEnabled,
|
||||
TogglePill,
|
||||
buttonRow,
|
||||
} from "./promptCreator.css";
|
||||
|
||||
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { type } from "os";
|
||||
|
||||
interface TagTypeProps {
|
||||
positive: boolean;
|
||||
setPositive: (positive: boolean) => void;
|
||||
};
|
||||
|
||||
function TagTypeToggle({ positive, setPositive }: TagTypeProps) {
|
||||
return (
|
||||
<Switch.Group as={Fragment}>
|
||||
<div className={ToggleGroupMain}>
|
||||
<Switch.Label> Type </Switch.Label>
|
||||
<Switch className={ToggleMain} checked={positive} onChange={setPositive}>
|
||||
<span
|
||||
className={TogglePill}
|
||||
>
|
||||
{positive
|
||||
? <i className={[IconFont, 'fa-solid', 'fa-plus'].join(" ")}></i>
|
||||
: <i className={[IconFont, 'fa-solid', 'fa-minus'].join(" ")}></i>}
|
||||
</span>
|
||||
</Switch>
|
||||
</div>
|
||||
</Switch.Group>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PromptCreator() {
|
||||
|
||||
const [positive, setPositive] = useState(true)
|
||||
const [tagText, setTagText] = useState('An astronaut riding a horse');
|
||||
|
||||
const addCreateTag = useImageCreate((state) => state.addCreateTag);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const checkForEnter = (event: KeyboardEventHandler<HTMLInputElement>) => {
|
||||
// @ts-expect-error
|
||||
if (event.key === "Enter") {
|
||||
if (tagText !== '') {
|
||||
const type = positive ? "positive" : "negative";
|
||||
|
||||
tagText.split(',').map((tag) => tag.trim()).forEach((tag) => {
|
||||
addCreateTag({ id: uuidv4(), name: tag, type });
|
||||
});
|
||||
//debugger;
|
||||
|
||||
setTagText('');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={PromptCreatorMain}>
|
||||
<div>
|
||||
<p>{t("home.editor-title")}</p>
|
||||
{/* @ts-expect-error */}
|
||||
<input value={tagText} onKeyDown={checkForEnter} onChange={(event) => {
|
||||
setTagText(event.target.value)
|
||||
}}></input>
|
||||
</div>
|
||||
<div className={buttonRow}>
|
||||
<button
|
||||
className={buttonStyle(
|
||||
{
|
||||
size: 'slim'
|
||||
}
|
||||
)}
|
||||
onClick={() => {
|
||||
}}
|
||||
>
|
||||
Add Prompt
|
||||
</button>
|
||||
|
||||
<TagTypeToggle positive={positive} setPositive={setPositive}></TagTypeToggle>
|
||||
</div>
|
||||
<ActiveTags></ActiveTags>
|
||||
</div >
|
||||
);
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
import { style, globalStyle } from '@vanilla-extract/css';
|
||||
|
||||
import { vars } from "../../../../../styles/theme/index.css";
|
||||
|
||||
export const PromptCreatorMain = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
marginBottom: 0,
|
||||
});
|
||||
|
||||
globalStyle(`${PromptCreatorMain} input`, {
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
globalStyle(`${PromptCreatorMain} > div`, {
|
||||
marginBottom: vars.spacing.small,
|
||||
});
|
||||
|
||||
export const ToggleGroupMain = style({
|
||||
// '--toggle-size': '30px',
|
||||
});
|
||||
|
||||
export const ToggleMain = style({
|
||||
background: vars.backgroundDark,
|
||||
height: '22px',
|
||||
borderRadius: '15px',
|
||||
width: '34px',
|
||||
border: 0,
|
||||
position: 'relative',
|
||||
display: 'inline-flex',
|
||||
padding: 0,
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
boxShadow: `0 0 2px 0 ${vars.backgroundDark}`,
|
||||
});
|
||||
|
||||
export const ToggleLabel = style({
|
||||
});
|
||||
|
||||
export const ToggleEnabled = style({
|
||||
});
|
||||
|
||||
globalStyle(`${ToggleMain}[data-headlessui-state="checked"]`, {
|
||||
background: vars.backgroundLight,
|
||||
});
|
||||
|
||||
export const TogglePill = style({
|
||||
display: 'inline-flex',
|
||||
height: '18px',
|
||||
width: '30px',
|
||||
borderRadius: '15px',
|
||||
background: vars.backgroundDark,
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
});
|
||||
|
||||
globalStyle(`${ToggleMain}[data-headlessui-state="checked"] ${TogglePill}`, {
|
||||
background: vars.backgroundAccentMain,
|
||||
});
|
||||
|
||||
globalStyle(`${TogglePill} p`, {
|
||||
color: vars.colors.text.normal,
|
||||
});
|
||||
|
||||
|
||||
export const buttonRow = style({
|
||||
marginTop: vars.spacing.small,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
});
|
||||
|
||||
globalStyle(`${buttonRow} > button`, {
|
||||
flexGrow: 1,
|
||||
marginRight: vars.spacing.medium,
|
||||
});
|
@ -1,11 +1,14 @@
|
||||
import React, { useRef, ChangeEvent } from "react";
|
||||
|
||||
|
||||
|
||||
import { XButton } from "../../../../../styles/shared.css";
|
||||
|
||||
import {
|
||||
ImageInputDisplay,
|
||||
InputLabel,
|
||||
ImageInput,
|
||||
ImageFixer,
|
||||
XButton,
|
||||
} from "./seedImage.css";
|
||||
|
||||
import {
|
||||
|
@ -21,21 +21,3 @@ export const ImageInput = style({
|
||||
export const ImageFixer = style({
|
||||
marginLeft: "20px",
|
||||
});
|
||||
|
||||
// just a 1 off component for now
|
||||
// dont bother bringing in line with the rest of the app
|
||||
export const XButton = style({
|
||||
position: "absolute",
|
||||
transform: "translateX(-50%) translateY(-35%)",
|
||||
background: "black",
|
||||
color: "white",
|
||||
border: "2pt solid #ccc",
|
||||
padding: "0",
|
||||
cursor: "pointer",
|
||||
outline: "inherit",
|
||||
borderRadius: "8pt",
|
||||
width: "16pt",
|
||||
height: "16pt",
|
||||
fontFamily: "Verdana",
|
||||
fontSize: "8pt",
|
||||
});
|
||||
|
@ -15,12 +15,17 @@ export const ImageModifierGrouping = style({
|
||||
marginTop: vars.spacing.medium,
|
||||
});
|
||||
|
||||
globalStyle(`${ImageModifierGrouping} h4`, {
|
||||
fontSize: vars.fonts.sizes.Plain,
|
||||
});
|
||||
|
||||
|
||||
export const ModifierListStyle = style({
|
||||
paddingLeft: 0,
|
||||
listStyleType: "none",
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
gap: vars.spacing.small,
|
||||
});
|
||||
|
||||
globalStyle(`${ModifierListStyle} li`, {
|
||||
|
@ -22,6 +22,7 @@ export default function ImageDisplay({ info, data }: CompletedImagesType) {
|
||||
const createFileName = () => {
|
||||
const {
|
||||
prompt,
|
||||
negative_prompt,
|
||||
seed,
|
||||
num_inference_steps,
|
||||
guidance_scale,
|
||||
@ -74,6 +75,7 @@ export default function ImageDisplay({ info, data }: CompletedImagesType) {
|
||||
<div className={imageDisplayContent}>
|
||||
<div>
|
||||
<p> {info?.prompt}</p>
|
||||
<p> {info?.negative_prompt}</p>
|
||||
<div>
|
||||
<button className={buttonStyle(
|
||||
|
||||
|
@ -42,11 +42,20 @@ interface ModifiersList {
|
||||
|
||||
type ModifiersOptionList = ModifiersList[];
|
||||
|
||||
export interface promptTag {
|
||||
id: string;
|
||||
name: string;
|
||||
type: 'positive' | 'negative';
|
||||
}
|
||||
|
||||
interface ImageCreateState {
|
||||
parallelCount: number;
|
||||
requestOptions: ImageRequest;
|
||||
allModifiers: ModifiersOptionList;
|
||||
tags: string[];
|
||||
|
||||
createTags: promptTag[];
|
||||
// negativeTags: promptTag[];
|
||||
|
||||
tagMap: Record<string, string[]>;
|
||||
isInpainting: boolean;
|
||||
|
||||
@ -59,6 +68,11 @@ interface ImageCreateState {
|
||||
toggleTag: (category: string, tag: string) => void;
|
||||
hasTag: (category: string, tag: string) => boolean;
|
||||
selectedTags: () => ModifierObject[];
|
||||
addCreateTag: (tag: promptTag) => void;
|
||||
removeCreateTag: (id: string) => void;
|
||||
changeCreateTagType: (id: string, type: 'positive' | 'negative') => void;
|
||||
reorderCreateTag: (tag: promptTag, index: number) => void;
|
||||
|
||||
builtRequest: () => ImageRequest;
|
||||
|
||||
uiOptions: ImageCreationUiOptions;
|
||||
@ -85,6 +99,7 @@ export const useImageCreate = create<ImageCreateState>(
|
||||
requestOptions: {
|
||||
session_id: new Date().getTime().toString(),
|
||||
prompt: "a photograph of an astronaut riding a horse",
|
||||
negative_prompt: "",
|
||||
seed: useRandomSeed(),
|
||||
num_outputs: 1,
|
||||
num_inference_steps: 50,
|
||||
@ -108,7 +123,8 @@ export const useImageCreate = create<ImageCreateState>(
|
||||
},
|
||||
|
||||
// selected tags
|
||||
tags: [] as string[],
|
||||
createTags: [] as promptTag[],
|
||||
// negativeTags: [] as promptTag[],
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
tagMap: {} as Record<string, string[]>,
|
||||
@ -202,7 +218,48 @@ export const useImageCreate = create<ImageCreateState>(
|
||||
return selected;
|
||||
},
|
||||
|
||||
addCreateTag: (tag: promptTag) => {
|
||||
set(
|
||||
produce((state) => {
|
||||
state.createTags.push(tag);
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
removeCreateTag: (id: string) => {
|
||||
set(
|
||||
produce((state) => {
|
||||
// @ts-expect-error
|
||||
state.createTags = state.createTags.filter((t) => t.id !== id);
|
||||
})
|
||||
|
||||
);
|
||||
},
|
||||
|
||||
changeCreateTagType: (id: string, type: 'positive' | 'negative') => {
|
||||
set(
|
||||
produce((state) => {
|
||||
// @ts-expect-error
|
||||
const tag = state.createTags.find((t) => t.id === id);
|
||||
if (tag) {
|
||||
tag.type = type;
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
reorderCreateTag: (tag: promptTag, index: number) => {
|
||||
set(
|
||||
produce((state) => {
|
||||
const tagIndex = state.createTags.indexOf(tag);
|
||||
if (tagIndex !== -1) {
|
||||
state.createTags.splice(tagIndex, 1);
|
||||
state.createTags.splice(index, 0, tag);
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
// the request body to send to the server
|
||||
// this is a computed value, just adding the tags to the request
|
||||
@ -212,13 +269,17 @@ export const useImageCreate = create<ImageCreateState>(
|
||||
const selectedTags = get().selectedTags();
|
||||
const tags = selectedTags.map((t: ModifierObject) => t.modifier);
|
||||
|
||||
const positivePrompt = state.createTags.filter((t) => t.type === "positive").map((t) => t.name).join(",");
|
||||
const negativePrompt = state.createTags.filter((t) => t.type === "negative").map((t) => t.name).join(",");
|
||||
|
||||
// join all the tags with a comma and add it to the prompt
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
const prompt = `${requestOptions.prompt}, ${tags.join(",")}`;
|
||||
// const prompt = `${requestOptions.prompt}, ${tags.join(",")}`;
|
||||
|
||||
const request = {
|
||||
...requestOptions,
|
||||
prompt,
|
||||
prompt: positivePrompt,
|
||||
negative_prompt: negativePrompt,
|
||||
};
|
||||
// if we arent using auto save clear the save path
|
||||
if (!state.uiOptions.isUseAutoSave) {
|
||||
|
@ -19,6 +19,24 @@ export const IconFont = style({
|
||||
});
|
||||
|
||||
|
||||
export const XButton = style({
|
||||
position: "absolute",
|
||||
transform: "translateX(-50%) translateY(-35%)",
|
||||
background: "black",
|
||||
color: "white",
|
||||
border: "2pt solid #ccc",
|
||||
padding: "0",
|
||||
cursor: "pointer",
|
||||
outline: "inherit",
|
||||
borderRadius: "8pt",
|
||||
width: "16pt",
|
||||
height: "16pt",
|
||||
fontFamily: "Verdana",
|
||||
fontSize: "8pt",
|
||||
});
|
||||
|
||||
|
||||
|
||||
export const MenuButton = style({
|
||||
display: "block",
|
||||
width: "100%",
|
||||
@ -33,6 +51,5 @@ export const MenuButton = style({
|
||||
|
||||
globalStyle(`${MenuButton}> h4`, {
|
||||
color: "#e7ba71",
|
||||
|
||||
});
|
||||
|
||||
|
@ -4,49 +4,6 @@ import {
|
||||
createTheme,
|
||||
} from "@vanilla-extract/css";
|
||||
|
||||
|
||||
// const colors = createThemeContract({
|
||||
// brand: null,
|
||||
// brandDimmed: null,
|
||||
// brandHover: null,
|
||||
// brandActive: null,
|
||||
// brandAccent: null,
|
||||
// brandAccentDimmed: null,
|
||||
// brandAccentActive: null,
|
||||
|
||||
// secondary: null,
|
||||
// secondaryDimmed: null,
|
||||
// secondaryHover: null,
|
||||
// secondaryActive: null,
|
||||
// secondaryAccent: null,
|
||||
// secondaryAccentDimmed: null,
|
||||
// secondaryAccentActive: null,
|
||||
|
||||
// background: null,
|
||||
// backgroundAccent: null,
|
||||
// backgroundAlt: null,
|
||||
// backgroundAltAccent: null,
|
||||
// backgroundDark: null,
|
||||
// backgroundDarkAccent: null,
|
||||
|
||||
// text: {
|
||||
// normal: null,
|
||||
// dimmed: null,
|
||||
|
||||
// secondary: null,
|
||||
// secondaryDimmed: null,
|
||||
|
||||
// accent: null,
|
||||
// accentDimmed: null,
|
||||
// },
|
||||
|
||||
// link: null,
|
||||
|
||||
// warning: null,
|
||||
// error: null,
|
||||
// success: null,
|
||||
// });
|
||||
|
||||
const app = createGlobalTheme(":root", {
|
||||
spacing: {
|
||||
none: "0",
|
||||
@ -107,6 +64,10 @@ const app = createGlobalTheme(":root", {
|
||||
backgroundDark: 'hsl(225, 3%, 7%)',
|
||||
backgroundAccentMain: 'hsl(225, 6%, 30%)',
|
||||
|
||||
backgroundAccentHue: '225',
|
||||
backgroundAccentSaturation: '26%',
|
||||
backgroundAccentLightness: '70%',
|
||||
|
||||
// this is depricated
|
||||
colors: {
|
||||
text: {
|
||||
|
2
ui/frontend/dist/index.css
vendored
2
ui/frontend/dist/index.css
vendored
File diff suppressed because one or more lines are too long
44
ui/frontend/dist/index.js
vendored
44
ui/frontend/dist/index.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user