mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2024-11-23 00:33:28 +01:00
current and cache history
This commit is contained in:
parent
bad015de9a
commit
c7b89a1126
13
ui/frontend/build_src/package-lock.json
generated
13
ui/frontend/build_src/package-lock.json
generated
@ -21,6 +21,7 @@
|
||||
"zustand": "^4.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.7.18",
|
||||
"@types/react": "^18.0.17",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/uuid": "^8.3.4",
|
||||
@ -613,6 +614,12 @@
|
||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.7.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.18.tgz",
|
||||
"integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/prop-types": {
|
||||
"version": "15.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||
@ -2361,6 +2368,12 @@
|
||||
"use-sync-external-store": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "18.7.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.18.tgz",
|
||||
"integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/prop-types": {
|
||||
"version": "15.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||
|
@ -23,6 +23,7 @@
|
||||
"zustand": "^4.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.7.18",
|
||||
"@types/react": "^18.0.17",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/uuid": "^8.3.4",
|
||||
|
@ -1,34 +1,20 @@
|
||||
import { style } from "@vanilla-extract/css";
|
||||
|
||||
export const generatedImage = style({
|
||||
export const generatedImageMain = style({
|
||||
position: "relative",
|
||||
width: "512px",
|
||||
height: "512px",
|
||||
});
|
||||
|
||||
export const imageContain = style({
|
||||
width: "512px",
|
||||
height: "512px",
|
||||
backgroundColor: "black",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
});
|
||||
// export const imageContain = style({
|
||||
// width: "512px",
|
||||
// height: "512px",
|
||||
// backgroundColor: "black",
|
||||
// display: "flex",
|
||||
// justifyContent: "center",
|
||||
// alignItems: "center",
|
||||
// });
|
||||
|
||||
export const image = style({
|
||||
width: "512px",
|
||||
height: "512px",
|
||||
objectFit: "contain",
|
||||
});
|
||||
|
||||
export const saveButton = style({
|
||||
position: "absolute",
|
||||
bottom: "10px",
|
||||
left: "10px",
|
||||
});
|
||||
|
||||
export const useButton = style({
|
||||
position: "absolute",
|
||||
bottom: "10px",
|
||||
right: "10px",
|
||||
// width: "512px",
|
||||
// height: "512px",
|
||||
// objectFit: "contain",
|
||||
});
|
||||
|
@ -3,17 +3,16 @@ import React, { useCallback } from "react";
|
||||
import { ImageRequest, useImageCreate } from "../../../stores/imageCreateStore";
|
||||
|
||||
import {
|
||||
generatedImage,
|
||||
imageContain,
|
||||
generatedImageMain,
|
||||
image,
|
||||
saveButton,
|
||||
useButton, //@ts-ignore
|
||||
} from "./generatedImage.css.ts";
|
||||
} from //@ts-ignore
|
||||
"./generatedImage.css.ts";
|
||||
|
||||
type GeneretaedImageProps = {
|
||||
imageData: string;
|
||||
metadata: ImageRequest;
|
||||
className?: string;
|
||||
children: never[];
|
||||
};
|
||||
|
||||
export default function GeneratedImage({
|
||||
@ -21,65 +20,10 @@ export default function GeneratedImage({
|
||||
metadata,
|
||||
className,
|
||||
}: GeneretaedImageProps) {
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
|
||||
const createFileName = () => {
|
||||
const {
|
||||
prompt,
|
||||
seed,
|
||||
num_inference_steps,
|
||||
guidance_scale,
|
||||
use_face_correction,
|
||||
use_upscale,
|
||||
width,
|
||||
height,
|
||||
} = metadata;
|
||||
|
||||
//Most important information is the prompt
|
||||
let underscoreName = prompt.replace(/[^a-zA-Z0-9]/g, "_");
|
||||
underscoreName = underscoreName.substring(0, 100);
|
||||
// name and the top level metadata
|
||||
let fileName = `${underscoreName}_Seed-${seed}_Steps-${num_inference_steps}_Guidance-${guidance_scale}`;
|
||||
// Add the face correction and upscale
|
||||
if (use_face_correction) {
|
||||
fileName += `_FaceCorrection-${use_face_correction}`;
|
||||
}
|
||||
if (use_upscale) {
|
||||
fileName += `_Upscale-${use_upscale}`;
|
||||
}
|
||||
// Add the width and height
|
||||
fileName += `_${width}x${height}`;
|
||||
// add the file extension
|
||||
fileName += `.png`;
|
||||
// return fileName
|
||||
return fileName;
|
||||
};
|
||||
|
||||
const _handleSave = () => {
|
||||
const link = document.createElement("a");
|
||||
link.download = createFileName();
|
||||
link.href = imageData;
|
||||
link.click();
|
||||
};
|
||||
|
||||
const _handleUseAsInput = () => {
|
||||
setRequestOption("init_image", imageData);
|
||||
};
|
||||
|
||||
// className={[statusClass, className].join(" ")}
|
||||
|
||||
return (
|
||||
<div className={[generatedImage, className].join(" ")}>
|
||||
<p>{metadata.prompt}</p>
|
||||
<div className={imageContain}>
|
||||
<img className={image} src={imageData} alt="generated" />
|
||||
<button className={saveButton} onClick={_handleSave}>
|
||||
Save
|
||||
</button>
|
||||
<button className={useButton} onClick={_handleUseAsInput}>
|
||||
Use as Input
|
||||
</button>
|
||||
</div>
|
||||
<div className={[generatedImageMain, className].join(" ")}>
|
||||
<img className={image} src={imageData} alt={metadata.prompt} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ import AdvancedSettings from "./advancedSettings";
|
||||
import ImageModifiers from "./imageModifiers";
|
||||
import InpaintingPanel from "./inpaintingPanel";
|
||||
|
||||
// this works but causes type errors so its not worth it for now
|
||||
// import { useImageCreate } from "@stores/imageCreateStore.ts";
|
||||
|
||||
import { useImageCreate } from "../../../stores/imageCreateStore";
|
||||
|
||||
import "./creationPanel.css";
|
||||
|
@ -0,0 +1,44 @@
|
||||
|
||||
|
||||
import { style, globalStyle } from "@vanilla-extract/css";
|
||||
|
||||
// @ts-ignore
|
||||
import { vars } from "../../../../styles/theme/index.css.ts";
|
||||
|
||||
|
||||
export const completedImagesMain = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'nowrap',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
overflow: 'auto',
|
||||
paddingBottom: vars.spacing.medium,
|
||||
|
||||
});
|
||||
|
||||
|
||||
export const imageContain = style({
|
||||
width: "112px",
|
||||
backgroundColor: "black",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexShrink: 0,
|
||||
border: '0 none',
|
||||
padding: '0',
|
||||
});
|
||||
|
||||
globalStyle(`${imageContain} img`, {
|
||||
width: "100%",
|
||||
objectFit: "contain",
|
||||
|
||||
});
|
||||
|
||||
globalStyle(`${completedImagesMain} > ${imageContain}:first-of-type`, {
|
||||
marginLeft: vars.spacing.medium,
|
||||
});
|
||||
|
||||
globalStyle(`${imageContain} > ${imageContain}:last-of-type`, {
|
||||
marginRight: 0,
|
||||
});
|
@ -1,18 +1,61 @@
|
||||
export const CompletedImages = () => {
|
||||
import React from "react";
|
||||
|
||||
|
||||
import { CompletedImagesType } from "../index";
|
||||
|
||||
type CurrentDisplayProps = {
|
||||
images: CompletedImagesType[] | null;
|
||||
setCurrentDisplay: (image: CompletedImagesType) => void;
|
||||
}
|
||||
|
||||
|
||||
import {
|
||||
completedImagesMain,
|
||||
imageContain
|
||||
} from //@ts-ignore
|
||||
"./completedImages.css.ts";
|
||||
|
||||
export default function CompletedImages({ images, setCurrentDisplay }: CurrentDisplayProps) {
|
||||
|
||||
|
||||
const _handleSetCurrentDisplay = (index: number) => {
|
||||
debugger
|
||||
const image = images![index];
|
||||
setCurrentDisplay(image);
|
||||
};
|
||||
|
||||
|
||||
console.log('COMP{LETED IMAGES', images);
|
||||
return (
|
||||
<div className="completed-images">
|
||||
<h1>Completed Images</h1>
|
||||
<div className={completedImagesMain}>
|
||||
{images && images.map((image, index) => {
|
||||
|
||||
// if (void 0 !== image) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
return (
|
||||
|
||||
// <div className={imageContain} key={index} value={index} onClick={() => {
|
||||
// debugger;
|
||||
// const image = images[index];
|
||||
// _handleSetCurrentDisplay(image);
|
||||
// }}>
|
||||
// <img src={image.data} alt={image.info.prompt} />
|
||||
// </div>
|
||||
|
||||
<button key={index} className={imageContain} onClick={
|
||||
() => {
|
||||
|
||||
console.log('CLICKED', index);
|
||||
debugger;
|
||||
_handleSetCurrentDisplay(index);
|
||||
}
|
||||
}>
|
||||
<img src={image.data} alt={image.info.prompt} />
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
// const { data } = useQuery("completedImages", getCompletedImages);
|
||||
// return (
|
||||
// <div className="completed-images">
|
||||
// <h2>Completed Images</h2>
|
||||
// <div className="completed-images-list">
|
||||
// {data?.map((image) => (
|
||||
// <GeneratedImage imageData={image.data} key={image.id} />
|
||||
// ))}
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
};
|
||||
)
|
||||
};
|
@ -0,0 +1,90 @@
|
||||
import React from "react";
|
||||
import GeneratedImage from "../../../molecules/generatedImage";
|
||||
import { ImageRequest, useImageCreate } from "../../../../stores/imageCreateStore";
|
||||
|
||||
import { CompletedImagesType } from "../index";
|
||||
|
||||
type CurrentDisplayProps = {
|
||||
image: CompletedImagesType | null;
|
||||
};
|
||||
|
||||
|
||||
export default function CurrentDisplay({ image }: CurrentDisplayProps) {
|
||||
|
||||
const { info, data } = image || { info: null, data: null };
|
||||
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
|
||||
const createFileName = () => {
|
||||
const {
|
||||
prompt,
|
||||
seed,
|
||||
num_inference_steps,
|
||||
guidance_scale,
|
||||
use_face_correction,
|
||||
use_upscale,
|
||||
width,
|
||||
height,
|
||||
} = info!;
|
||||
|
||||
//Most important information is the prompt
|
||||
let underscoreName = prompt.replace(/[^a-zA-Z0-9]/g, "_");
|
||||
underscoreName = underscoreName.substring(0, 100);
|
||||
// name and the top level metadata
|
||||
let fileName = `${underscoreName}_Seed-${seed}_Steps-${num_inference_steps}_Guidance-${guidance_scale}`;
|
||||
// Add the face correction and upscale
|
||||
if (use_face_correction) {
|
||||
fileName += `_FaceCorrection-${use_face_correction}`;
|
||||
}
|
||||
if (use_upscale) {
|
||||
fileName += `_Upscale-${use_upscale}`;
|
||||
}
|
||||
// Add the width and height
|
||||
fileName += `_${width}x${height}`;
|
||||
// add the file extension
|
||||
fileName += `.png`;
|
||||
// return fileName
|
||||
return fileName;
|
||||
};
|
||||
|
||||
const _handleSave = () => {
|
||||
const link = document.createElement("a");
|
||||
link.download = createFileName();
|
||||
link.href = data!;
|
||||
link.click();
|
||||
};
|
||||
|
||||
const _handleUseAsInput = () => {
|
||||
setRequestOption("init_image", data);
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="current-display">
|
||||
{image &&
|
||||
<div>
|
||||
<p> {info!.prompt}</p>
|
||||
<GeneratedImage
|
||||
imageData={data!}
|
||||
metadata={info!}
|
||||
>
|
||||
</GeneratedImage>
|
||||
|
||||
<div>
|
||||
<button onClick={_handleSave}>
|
||||
Save
|
||||
</button>
|
||||
<button onClick={_handleUseAsInput}>
|
||||
Use as Input
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4,29 +4,21 @@ import { style } from "@vanilla-extract/css";
|
||||
import { vars } from "../../../styles/theme/index.css.ts";
|
||||
|
||||
export const displayPanel = style({
|
||||
padding: vars.spacing.medium,
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
});
|
||||
|
||||
export const displayContainer = style({
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
overflow: "hidden",
|
||||
});
|
||||
|
||||
export const CurrentDisplay = style({
|
||||
width: "512px",
|
||||
height: "100%",
|
||||
flexGrow: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
|
||||
});
|
||||
|
||||
export const previousImages = style({
|
||||
marginLeft: vars.spacing.large,
|
||||
display: "flex",
|
||||
flex: "auto",
|
||||
flexWrap: "wrap",
|
||||
});
|
||||
|
||||
export const previousImage = style({
|
||||
margin: `0 ${vars.spacing.small}`,
|
||||
height: '150px',
|
||||
});
|
||||
|
@ -9,33 +9,36 @@ import { doMakeImage, MakeImageKey } from "../../../api";
|
||||
|
||||
import AudioDing from "./audioDing";
|
||||
|
||||
import GeneratedImage from "../../molecules/generatedImage";
|
||||
// import GeneratedImage from "../../molecules/generatedImage";
|
||||
// import DrawImage from "../../molecules/drawImage";
|
||||
|
||||
|
||||
import CurrentDisplay from "./currentDisplay";
|
||||
import CompletedImages from "./completedImages";
|
||||
|
||||
import {
|
||||
displayPanel,
|
||||
displayContainer,
|
||||
CurrentDisplay,
|
||||
// CurrentDisplay,
|
||||
previousImages,
|
||||
previousImage, //@ts-ignore
|
||||
} from "./displayPanel.css.ts";
|
||||
|
||||
type CompletedImagesType = {
|
||||
export type CompletedImagesType = {
|
||||
id: string;
|
||||
data: string;
|
||||
info: ImageRequest;
|
||||
};
|
||||
|
||||
export default function DisplayPanel() {
|
||||
|
||||
const dingRef = useRef<HTMLAudioElement>(null);
|
||||
const isSoundEnabled = useImageCreate((state) => state.isSoundEnabled());
|
||||
|
||||
const isInPaintingMode = useImageCreate((state) => state.isInpainting);
|
||||
|
||||
/* FETCHING */
|
||||
// @ts-ignore
|
||||
const { id, options } = useImageQueue((state) => state.firstInQueue());
|
||||
const removeFirstInQueue = useImageQueue((state) => state.removeFirstInQueue);
|
||||
const [currentImage, setCurrentImage] = useState<CompletedImagesType | null>(null);
|
||||
|
||||
const { status, data } = useQuery(
|
||||
[MakeImageKey, id],
|
||||
() => doMakeImage(options),
|
||||
@ -58,16 +61,15 @@ export default function DisplayPanel() {
|
||||
}, [status, data, removeFirstInQueue, dingRef, isSoundEnabled]);
|
||||
|
||||
/* COMPLETED IMAGES */
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
const [completedImages, setCompletedImages] = useState<CompletedImagesType[]>(
|
||||
[]
|
||||
);
|
||||
const completedIds = useImageQueue((state) => state.completedImageIds);
|
||||
|
||||
const init_image = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("init_image")
|
||||
);
|
||||
// const init_image = useImageCreate((state) =>
|
||||
// state.getValueForRequestKey("init_image")
|
||||
// );
|
||||
|
||||
useEffect(() => {
|
||||
const testReq = {} as ImageRequest;
|
||||
@ -97,51 +99,23 @@ export default function DisplayPanel() {
|
||||
.flat()
|
||||
.reverse();
|
||||
setCompletedImages(temp);
|
||||
setCurrentImage(temp[0] || null);
|
||||
} else {
|
||||
setCompletedImages([]);
|
||||
setCurrentImage(null);
|
||||
}
|
||||
}, [setCompletedImages, queryClient, completedIds]);
|
||||
}, [setCompletedImages, setCurrentImage, queryClient, completedIds]);
|
||||
|
||||
return (
|
||||
<div className={displayPanel}>
|
||||
<AudioDing ref={dingRef}></AudioDing>
|
||||
<div className={displayContainer}>
|
||||
{/* {isInPaintingMode && <DrawImage imageData={init_image}></DrawImage>} */}
|
||||
|
||||
{completedImages.length > 0 && (
|
||||
<>
|
||||
<div className={CurrentDisplay}>
|
||||
<GeneratedImage
|
||||
key={completedImages[0].id}
|
||||
imageData={completedImages[0].data}
|
||||
metadata={completedImages[0].info}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={previousImages}>
|
||||
{completedImages.map((image, index) => {
|
||||
if (void 0 !== image) {
|
||||
if (index == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<GeneratedImage
|
||||
className={previousImage}
|
||||
key={image.id}
|
||||
imageData={image.data}
|
||||
metadata={image.info}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
console.warn("image is undefined", image, index);
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<CurrentDisplay image={currentImage}></CurrentDisplay>
|
||||
</div>
|
||||
<div className={previousImages}>
|
||||
<CompletedImages images={completedImages} setCurrentDisplay={setCurrentImage}></CompletedImages>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@stores": ["src/stores"]
|
||||
},
|
||||
|
||||
"target": "ESNext",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||
|
@ -2,14 +2,28 @@ import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
|
||||
|
||||
import path from "path";
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
|
||||
resolve: {
|
||||
alias: {
|
||||
// TODO figure out why vs code complains about this even though it works
|
||||
"@stores": path.resolve(__dirname, "./src/stores"),
|
||||
// TODO - add more aliases
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
plugins: [
|
||||
react(),
|
||||
vanillaExtractPlugin({
|
||||
// configuration
|
||||
}),
|
||||
],
|
||||
|
||||
|
||||
server: {
|
||||
port: 9001,
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user