mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2025-06-01 15:46:54 +02:00
Merge pull request #29 from caranicas/beta-react-loading-and-cache
Beta react loading and cache
This commit is contained in:
commit
9f2ae75fa2
@ -35,6 +35,7 @@ module.exports = {
|
|||||||
yoda: ["off"],
|
yoda: ["off"],
|
||||||
eqeqeq: ["off"],
|
eqeqeq: ["off"],
|
||||||
"spaced-comment": ["off"],
|
"spaced-comment": ["off"],
|
||||||
|
"padded-blocks": ["off"],
|
||||||
|
|
||||||
// TS things turned off for now
|
// TS things turned off for now
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
|
@ -59,7 +59,6 @@ export const toggleBetaConfig = async (branch: string) => {
|
|||||||
|
|
||||||
export const MakeImageKey = "MakeImage";
|
export const MakeImageKey = "MakeImage";
|
||||||
export const doMakeImage = async (reqBody: ImageRequest) => {
|
export const doMakeImage = async (reqBody: ImageRequest) => {
|
||||||
const { seed, num_outputs } = reqBody;
|
|
||||||
|
|
||||||
const res = await fetch(`${API_URL}/image`, {
|
const res = await fetch(`${API_URL}/image`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -8,8 +8,8 @@ import {
|
|||||||
} from "./generatedImage.css.ts";
|
} from "./generatedImage.css.ts";
|
||||||
|
|
||||||
interface GeneretaedImageProps {
|
interface GeneretaedImageProps {
|
||||||
imageData: string;
|
imageData: string | undefined;
|
||||||
metadata: ImageRequest;
|
metadata: ImageRequest | undefined;
|
||||||
className?: string;
|
className?: string;
|
||||||
// children: never[];
|
// children: never[];
|
||||||
}
|
}
|
||||||
@ -21,7 +21,7 @@ export default function GeneratedImage({
|
|||||||
}: GeneretaedImageProps) {
|
}: GeneretaedImageProps) {
|
||||||
return (
|
return (
|
||||||
<div className={[generatedImageMain, className].join(" ")}>
|
<div className={[generatedImageMain, className].join(" ")}>
|
||||||
<img className={image} src={imageData} alt={metadata.prompt} />
|
<img className={image} src={imageData} alt={metadata!.prompt} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,6 @@ export default function ImprovementSettings() {
|
|||||||
const [isFilteringDisabled, setIsFilteringDisabled] = useState(false);
|
const [isFilteringDisabled, setIsFilteringDisabled] = useState(false);
|
||||||
// should probably be a store selector
|
// should probably be a store selector
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("isUsingUpscaling", isUsingUpscaling);
|
|
||||||
console.log("isUsingFaceCorrection", isUsingFaceCorrection);
|
|
||||||
|
|
||||||
// if either are true we arent disabled
|
// if either are true we arent disabled
|
||||||
if (isUsingFaceCorrection || use_upscale) {
|
if (isUsingFaceCorrection || use_upscale) {
|
||||||
|
@ -14,7 +14,6 @@ import {
|
|||||||
} from //@ts-expect-error
|
} from //@ts-expect-error
|
||||||
"./imageModifiers.css.ts";
|
"./imageModifiers.css.ts";
|
||||||
|
|
||||||
|
|
||||||
import { useImageCreate } from "../../../../stores/imageCreateStore";
|
import { useImageCreate } from "../../../../stores/imageCreateStore";
|
||||||
import { useCreateUI } from "../creationPanelUIStore";
|
import { useCreateUI } from "../creationPanelUIStore";
|
||||||
|
|
||||||
@ -88,7 +87,9 @@ export default function ImageModifers() {
|
|||||||
<ul className={ImagerModifierGroups}>
|
<ul className={ImagerModifierGroups}>
|
||||||
{allModifiers.map((item, index) => {
|
{allModifiers.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
|
// @ts-ignore
|
||||||
<li key={item[0]}>
|
<li key={item[0]}>
|
||||||
|
{/* @ts-ignore */}
|
||||||
<ModifierGrouping title={item[0]} tags={item[1]} />
|
<ModifierGrouping title={item[0]} tags={item[1]} />
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
@ -10,4 +10,6 @@ const AudioDing = React.forwardRef((props, ref) => (
|
|||||||
</audio>
|
</audio>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
AudioDing.displayName = "AudioDing";
|
||||||
|
|
||||||
export default AudioDing;
|
export default AudioDing;
|
||||||
|
@ -4,15 +4,37 @@ import { style, globalStyle } from "@vanilla-extract/css";
|
|||||||
import { vars } from "../../../../styles/theme/index.css.ts";
|
import { vars } from "../../../../styles/theme/index.css.ts";
|
||||||
|
|
||||||
export const completedImagesMain = style({
|
export const completedImagesMain = style({
|
||||||
|
height: "100%",
|
||||||
|
width: "100%",
|
||||||
|
display: "flex",
|
||||||
|
paddingBottom: vars.spacing.medium,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const completedImagesList = style({
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
flexWrap: "nowrap",
|
flexWrap: "nowrap",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
overflow: "auto",
|
overflow: "auto",
|
||||||
paddingBottom: vars.spacing.medium,
|
paddingLeft: vars.spacing.none,
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
globalStyle(`${completedImagesMain} li`, {
|
||||||
|
|
||||||
|
position: "relative",
|
||||||
|
});
|
||||||
|
|
||||||
|
globalStyle(`${completedImagesMain} > li:first-of-type`, {
|
||||||
|
marginLeft: vars.spacing.medium,
|
||||||
|
});
|
||||||
|
|
||||||
|
globalStyle(`${completedImagesMain} > li:last-of-type`, {
|
||||||
|
marginRight: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
export const imageContain = style({
|
export const imageContain = style({
|
||||||
width: "206px",
|
width: "206px",
|
||||||
backgroundColor: "black",
|
backgroundColor: "black",
|
||||||
@ -26,15 +48,18 @@ export const imageContain = style({
|
|||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
globalStyle(`${imageContain} img`, {
|
globalStyle(`${imageContain} img`, {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
objectFit: "contain",
|
objectFit: "contain",
|
||||||
});
|
});
|
||||||
|
|
||||||
globalStyle(`${completedImagesMain} > ${imageContain}:first-of-type`, {
|
export const RemoveButton = style({
|
||||||
marginLeft: vars.spacing.medium,
|
marginLeft: vars.spacing.small,
|
||||||
});
|
backgroundColor: vars.colors.brand,
|
||||||
|
border: "0 none",
|
||||||
globalStyle(`${imageContain} > ${imageContain}:last-of-type`, {
|
padding: vars.spacing.small,
|
||||||
marginRight: 0,
|
cursor: "pointer",
|
||||||
|
borderRadius: vars.trim.borderRadiusSmall,
|
||||||
});
|
});
|
@ -4,17 +4,22 @@ import { CompletedImagesType } from "../index";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
completedImagesMain,
|
completedImagesMain,
|
||||||
imageContain, // @ts-expect-error
|
completedImagesList,
|
||||||
|
imageContain,
|
||||||
|
RemoveButton,
|
||||||
|
// @ts-expect-error
|
||||||
} from "./completedImages.css.ts";
|
} from "./completedImages.css.ts";
|
||||||
|
|
||||||
interface CurrentDisplayProps {
|
interface CurrentDisplayProps {
|
||||||
images: CompletedImagesType[] | null;
|
images: CompletedImagesType[] | null;
|
||||||
setCurrentDisplay: (image: CompletedImagesType) => void;
|
setCurrentDisplay: (image: CompletedImagesType) => void;
|
||||||
|
removeImages: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CompletedImages({
|
export default function CompletedImages({
|
||||||
images,
|
images,
|
||||||
setCurrentDisplay,
|
setCurrentDisplay,
|
||||||
|
removeImages,
|
||||||
}: CurrentDisplayProps) {
|
}: CurrentDisplayProps) {
|
||||||
const _handleSetCurrentDisplay = (index: number) => {
|
const _handleSetCurrentDisplay = (index: number) => {
|
||||||
const image = images![index];
|
const image = images![index];
|
||||||
@ -23,25 +28,37 @@ export default function CompletedImages({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={completedImagesMain}>
|
<div className={completedImagesMain}>
|
||||||
{images != null &&
|
{/* Adjust the dom do we dont do this check twice */}
|
||||||
images.map((image, index) => {
|
{images != null && images.length > 0 && (
|
||||||
if (void 0 === image) {
|
<button className={RemoveButton} onClick={
|
||||||
console.warn(`image ${index} is undefined`);
|
() => {
|
||||||
return null;
|
removeImages();
|
||||||
}
|
}
|
||||||
|
}>REMOVE</button>
|
||||||
|
)}
|
||||||
|
<ul className={completedImagesList}>
|
||||||
|
{images != null &&
|
||||||
|
images.map((image, index) => {
|
||||||
|
if (void 0 === image) {
|
||||||
|
console.warn(`image ${index} is undefined`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<li key={image.id}>
|
||||||
key={index}
|
<button
|
||||||
className={imageContain}
|
className={imageContain}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
_handleSetCurrentDisplay(index);
|
_handleSetCurrentDisplay(index);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img src={image.data} alt={image.info.prompt} />
|
<img src={image.data} alt={image.info.prompt} />
|
||||||
</button>
|
</button>
|
||||||
);
|
</li>
|
||||||
})}
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,12 @@ import {
|
|||||||
import { CompletedImagesType } from "../index";
|
import { CompletedImagesType } from "../index";
|
||||||
|
|
||||||
interface CurrentDisplayProps {
|
interface CurrentDisplayProps {
|
||||||
|
isLoading: boolean;
|
||||||
image: CompletedImagesType | null;
|
image: CompletedImagesType | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CurrentDisplay({ image }: CurrentDisplayProps) {
|
export default function CurrentDisplay({ isLoading, image }: CurrentDisplayProps) {
|
||||||
// @ts-ignore
|
const { info, data } = image ?? {};
|
||||||
const { info, data } = image != null || { info: null, data: null };
|
|
||||||
|
|
||||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||||
|
|
||||||
@ -27,7 +27,8 @@ export default function CurrentDisplay({ image }: CurrentDisplayProps) {
|
|||||||
use_upscale,
|
use_upscale,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
} = info;
|
} = info!;
|
||||||
|
|
||||||
|
|
||||||
// Most important information is the prompt
|
// Most important information is the prompt
|
||||||
let underscoreName = prompt.replace(/[^a-zA-Z0-9]/g, "_");
|
let underscoreName = prompt.replace(/[^a-zA-Z0-9]/g, "_");
|
||||||
@ -60,20 +61,22 @@ export default function CurrentDisplay({ image }: CurrentDisplayProps) {
|
|||||||
setRequestOption("init_image", data);
|
setRequestOption("init_image", data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="current-display">
|
<div className="current-display">
|
||||||
{image != null && (
|
{isLoading
|
||||||
<div>
|
? <h4 className="loading">Loading...</h4>
|
||||||
<p> {info.prompt}</p>
|
: (image != null && (
|
||||||
<GeneratedImage imageData={data} metadata={info}></GeneratedImage>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button onClick={_handleSave}>Save</button>
|
<p> {info?.prompt}</p>
|
||||||
<button onClick={_handleUseAsInput}>Use as Input</button>
|
<GeneratedImage imageData={data} metadata={info}></GeneratedImage>
|
||||||
|
<div>
|
||||||
|
<button onClick={_handleSave}>Save</button>
|
||||||
|
<button onClick={_handleUseAsInput}>Use as Input</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)) || <h4 className="no-image">Try Making a new image!</h4>}
|
||||||
)}
|
|
||||||
<div></div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -29,24 +29,48 @@ export interface CompletedImagesType {
|
|||||||
info: ImageRequest;
|
info: ImageRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const idDelim = '_batch';
|
||||||
|
|
||||||
export default function DisplayPanel() {
|
export default function DisplayPanel() {
|
||||||
const dingRef = useRef<HTMLAudioElement>(null);
|
const dingRef = useRef<HTMLAudioElement>(null);
|
||||||
const isSoundEnabled = useImageCreate((state) => state.isSoundEnabled());
|
const isSoundEnabled = useImageCreate((state) => state.isSoundEnabled());
|
||||||
|
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
const { id, options } = useImageQueue((state) => state.firstInQueue());
|
const { id, options } = useImageQueue((state) => state.firstInQueue());
|
||||||
const removeFirstInQueue = useImageQueue((state) => state.removeFirstInQueue);
|
const removeFirstInQueue = useImageQueue((state) => state.removeFirstInQueue);
|
||||||
|
|
||||||
const [currentImage, setCurrentImage] = useState<CompletedImagesType | null>(
|
const [currentImage, setCurrentImage] = useState<CompletedImagesType | null>(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [isEnabled, setIsEnabled] = useState(false);
|
||||||
|
|
||||||
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
|
||||||
const { status, data } = useQuery(
|
const { status, data } = useQuery(
|
||||||
[MakeImageKey, id],
|
[MakeImageKey, id],
|
||||||
async () => await doMakeImage(options),
|
async () => await doMakeImage(options),
|
||||||
{
|
{
|
||||||
enabled: void 0 !== id,
|
enabled: isEnabled
|
||||||
|
// void 0 !== id,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// update the enabled state when the id changes
|
||||||
|
useEffect(() => {
|
||||||
|
setIsEnabled(void 0 !== id)
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
// helper for the loading state to be enabled aware
|
||||||
|
useEffect(() => {
|
||||||
|
if (isEnabled && status === "loading") {
|
||||||
|
setIsLoading(true);
|
||||||
|
} else {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
}, [isEnabled, status]);
|
||||||
|
|
||||||
|
// this is where there loading actually happens
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// query is done
|
// query is done
|
||||||
if (status === "success") {
|
if (status === "success") {
|
||||||
@ -60,23 +84,23 @@ export default function DisplayPanel() {
|
|||||||
}
|
}
|
||||||
}, [status, data, removeFirstInQueue, dingRef, isSoundEnabled]);
|
}, [status, data, removeFirstInQueue, dingRef, isSoundEnabled]);
|
||||||
|
|
||||||
|
|
||||||
/* COMPLETED IMAGES */
|
/* COMPLETED IMAGES */
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const [completedImages, setCompletedImages] = useState<CompletedImagesType[]>(
|
const [completedImages, setCompletedImages] = useState<CompletedImagesType[]>(
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const completedIds = useImageQueue((state) => state.completedImageIds);
|
const completedIds = useImageQueue((state) => state.completedImageIds);
|
||||||
|
const clearCachedIds = useImageQueue((state) => state.clearCachedIds);
|
||||||
|
|
||||||
// const init_image = useImageCreate((state) =>
|
// this is where we generate the list of completed images
|
||||||
// state.getValueForRequestKey("init_image")
|
|
||||||
// );
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const testReq = {} as ImageRequest;
|
const testReq = {} as ImageRequest;
|
||||||
const completedQueries = completedIds.map((id) => {
|
const completedQueries = completedIds.map((id) => {
|
||||||
const imageData = queryClient.getQueryData([MakeImageKey, id]);
|
const imageData = queryClient.getQueryData([MakeImageKey, id]);
|
||||||
return imageData;
|
return imageData;
|
||||||
});
|
}) as ImageRequest[];
|
||||||
|
|
||||||
if (completedQueries.length > 0) {
|
if (completedQueries.length > 0) {
|
||||||
// map the completedImagesto a new array
|
// map the completedImagesto a new array
|
||||||
@ -85,10 +109,10 @@ export default function DisplayPanel() {
|
|||||||
.map((query, index) => {
|
.map((query, index) => {
|
||||||
if (void 0 !== query) {
|
if (void 0 !== query) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return query.output.map((data) => {
|
return query.output.map((data, index) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return {
|
return {
|
||||||
id: `${completedIds[index]}-${data.seed}`,
|
id: `${completedIds[index]}${idDelim}-${data.seed}-${data.index}`,
|
||||||
data: data.data,
|
data: data.data,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
info: { ...query.request, seed: data.seed },
|
info: { ...query.request, seed: data.seed },
|
||||||
@ -98,10 +122,9 @@ export default function DisplayPanel() {
|
|||||||
})
|
})
|
||||||
.flat()
|
.flat()
|
||||||
.reverse()
|
.reverse()
|
||||||
.filter((item) => void 0 !== item); // remove undefined items
|
.filter((item) => void 0 !== item) as CompletedImagesType[]; // remove undefined items
|
||||||
|
|
||||||
setCompletedImages(temp);
|
setCompletedImages(temp);
|
||||||
debugger;
|
|
||||||
setCurrentImage(temp[0] || null);
|
setCurrentImage(temp[0] || null);
|
||||||
} else {
|
} else {
|
||||||
setCompletedImages([]);
|
setCompletedImages([]);
|
||||||
@ -109,14 +132,25 @@ export default function DisplayPanel() {
|
|||||||
}
|
}
|
||||||
}, [setCompletedImages, setCurrentImage, queryClient, completedIds]);
|
}, [setCompletedImages, setCurrentImage, queryClient, completedIds]);
|
||||||
|
|
||||||
|
// this is how we remove them
|
||||||
|
const removeImages = () => {
|
||||||
|
completedIds.forEach((id) => {
|
||||||
|
queryClient.removeQueries([MakeImageKey, id]);
|
||||||
|
});
|
||||||
|
clearCachedIds();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={displayPanel}>
|
<div className={displayPanel}>
|
||||||
<AudioDing ref={dingRef}></AudioDing>
|
<AudioDing ref={dingRef}></AudioDing>
|
||||||
<div className={displayContainer}>
|
<div className={displayContainer}>
|
||||||
<CurrentDisplay image={currentImage}></CurrentDisplay>
|
<CurrentDisplay isLoading={isLoading} image={currentImage}></CurrentDisplay>
|
||||||
</div>
|
</div>
|
||||||
<div className={previousImages}>
|
<div className={previousImages}>
|
||||||
<CompletedImages
|
<CompletedImages
|
||||||
|
removeImages={removeImages}
|
||||||
images={completedImages}
|
images={completedImages}
|
||||||
setCurrentDisplay={setCurrentImage}
|
setCurrentDisplay={setCurrentImage}
|
||||||
></CompletedImages>
|
></CompletedImages>
|
||||||
|
@ -11,6 +11,7 @@ interface ImageQueueState {
|
|||||||
hasQueuedImages: () => boolean;
|
hasQueuedImages: () => boolean;
|
||||||
firstInQueue: () => ImageRequest | [];
|
firstInQueue: () => ImageRequest | [];
|
||||||
removeFirstInQueue: () => void;
|
removeFirstInQueue: () => void;
|
||||||
|
clearCachedIds: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
// figure out why TS is complaining about this
|
// figure out why TS is complaining about this
|
||||||
@ -46,4 +47,12 @@ export const useImageQueue = create<ImageQueueState>((set, get) => ({
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
clearCachedIds: () => {
|
||||||
|
set(
|
||||||
|
produce((state) => {
|
||||||
|
state.completedImageIds = [];
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
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
254
ui/frontend/dist/index.html
vendored
254
ui/frontend/dist/index.html
vendored
@ -12,259 +12,5 @@
|
|||||||
<!-- The react app entry point. Currently no ui just poc importing and logging -->
|
<!-- The react app entry point. Currently no ui just poc importing and logging -->
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|
||||||
|
|
||||||
<!-- ORIGINAL CODE BELOW FOR REFENCE -->
|
|
||||||
|
|
||||||
<!-- KEEP FOR NOW -->
|
|
||||||
<!-- THE STYLES ARE BEING USED IN THE REACT APP -->
|
|
||||||
<!-- WE NEED TO PORT OVER THE STYLES OVER TO THE REACT COMPONENTS -->
|
|
||||||
<style>
|
|
||||||
/* label {
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
|
||||||
#prompt {
|
|
||||||
width: 100%;
|
|
||||||
height: 50pt;
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 600px) {
|
|
||||||
#prompt {
|
|
||||||
width: 95%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.image_preview_container {
|
|
||||||
display: none;
|
|
||||||
margin-top: 10pt;
|
|
||||||
}
|
|
||||||
.image_clear_btn {
|
|
||||||
position: absolute;
|
|
||||||
transform: translateX(-50%) translateY(-35%);
|
|
||||||
background: black;
|
|
||||||
color: white;
|
|
||||||
border: 2pt solid #ccc;
|
|
||||||
padding: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
outline: inherit;
|
|
||||||
border-radius: 8pt;
|
|
||||||
width: 16pt;
|
|
||||||
height: 16pt;
|
|
||||||
font-family: Verdana;
|
|
||||||
font-size: 8pt;
|
|
||||||
}
|
|
||||||
#editor-settings-entries {
|
|
||||||
font-size: 9pt;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
padding-left: 10px;
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
#editor-settings-entries li {
|
|
||||||
padding-bottom: 3pt;
|
|
||||||
}
|
|
||||||
#guidance_scale {
|
|
||||||
transform: translateY(30%);
|
|
||||||
} */
|
|
||||||
#outputMsg {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
#footer {
|
|
||||||
font-size: small;
|
|
||||||
padding-left: 10pt;
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
#footer-legal {
|
|
||||||
font-size: 8pt;
|
|
||||||
}
|
|
||||||
.imgSeedLabel {
|
|
||||||
position: absolute;
|
|
||||||
transform: translateX(-100%);
|
|
||||||
margin-top: 5pt;
|
|
||||||
margin-left: -5pt;
|
|
||||||
font-size: 10pt;
|
|
||||||
|
|
||||||
background-color: #333;
|
|
||||||
opacity: 0.8;
|
|
||||||
color: #ddd;
|
|
||||||
border-radius: 3pt;
|
|
||||||
padding: 1pt 3pt;
|
|
||||||
}
|
|
||||||
.imgUseBtn {
|
|
||||||
position: absolute;
|
|
||||||
transform: translateX(-100%);
|
|
||||||
margin-top: 30pt;
|
|
||||||
margin-left: -5pt;
|
|
||||||
}
|
|
||||||
.imgSaveBtn {
|
|
||||||
position: absolute;
|
|
||||||
transform: translateX(-100%);
|
|
||||||
margin-top: 55pt;
|
|
||||||
margin-left: -5pt;
|
|
||||||
}
|
|
||||||
.imgItem {
|
|
||||||
display: inline;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
.imgItemInfo {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
#container {
|
|
||||||
width: 75%;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 1400px) {
|
|
||||||
#container {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#meta small {
|
|
||||||
font-size: 11pt;
|
|
||||||
}
|
|
||||||
#editor {
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
#editor label {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
#preview {
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
#editor-inputs {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
#editor-inputs-prompt {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
#editor-inputs .row {
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
#makeImage {
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
#editor-modifiers h5 {
|
|
||||||
padding: 5pt 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
#makeImage {
|
|
||||||
flex: 0 0 70px;
|
|
||||||
background: rgb(80, 0, 185);
|
|
||||||
border: 2px solid rgb(40, 0, 78);
|
|
||||||
color: rgb(255, 221, 255);
|
|
||||||
width: 100%;
|
|
||||||
height: 30pt;
|
|
||||||
}
|
|
||||||
#makeImage:hover {
|
|
||||||
background: rgb(93, 0, 214);
|
|
||||||
}
|
|
||||||
.flex-container {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.col-50 {
|
|
||||||
flex: 50%;
|
|
||||||
}
|
|
||||||
.col-free {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.collapsible {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.collapsible-content {
|
|
||||||
display: none;
|
|
||||||
padding-left: 15px;
|
|
||||||
}
|
|
||||||
.collapsible-content h5 {
|
|
||||||
padding: 5pt 0pt;
|
|
||||||
margin: 0;
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
|
||||||
.collapsible-handle {
|
|
||||||
color: white;
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
.panel-box {
|
|
||||||
background: rgb(44, 45, 48);
|
|
||||||
border: 1px solid rgb(47, 49, 53);
|
|
||||||
border-radius: 7px;
|
|
||||||
padding: 5px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.15),
|
|
||||||
0 6px 20px 0 rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
.panel-box h4 {
|
|
||||||
margin: 0;
|
|
||||||
padding: 2px 0;
|
|
||||||
}
|
|
||||||
.prompt-modifier-tag {
|
|
||||||
border: 1px solid rgb(10, 0, 24);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 0pt 3pt;
|
|
||||||
margin-right: 2pt;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline;
|
|
||||||
background: rgb(163, 163, 163);
|
|
||||||
color: black;
|
|
||||||
line-height: 25pt;
|
|
||||||
float: left;
|
|
||||||
font-size: 9pt;
|
|
||||||
}
|
|
||||||
.prompt-modifier-tag:hover {
|
|
||||||
background: black;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
#editor-modifiers-entries .prompt-modifier-tag {
|
|
||||||
background: #110f0f;
|
|
||||||
color: rgb(212, 212, 212);
|
|
||||||
margin-bottom: 4pt;
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
|
||||||
#editor-modifiers-entries .prompt-modifier-tag:hover {
|
|
||||||
background: rgb(163, 163, 163);
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
#editor-modifiers .editor-modifiers-leaf {
|
|
||||||
padding-top: 10pt;
|
|
||||||
padding-bottom: 10pt;
|
|
||||||
}
|
|
||||||
#preview {
|
|
||||||
margin-left: 20pt;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.15),
|
|
||||||
0 6px 20px 0 rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
.line-separator {
|
|
||||||
background: rgb(56, 56, 56);
|
|
||||||
height: 1pt;
|
|
||||||
margin: 15pt 0;
|
|
||||||
}
|
|
||||||
#editor-inputs-tags-container {
|
|
||||||
margin-top: 5pt;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#server-status {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
#server-status-color {
|
|
||||||
width: 8pt;
|
|
||||||
height: 8pt;
|
|
||||||
border-radius: 4pt;
|
|
||||||
background-color: rgb(128, 87, 0);
|
|
||||||
/* background-color: rgb(197, 1, 1); */
|
|
||||||
float: left;
|
|
||||||
transform: translateY(15%);
|
|
||||||
}
|
|
||||||
#server-status-msg {
|
|
||||||
color: rgb(128, 87, 0);
|
|
||||||
padding-left: 2pt;
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
|
||||||
#preview-prompt {
|
|
||||||
font-size: 16pt;
|
|
||||||
margin-bottom: 10pt;
|
|
||||||
}
|
|
||||||
#coffeeButton {
|
|
||||||
height: 23px;
|
|
||||||
transform: translateY(25%);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
36
ui/frontend/dist/index.js
vendored
36
ui/frontend/dist/index.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user