mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Reorganises internal state
`options` slice was huge and managed a mix of generation parameters and general app settings. It has been split up: - Generation parameters are now in `generationSlice`. - Postprocessing parameters are now in `postprocessingSlice` - UI related things are now in `uiSlice` There is probably more to be done, like `gallerySlice` perhaps should only manage internal gallery state, and not if the gallery is displayed. Full-slice selectors have been made for each slice. Other organisational tweaks.
This commit is contained in:
parent
511df2963b
commit
f80a64a0f4
52
invokeai/frontend/dist/assets/index-legacy-35973932.js
vendored
Normal file
52
invokeai/frontend/dist/assets/index-legacy-35973932.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
9
invokeai/frontend/dist/index.html
vendored
9
invokeai/frontend/dist/index.html
vendored
@ -7,8 +7,13 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
||||||
<link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" />
|
<link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" />
|
||||||
|
<<<<<<< HEAD
|
||||||
<script type="module" crossorigin src="./assets/index.f3fa9388.js"></script>
|
<script type="module" crossorigin src="./assets/index.f3fa9388.js"></script>
|
||||||
<link rel="stylesheet" href="./assets/index.1536494e.css">
|
<link rel="stylesheet" href="./assets/index.1536494e.css">
|
||||||
|
=======
|
||||||
|
<script type="module" crossorigin src="./assets/index.5c5bc3f1.js"></script>
|
||||||
|
<link rel="stylesheet" href="./assets/index.8badc8b4.css">
|
||||||
|
>>>>>>> 64c0b743 (Reorganises internal state)
|
||||||
<script type="module">try{import.meta.url;import("_").catch(()=>1);}catch(e){}window.__vite_is_modern_browser=true;</script>
|
<script type="module">try{import.meta.url;import("_").catch(()=>1);}catch(e){}window.__vite_is_modern_browser=true;</script>
|
||||||
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy build because dynamic import or import.meta.url is unsupported, syntax error above should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
|
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy build because dynamic import or import.meta.url is unsupported, syntax error above should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
|
||||||
</head>
|
</head>
|
||||||
@ -18,6 +23,10 @@
|
|||||||
|
|
||||||
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
|
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
|
||||||
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-dde3a68a.js"></script>
|
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-dde3a68a.js"></script>
|
||||||
|
<<<<<<< HEAD
|
||||||
<script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/index-legacy-4add591a.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
|
<script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/index-legacy-4add591a.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
|
||||||
|
=======
|
||||||
|
<script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/index-legacy-35973932.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
|
||||||
|
>>>>>>> 64c0b743 (Reorganises internal state)
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -48,8 +48,8 @@
|
|||||||
"sendTo": "Send to",
|
"sendTo": "Send to",
|
||||||
"sendToImg2Img": "Send to Image to Image",
|
"sendToImg2Img": "Send to Image to Image",
|
||||||
"sendToUnifiedCanvas": "Send To Unified Canvas",
|
"sendToUnifiedCanvas": "Send To Unified Canvas",
|
||||||
"copyImage": "Copy Image",
|
|
||||||
"copyImageToLink": "Copy Image To Link",
|
"copyImageToLink": "Copy Image To Link",
|
||||||
|
"copyImage": "Copy Image",
|
||||||
"downloadImage": "Download Image",
|
"downloadImage": "Download Image",
|
||||||
"openInViewer": "Open In Viewer",
|
"openInViewer": "Open In Viewer",
|
||||||
"closeViewer": "Close Viewer",
|
"closeViewer": "Close Viewer",
|
@ -2,13 +2,13 @@ import ProgressBar from 'features/system/components/ProgressBar';
|
|||||||
import SiteHeader from 'features/system/components/SiteHeader';
|
import SiteHeader from 'features/system/components/SiteHeader';
|
||||||
import Console from 'features/system/components/Console';
|
import Console from 'features/system/components/Console';
|
||||||
import { keepGUIAlive } from './utils';
|
import { keepGUIAlive } from './utils';
|
||||||
import InvokeTabs from 'features/tabs/components/InvokeTabs';
|
import InvokeTabs from 'features/ui/components/InvokeTabs';
|
||||||
import ImageUploader from 'common/components/ImageUploader';
|
import ImageUploader from 'common/components/ImageUploader';
|
||||||
|
|
||||||
import useToastWatcher from 'features/system/hooks/useToastWatcher';
|
import useToastWatcher from 'features/system/hooks/useToastWatcher';
|
||||||
|
|
||||||
import FloatingOptionsPanelButtons from 'features/tabs/components/FloatingOptionsPanelButtons';
|
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
|
||||||
import FloatingGalleryButton from 'features/tabs/components/FloatingGalleryButton';
|
import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton';
|
||||||
|
|
||||||
keepGUIAlive();
|
keepGUIAlive();
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ const App = () => {
|
|||||||
<Console />
|
<Console />
|
||||||
</div>
|
</div>
|
||||||
</ImageUploader>
|
</ImageUploader>
|
||||||
<FloatingOptionsPanelButtons />
|
<FloatingParametersPanelButtons />
|
||||||
<FloatingGalleryButton />
|
<FloatingGalleryButton />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
2
invokeai/frontend/src/app/invokeai.d.ts
vendored
2
invokeai/frontend/src/app/invokeai.d.ts
vendored
@ -12,7 +12,7 @@
|
|||||||
* 'gfpgan'.
|
* 'gfpgan'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { InvokeTabName } from 'features/tabs/tabMap';
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import { IRect } from 'konva/lib/types';
|
import { IRect } from 'konva/lib/types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,32 +1,26 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { RootState } from 'app/store';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
import { OptionsState } from 'features/options/store/optionsSlice';
|
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
|
||||||
import { validateSeedWeights } from 'common/util/seedWeightPairs';
|
import { validateSeedWeights } from 'common/util/seedWeightPairs';
|
||||||
import { initialCanvasImageSelector } from 'features/canvas/store/canvasSelectors';
|
import { initialCanvasImageSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
|
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||||
|
|
||||||
export const readinessSelector = createSelector(
|
export const readinessSelector = createSelector(
|
||||||
[
|
[
|
||||||
(state: RootState) => state.options,
|
generationSelector,
|
||||||
(state: RootState) => state.system,
|
systemSelector,
|
||||||
initialCanvasImageSelector,
|
initialCanvasImageSelector,
|
||||||
activeTabNameSelector,
|
activeTabNameSelector,
|
||||||
],
|
],
|
||||||
(
|
(generation, system, initialCanvasImage, activeTabName) => {
|
||||||
options: OptionsState,
|
|
||||||
system: SystemState,
|
|
||||||
initialCanvasImage,
|
|
||||||
activeTabName
|
|
||||||
) => {
|
|
||||||
const {
|
const {
|
||||||
prompt,
|
prompt,
|
||||||
shouldGenerateVariations,
|
shouldGenerateVariations,
|
||||||
seedWeights,
|
seedWeights,
|
||||||
initialImage,
|
initialImage,
|
||||||
seed,
|
seed,
|
||||||
} = options;
|
} = generation;
|
||||||
|
|
||||||
const { isProcessing, isConnected } = system;
|
const { isProcessing, isConnected } = system;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createAction } from '@reduxjs/toolkit';
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
import { GalleryCategory } from 'features/gallery/store/gallerySlice';
|
import { GalleryCategory } from 'features/gallery/store/gallerySlice';
|
||||||
import { InvokeTabName } from 'features/tabs/tabMap';
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import * as InvokeAI from 'app/invokeai';
|
import * as InvokeAI from 'app/invokeai';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,14 +10,13 @@ import {
|
|||||||
GalleryState,
|
GalleryState,
|
||||||
removeImage,
|
removeImage,
|
||||||
} from 'features/gallery/store/gallerySlice';
|
} from 'features/gallery/store/gallerySlice';
|
||||||
import { OptionsState } from 'features/options/store/optionsSlice';
|
|
||||||
import {
|
import {
|
||||||
addLogEntry,
|
addLogEntry,
|
||||||
generationRequested,
|
generationRequested,
|
||||||
modelChangeRequested,
|
modelChangeRequested,
|
||||||
setIsProcessing,
|
setIsProcessing,
|
||||||
} from 'features/system/store/systemSlice';
|
} from 'features/system/store/systemSlice';
|
||||||
import { InvokeTabName } from 'features/tabs/tabMap';
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import * as InvokeAI from 'app/invokeai';
|
import * as InvokeAI from 'app/invokeai';
|
||||||
import type { RootState } from 'app/store';
|
import type { RootState } from 'app/store';
|
||||||
|
|
||||||
@ -39,7 +38,8 @@ const makeSocketIOEmitters = (
|
|||||||
const state: RootState = getState();
|
const state: RootState = getState();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
options: optionsState,
|
generation: generationState,
|
||||||
|
postprocessing: postprocessingState,
|
||||||
system: systemState,
|
system: systemState,
|
||||||
canvas: canvasState,
|
canvas: canvasState,
|
||||||
} = state;
|
} = state;
|
||||||
@ -47,7 +47,8 @@ const makeSocketIOEmitters = (
|
|||||||
const frontendToBackendParametersConfig: FrontendToBackendParametersConfig =
|
const frontendToBackendParametersConfig: FrontendToBackendParametersConfig =
|
||||||
{
|
{
|
||||||
generationMode,
|
generationMode,
|
||||||
optionsState,
|
generationState,
|
||||||
|
postprocessingState,
|
||||||
canvasState,
|
canvasState,
|
||||||
systemState,
|
systemState,
|
||||||
};
|
};
|
||||||
@ -90,8 +91,11 @@ const makeSocketIOEmitters = (
|
|||||||
},
|
},
|
||||||
emitRunESRGAN: (imageToProcess: InvokeAI.Image) => {
|
emitRunESRGAN: (imageToProcess: InvokeAI.Image) => {
|
||||||
dispatch(setIsProcessing(true));
|
dispatch(setIsProcessing(true));
|
||||||
const options: OptionsState = getState().options;
|
|
||||||
const { upscalingLevel, upscalingStrength } = options;
|
const {
|
||||||
|
postprocessing: { upscalingLevel, upscalingStrength },
|
||||||
|
} = getState();
|
||||||
|
|
||||||
const esrganParameters = {
|
const esrganParameters = {
|
||||||
upscale: [upscalingLevel, upscalingStrength],
|
upscale: [upscalingLevel, upscalingStrength],
|
||||||
};
|
};
|
||||||
@ -111,8 +115,10 @@ const makeSocketIOEmitters = (
|
|||||||
},
|
},
|
||||||
emitRunFacetool: (imageToProcess: InvokeAI.Image) => {
|
emitRunFacetool: (imageToProcess: InvokeAI.Image) => {
|
||||||
dispatch(setIsProcessing(true));
|
dispatch(setIsProcessing(true));
|
||||||
const options: OptionsState = getState().options;
|
|
||||||
const { facetoolType, facetoolStrength, codeformerFidelity } = options;
|
const {
|
||||||
|
postprocessing: { facetoolType, facetoolStrength, codeformerFidelity },
|
||||||
|
} = getState();
|
||||||
|
|
||||||
const facetoolParameters: Record<string, unknown> = {
|
const facetoolParameters: Record<string, unknown> = {
|
||||||
facetool_strength: facetoolStrength,
|
facetool_strength: facetoolStrength,
|
||||||
|
@ -35,14 +35,14 @@ import {
|
|||||||
setInfillMethod,
|
setInfillMethod,
|
||||||
setInitialImage,
|
setInitialImage,
|
||||||
setMaskPath,
|
setMaskPath,
|
||||||
} from 'features/options/store/optionsSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
import {
|
import {
|
||||||
requestImages,
|
requestImages,
|
||||||
requestNewImages,
|
requestNewImages,
|
||||||
requestSystemConfig,
|
requestSystemConfig,
|
||||||
} from './actions';
|
} from './actions';
|
||||||
import { addImageToStagingArea } from 'features/canvas/store/canvasSlice';
|
import { addImageToStagingArea } from 'features/canvas/store/canvasSlice';
|
||||||
import { tabMap } from 'features/tabs/tabMap';
|
import { tabMap } from 'features/ui/store/tabMap';
|
||||||
import type { RootState } from 'app/store';
|
import type { RootState } from 'app/store';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,8 +104,9 @@ const makeSocketIOListeners = (
|
|||||||
*/
|
*/
|
||||||
onGenerationResult: (data: InvokeAI.ImageResultResponse) => {
|
onGenerationResult: (data: InvokeAI.ImageResultResponse) => {
|
||||||
try {
|
try {
|
||||||
const state: RootState = getState();
|
const state = getState();
|
||||||
const { shouldLoopback, activeTab } = state.options;
|
const { activeTab } = state.ui;
|
||||||
|
const { shouldLoopback } = state.postprocessing;
|
||||||
const { boundingBox: _, generationMode, ...rest } = data;
|
const { boundingBox: _, generationMode, ...rest } = data;
|
||||||
|
|
||||||
const newImage = {
|
const newImage = {
|
||||||
@ -327,7 +328,9 @@ const makeSocketIOListeners = (
|
|||||||
dispatch(removeImage(data));
|
dispatch(removeImage(data));
|
||||||
|
|
||||||
// remove references to image in options
|
// remove references to image in options
|
||||||
const { initialImage, maskPath } = getState().options;
|
const {
|
||||||
|
generation: { initialImage, maskPath },
|
||||||
|
} = getState();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
initialImage === url ||
|
initialImage === url ||
|
||||||
|
@ -5,10 +5,13 @@ import storage from 'redux-persist/lib/storage'; // defaults to localStorage for
|
|||||||
|
|
||||||
import { getPersistConfig } from 'redux-deep-persist';
|
import { getPersistConfig } from 'redux-deep-persist';
|
||||||
|
|
||||||
import optionsReducer from 'features/options/store/optionsSlice';
|
import generationReducer from 'features/parameters/store/generationSlice';
|
||||||
|
import postprocessingReducer from 'features/parameters/store/postprocessingSlice';
|
||||||
import galleryReducer from 'features/gallery/store/gallerySlice';
|
import galleryReducer from 'features/gallery/store/gallerySlice';
|
||||||
import systemReducer from 'features/system/store/systemSlice';
|
import systemReducer from 'features/system/store/systemSlice';
|
||||||
import canvasReducer from 'features/canvas/store/canvasSlice';
|
import canvasReducer from 'features/canvas/store/canvasSlice';
|
||||||
|
import uiReducer from 'features/ui/store/uiSlice';
|
||||||
|
import lightboxReducer from 'features/lightbox/store/lightboxSlice';
|
||||||
|
|
||||||
import { socketioMiddleware } from './socketio/middleware';
|
import { socketioMiddleware } from './socketio/middleware';
|
||||||
|
|
||||||
@ -58,10 +61,13 @@ const galleryBlacklist = [
|
|||||||
].map((blacklistItem) => `gallery.${blacklistItem}`);
|
].map((blacklistItem) => `gallery.${blacklistItem}`);
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
options: optionsReducer,
|
generation: generationReducer,
|
||||||
|
postprocessing: postprocessingReducer,
|
||||||
gallery: galleryReducer,
|
gallery: galleryReducer,
|
||||||
system: systemReducer,
|
system: systemReducer,
|
||||||
canvas: canvasReducer,
|
canvas: canvasReducer,
|
||||||
|
ui: uiReducer,
|
||||||
|
lightbox: lightboxReducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
const rootPersistConfig = getPersistConfig({
|
const rootPersistConfig = getPersistConfig({
|
||||||
@ -89,8 +95,8 @@ export const store = configureStore({
|
|||||||
'canvas/setStageCoordinates',
|
'canvas/setStageCoordinates',
|
||||||
'canvas/setStageScale',
|
'canvas/setStageScale',
|
||||||
'canvas/setIsDrawing',
|
'canvas/setIsDrawing',
|
||||||
// 'canvas/setBoundingBoxCoordinates',
|
'canvas/setBoundingBoxCoordinates',
|
||||||
// 'canvas/setBoundingBoxDimensions',
|
'canvas/setBoundingBoxDimensions',
|
||||||
'canvas/setIsDrawing',
|
'canvas/setIsDrawing',
|
||||||
'canvas/addPointToCurrentLine',
|
'canvas/addPointToCurrentLine',
|
||||||
],
|
],
|
||||||
|
@ -7,23 +7,23 @@ import {
|
|||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
import { SystemState } from 'features/system/store/systemSlice';
|
||||||
import { useAppSelector } from 'app/storeHooks';
|
import { useAppSelector } from 'app/storeHooks';
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
import { Feature, useFeatureHelpInfo } from 'app/features';
|
import { Feature, useFeatureHelpInfo } from 'app/features';
|
||||||
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
|
||||||
type GuideProps = {
|
type GuideProps = {
|
||||||
children: ReactElement;
|
children: ReactElement;
|
||||||
feature: Feature;
|
feature: Feature;
|
||||||
};
|
};
|
||||||
|
|
||||||
const systemSelector = createSelector(
|
const guidePopoverSelector = createSelector(
|
||||||
(state: RootState) => state.system,
|
systemSelector,
|
||||||
(system: SystemState) => system.shouldDisplayGuides
|
(system: SystemState) => system.shouldDisplayGuides
|
||||||
);
|
);
|
||||||
|
|
||||||
const GuidePopover = ({ children, feature }: GuideProps) => {
|
const GuidePopover = ({ children, feature }: GuideProps) => {
|
||||||
const shouldDisplayGuides = useAppSelector(systemSelector);
|
const shouldDisplayGuides = useAppSelector(guidePopoverSelector);
|
||||||
const { text } = useFeatureHelpInfo(feature);
|
const { text } = useFeatureHelpInfo(feature);
|
||||||
|
|
||||||
if (!shouldDisplayGuides) return null;
|
if (!shouldDisplayGuides) return null;
|
||||||
|
@ -9,8 +9,8 @@ import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
|||||||
import { FileRejection, useDropzone } from 'react-dropzone';
|
import { FileRejection, useDropzone } from 'react-dropzone';
|
||||||
import { useToast } from '@chakra-ui/react';
|
import { useToast } from '@chakra-ui/react';
|
||||||
import { ImageUploaderTriggerContext } from 'app/contexts/ImageUploaderTriggerContext';
|
import { ImageUploaderTriggerContext } from 'app/contexts/ImageUploaderTriggerContext';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { tabDict } from 'features/tabs/components/InvokeTabs';
|
import { tabDict } from 'features/ui/components/InvokeTabs';
|
||||||
import ImageUploadOverlay from './ImageUploadOverlay';
|
import ImageUploadOverlay from './ImageUploadOverlay';
|
||||||
import { uploadImage } from 'features/gallery/store/thunks/uploadImage';
|
import { uploadImage } from 'features/gallery/store/thunks/uploadImage';
|
||||||
import useImageUploader from 'common/hooks/useImageUploader';
|
import useImageUploader from 'common/hooks/useImageUploader';
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
|
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
|
||||||
import { OptionsState } from 'features/options/store/optionsSlice';
|
import { GenerationState } from 'features/parameters/store/generationSlice';
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
import { SystemState } from 'features/system/store/systemSlice';
|
||||||
import { Vector2d } from 'konva/lib/types';
|
import { Vector2d } from 'konva/lib/types';
|
||||||
import { Dimensions } from 'features/canvas/store/canvasTypes';
|
import { Dimensions } from 'features/canvas/store/canvasTypes';
|
||||||
|
|
||||||
import { stringToSeedWeightsArray } from './seedWeightPairs';
|
import { stringToSeedWeightsArray } from './seedWeightPairs';
|
||||||
import randomInt from './randomInt';
|
import randomInt from './randomInt';
|
||||||
import { InvokeTabName } from 'features/tabs/tabMap';
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import {
|
import {
|
||||||
CanvasState,
|
CanvasState,
|
||||||
isCanvasMaskLine,
|
isCanvasMaskLine,
|
||||||
@ -17,11 +17,13 @@ import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
|||||||
import type {
|
import type {
|
||||||
UpscalingLevel,
|
UpscalingLevel,
|
||||||
FacetoolType,
|
FacetoolType,
|
||||||
} from 'features/options/store/optionsSlice';
|
} from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import { PostprocessingState } from 'features/parameters/store/postprocessingSlice';
|
||||||
|
|
||||||
export type FrontendToBackendParametersConfig = {
|
export type FrontendToBackendParametersConfig = {
|
||||||
generationMode: InvokeTabName;
|
generationMode: InvokeTabName;
|
||||||
optionsState: OptionsState;
|
generationState: GenerationState;
|
||||||
|
postprocessingState: PostprocessingState;
|
||||||
canvasState: CanvasState;
|
canvasState: CanvasState;
|
||||||
systemState: SystemState;
|
systemState: SystemState;
|
||||||
imageToProcessUrl?: string;
|
imageToProcessUrl?: string;
|
||||||
@ -91,16 +93,31 @@ export const frontendToBackendParameters = (
|
|||||||
): BackendParameters => {
|
): BackendParameters => {
|
||||||
const canvasBaseLayer = getCanvasBaseLayer();
|
const canvasBaseLayer = getCanvasBaseLayer();
|
||||||
|
|
||||||
const { generationMode, optionsState, canvasState, systemState } = config;
|
const {
|
||||||
|
generationMode,
|
||||||
|
generationState,
|
||||||
|
postprocessingState,
|
||||||
|
canvasState,
|
||||||
|
systemState,
|
||||||
|
} = config;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
cfgScale,
|
|
||||||
codeformerFidelity,
|
codeformerFidelity,
|
||||||
facetoolStrength,
|
facetoolStrength,
|
||||||
facetoolType,
|
facetoolType,
|
||||||
height,
|
|
||||||
hiresFix,
|
hiresFix,
|
||||||
hiresStrength,
|
hiresStrength,
|
||||||
|
shouldRunESRGAN,
|
||||||
|
shouldRunFacetool,
|
||||||
|
upscalingLevel,
|
||||||
|
upscalingStrength,
|
||||||
|
} = postprocessingState;
|
||||||
|
|
||||||
|
const {
|
||||||
|
cfgScale,
|
||||||
|
|
||||||
|
height,
|
||||||
|
|
||||||
img2imgStrength,
|
img2imgStrength,
|
||||||
infillMethod,
|
infillMethod,
|
||||||
initialImage,
|
initialImage,
|
||||||
@ -119,16 +136,14 @@ export const frontendToBackendParameters = (
|
|||||||
shouldFitToWidthHeight,
|
shouldFitToWidthHeight,
|
||||||
shouldGenerateVariations,
|
shouldGenerateVariations,
|
||||||
shouldRandomizeSeed,
|
shouldRandomizeSeed,
|
||||||
shouldRunESRGAN,
|
|
||||||
shouldRunFacetool,
|
|
||||||
steps,
|
steps,
|
||||||
threshold,
|
threshold,
|
||||||
tileSize,
|
tileSize,
|
||||||
upscalingLevel,
|
|
||||||
upscalingStrength,
|
|
||||||
variationAmount,
|
variationAmount,
|
||||||
width,
|
width,
|
||||||
} = optionsState;
|
} = generationState;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
shouldDisplayInProgressType,
|
shouldDisplayInProgressType,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Spinner } from '@chakra-ui/react';
|
import { Spinner } from '@chakra-ui/react';
|
||||||
import { useLayoutEffect, useRef } from 'react';
|
import { useLayoutEffect, useRef } from 'react';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import {
|
import {
|
||||||
resizeAndScaleCanvas,
|
resizeAndScaleCanvas,
|
||||||
resizeCanvas,
|
resizeCanvas,
|
||||||
|
@ -3,7 +3,7 @@ import { useHotkeys } from 'react-hotkeys-hook';
|
|||||||
import { FaRedo } from 'react-icons/fa';
|
import { FaRedo } from 'react-icons/fa';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
@ -6,7 +6,7 @@ import IAIIconButton from 'common/components/IAIIconButton';
|
|||||||
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { undo } from 'features/canvas/store/canvasSlice';
|
import { undo } from 'features/canvas/store/canvasSlice';
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import {
|
import {
|
||||||
clearMask,
|
clearMask,
|
||||||
resetCanvasInteractionState,
|
resetCanvasInteractionState,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import Konva from 'konva';
|
import Konva from 'konva';
|
||||||
import { KonvaEventObject } from 'konva/lib/Node';
|
import { KonvaEventObject } from 'konva/lib/Node';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import Konva from 'konva';
|
import Konva from 'konva';
|
||||||
import { Vector2d } from 'konva/lib/types';
|
import { Vector2d } from 'konva/lib/types';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import Konva from 'konva';
|
import Konva from 'konva';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { MutableRefObject, useCallback } from 'react';
|
import { MutableRefObject, useCallback } from 'react';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
import { CanvasImage, CanvasState, isCanvasBaseImage } from './canvasTypes';
|
import { CanvasImage, CanvasState, isCanvasBaseImage } from './canvasTypes';
|
||||||
|
|
||||||
|
@ -1,28 +1,42 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
|
|
||||||
|
import { ButtonGroup, Link, useToast } from '@chakra-ui/react';
|
||||||
|
import { runESRGAN, runFacetool } from 'app/socketio/actions';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import { RootState } from 'app/store';
|
import IAIButton from 'common/components/IAIButton';
|
||||||
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
|
import IAIPopover from 'common/components/IAIPopover';
|
||||||
|
import { getPromptAndNegative } from 'common/util/getPromptAndNegative';
|
||||||
|
import {
|
||||||
|
setDoesCanvasNeedScaling,
|
||||||
|
setInitialCanvasImage,
|
||||||
|
} from 'features/canvas/store/canvasSlice';
|
||||||
|
import { GalleryState } from 'features/gallery/store/gallerySlice';
|
||||||
|
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
|
||||||
|
import { setIsLightboxOpen } from 'features/lightbox/store/lightboxSlice';
|
||||||
|
import FaceRestoreSettings from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreSettings';
|
||||||
|
import UpscaleSettings from 'features/parameters/components/AdvancedParameters/Upscale/UpscaleSettings';
|
||||||
import {
|
import {
|
||||||
OptionsState,
|
|
||||||
setActiveTab,
|
|
||||||
setAllParameters,
|
setAllParameters,
|
||||||
setInitialImage,
|
setInitialImage,
|
||||||
setIsLightBoxOpen,
|
|
||||||
setNegativePrompt,
|
setNegativePrompt,
|
||||||
setPrompt,
|
setPrompt,
|
||||||
setSeed,
|
setSeed,
|
||||||
setShouldShowImageDetails,
|
} from 'features/parameters/store/generationSlice';
|
||||||
} from 'features/options/store/optionsSlice';
|
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||||
import DeleteImageModal from './DeleteImageModal';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
import { SystemState } from 'features/system/store/systemSlice';
|
||||||
import IAIButton from 'common/components/IAIButton';
|
import {
|
||||||
import { runESRGAN, runFacetool } from 'app/socketio/actions';
|
activeTabNameSelector,
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
uiSelector,
|
||||||
import UpscaleOptions from 'features/options/components/AdvancedOptions/Upscale/UpscaleOptions';
|
} from 'features/ui/store/uiSelectors';
|
||||||
import FaceRestoreOptions from 'features/options/components/AdvancedOptions/FaceRestore/FaceRestoreOptions';
|
import {
|
||||||
|
setActiveTab,
|
||||||
|
setShouldShowImageDetails,
|
||||||
|
} from 'features/ui/store/uiSlice';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { ButtonGroup, Link, useToast } from '@chakra-ui/react';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
FaAsterisk,
|
FaAsterisk,
|
||||||
FaCode,
|
FaCode,
|
||||||
@ -37,38 +51,34 @@ import {
|
|||||||
FaShareAlt,
|
FaShareAlt,
|
||||||
FaTrash,
|
FaTrash,
|
||||||
} from 'react-icons/fa';
|
} from 'react-icons/fa';
|
||||||
import {
|
import { gallerySelector } from '../store/gallerySelectors';
|
||||||
setDoesCanvasNeedScaling,
|
import DeleteImageModal from './DeleteImageModal';
|
||||||
setInitialCanvasImage,
|
|
||||||
} from 'features/canvas/store/canvasSlice';
|
|
||||||
import { GalleryState } from 'features/gallery/store/gallerySlice';
|
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
|
||||||
import IAIPopover from 'common/components/IAIPopover';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { getPromptAndNegative } from 'common/util/getPromptAndNegative';
|
|
||||||
|
|
||||||
const systemSelector = createSelector(
|
const currentImageButtonsSelector = createSelector(
|
||||||
[
|
[
|
||||||
(state: RootState) => state.system,
|
systemSelector,
|
||||||
(state: RootState) => state.options,
|
gallerySelector,
|
||||||
(state: RootState) => state.gallery,
|
postprocessingSelector,
|
||||||
|
uiSelector,
|
||||||
|
lightboxSelector,
|
||||||
activeTabNameSelector,
|
activeTabNameSelector,
|
||||||
],
|
],
|
||||||
(
|
(
|
||||||
system: SystemState,
|
system: SystemState,
|
||||||
options: OptionsState,
|
|
||||||
gallery: GalleryState,
|
gallery: GalleryState,
|
||||||
|
postprocessing,
|
||||||
|
ui,
|
||||||
|
lightbox,
|
||||||
activeTabName
|
activeTabName
|
||||||
) => {
|
) => {
|
||||||
const { isProcessing, isConnected, isGFPGANAvailable, isESRGANAvailable } =
|
const { isProcessing, isConnected, isGFPGANAvailable, isESRGANAvailable } =
|
||||||
system;
|
system;
|
||||||
|
|
||||||
const {
|
const { upscalingLevel, facetoolStrength } = postprocessing;
|
||||||
upscalingLevel,
|
|
||||||
facetoolStrength,
|
const { isLightboxOpen } = lightbox;
|
||||||
shouldShowImageDetails,
|
|
||||||
isLightBoxOpen,
|
const { shouldShowImageDetails } = ui;
|
||||||
} = options;
|
|
||||||
|
|
||||||
const { intermediateImage, currentImage } = gallery;
|
const { intermediateImage, currentImage } = gallery;
|
||||||
|
|
||||||
@ -83,7 +93,7 @@ const systemSelector = createSelector(
|
|||||||
currentImage,
|
currentImage,
|
||||||
shouldShowImageDetails,
|
shouldShowImageDetails,
|
||||||
activeTabName,
|
activeTabName,
|
||||||
isLightBoxOpen,
|
isLightboxOpen,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -109,36 +119,20 @@ const CurrentImageButtons = () => {
|
|||||||
shouldDisableToolbarButtons,
|
shouldDisableToolbarButtons,
|
||||||
shouldShowImageDetails,
|
shouldShowImageDetails,
|
||||||
currentImage,
|
currentImage,
|
||||||
isLightBoxOpen,
|
isLightboxOpen,
|
||||||
activeTabName,
|
activeTabName,
|
||||||
} = useAppSelector(systemSelector);
|
} = useAppSelector(currentImageButtonsSelector);
|
||||||
|
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleClickUseAsInitialImage = () => {
|
const handleClickUseAsInitialImage = () => {
|
||||||
if (!currentImage) return;
|
if (!currentImage) return;
|
||||||
if (isLightBoxOpen) dispatch(setIsLightBoxOpen(false));
|
if (isLightboxOpen) dispatch(setIsLightboxOpen(false));
|
||||||
dispatch(setInitialImage(currentImage));
|
dispatch(setInitialImage(currentImage));
|
||||||
dispatch(setActiveTab('img2img'));
|
dispatch(setActiveTab('img2img'));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCopyImage = async () => {
|
|
||||||
if (!currentImage) return;
|
|
||||||
|
|
||||||
const blob = await fetch(currentImage.url).then((res) => res.blob());
|
|
||||||
const data = [new ClipboardItem({ [blob.type]: blob })];
|
|
||||||
|
|
||||||
await navigator.clipboard.write(data);
|
|
||||||
|
|
||||||
toast({
|
|
||||||
title: t('toast:imageCopied'),
|
|
||||||
status: 'success',
|
|
||||||
duration: 2500,
|
|
||||||
isClosable: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCopyImageLink = () => {
|
const handleCopyImageLink = () => {
|
||||||
navigator.clipboard
|
navigator.clipboard
|
||||||
.writeText(
|
.writeText(
|
||||||
@ -353,7 +347,7 @@ const CurrentImageButtons = () => {
|
|||||||
|
|
||||||
const handleSendToCanvas = () => {
|
const handleSendToCanvas = () => {
|
||||||
if (!currentImage) return;
|
if (!currentImage) return;
|
||||||
if (isLightBoxOpen) dispatch(setIsLightBoxOpen(false));
|
if (isLightboxOpen) dispatch(setIsLightboxOpen(false));
|
||||||
|
|
||||||
dispatch(setInitialCanvasImage(currentImage));
|
dispatch(setInitialCanvasImage(currentImage));
|
||||||
dispatch(setDoesCanvasNeedScaling(true));
|
dispatch(setDoesCanvasNeedScaling(true));
|
||||||
@ -388,7 +382,7 @@ const CurrentImageButtons = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleLightBox = () => {
|
const handleLightBox = () => {
|
||||||
dispatch(setIsLightBoxOpen(!isLightBoxOpen));
|
dispatch(setIsLightboxOpen(!isLightboxOpen));
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -398,7 +392,7 @@ const CurrentImageButtons = () => {
|
|||||||
trigger="hover"
|
trigger="hover"
|
||||||
triggerComponent={
|
triggerComponent={
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
aria-label={`${t('options:sendTo')}...`}
|
aria-label={`${t('parameters:sendTo')}...`}
|
||||||
icon={<FaShareAlt />}
|
icon={<FaShareAlt />}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@ -409,34 +403,26 @@ const CurrentImageButtons = () => {
|
|||||||
onClick={handleClickUseAsInitialImage}
|
onClick={handleClickUseAsInitialImage}
|
||||||
leftIcon={<FaShare />}
|
leftIcon={<FaShare />}
|
||||||
>
|
>
|
||||||
{t('options:sendToImg2Img')}
|
{t('parameters:sendToImg2Img')}
|
||||||
</IAIButton>
|
</IAIButton>
|
||||||
<IAIButton
|
<IAIButton
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
onClick={handleSendToCanvas}
|
onClick={handleSendToCanvas}
|
||||||
leftIcon={<FaShare />}
|
leftIcon={<FaShare />}
|
||||||
>
|
>
|
||||||
{t('options:sendToUnifiedCanvas')}
|
{t('parameters:sendToUnifiedCanvas')}
|
||||||
</IAIButton>
|
|
||||||
|
|
||||||
<IAIButton
|
|
||||||
size={'sm'}
|
|
||||||
onClick={handleCopyImage}
|
|
||||||
leftIcon={<FaCopy />}
|
|
||||||
>
|
|
||||||
{t('options:copyImage')}
|
|
||||||
</IAIButton>
|
</IAIButton>
|
||||||
<IAIButton
|
<IAIButton
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
onClick={handleCopyImageLink}
|
onClick={handleCopyImageLink}
|
||||||
leftIcon={<FaCopy />}
|
leftIcon={<FaCopy />}
|
||||||
>
|
>
|
||||||
{t('options:copyImageToLink')}
|
{t('parameters:copyImageToLink')}
|
||||||
</IAIButton>
|
</IAIButton>
|
||||||
|
|
||||||
<Link download={true} href={currentImage?.url}>
|
<Link download={true} href={currentImage?.url}>
|
||||||
<IAIButton leftIcon={<FaDownload />} size={'sm'} w="100%">
|
<IAIButton leftIcon={<FaDownload />} size={'sm'} w="100%">
|
||||||
{t('options:downloadImage')}
|
{t('parameters:downloadImage')}
|
||||||
</IAIButton>
|
</IAIButton>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@ -444,16 +430,16 @@ const CurrentImageButtons = () => {
|
|||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
icon={<FaExpand />}
|
icon={<FaExpand />}
|
||||||
tooltip={
|
tooltip={
|
||||||
!isLightBoxOpen
|
!isLightboxOpen
|
||||||
? `${t('options:openInViewer')} (Z)`
|
? `${t('parameters:openInViewer')} (Z)`
|
||||||
: `${t('options:closeViewer')} (Z)`
|
: `${t('parameters:closeViewer')} (Z)`
|
||||||
}
|
}
|
||||||
aria-label={
|
aria-label={
|
||||||
!isLightBoxOpen
|
!isLightboxOpen
|
||||||
? `${t('options:openInViewer')} (Z)`
|
? `${t('parameters:openInViewer')} (Z)`
|
||||||
: `${t('options:closeViewer')} (Z)`
|
: `${t('parameters:closeViewer')} (Z)`
|
||||||
}
|
}
|
||||||
data-selected={isLightBoxOpen}
|
data-selected={isLightboxOpen}
|
||||||
onClick={handleLightBox}
|
onClick={handleLightBox}
|
||||||
/>
|
/>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
@ -461,24 +447,24 @@ const CurrentImageButtons = () => {
|
|||||||
<ButtonGroup isAttached={true}>
|
<ButtonGroup isAttached={true}>
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
icon={<FaQuoteRight />}
|
icon={<FaQuoteRight />}
|
||||||
tooltip={`${t('options:usePrompt')} (P)`}
|
tooltip={`${t('parameters:usePrompt')} (P)`}
|
||||||
aria-label={`${t('options:usePrompt')} (P)`}
|
aria-label={`${t('parameters:usePrompt')} (P)`}
|
||||||
isDisabled={!currentImage?.metadata?.image?.prompt}
|
isDisabled={!currentImage?.metadata?.image?.prompt}
|
||||||
onClick={handleClickUsePrompt}
|
onClick={handleClickUsePrompt}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
icon={<FaSeedling />}
|
icon={<FaSeedling />}
|
||||||
tooltip={`${t('options:useSeed')} (S)`}
|
tooltip={`${t('parameters:useSeed')} (S)`}
|
||||||
aria-label={`${t('options:useSeed')} (S)`}
|
aria-label={`${t('parameters:useSeed')} (S)`}
|
||||||
isDisabled={!currentImage?.metadata?.image?.seed}
|
isDisabled={!currentImage?.metadata?.image?.seed}
|
||||||
onClick={handleClickUseSeed}
|
onClick={handleClickUseSeed}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
icon={<FaAsterisk />}
|
icon={<FaAsterisk />}
|
||||||
tooltip={`${t('options:useAll')} (A)`}
|
tooltip={`${t('parameters:useAll')} (A)`}
|
||||||
aria-label={`${t('options:useAll')} (A)`}
|
aria-label={`${t('parameters:useAll')} (A)`}
|
||||||
isDisabled={
|
isDisabled={
|
||||||
!['txt2img', 'img2img'].includes(
|
!['txt2img', 'img2img'].includes(
|
||||||
currentImage?.metadata?.image?.type
|
currentImage?.metadata?.image?.type
|
||||||
@ -494,12 +480,12 @@ const CurrentImageButtons = () => {
|
|||||||
triggerComponent={
|
triggerComponent={
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
icon={<FaGrinStars />}
|
icon={<FaGrinStars />}
|
||||||
aria-label={t('options:restoreFaces')}
|
aria-label={t('parameters:restoreFaces')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="current-image-postprocessing-popover">
|
<div className="current-image-postprocessing-popover">
|
||||||
<FaceRestoreOptions />
|
<FaceRestoreSettings />
|
||||||
<IAIButton
|
<IAIButton
|
||||||
isDisabled={
|
isDisabled={
|
||||||
!isGFPGANAvailable ||
|
!isGFPGANAvailable ||
|
||||||
@ -509,7 +495,7 @@ const CurrentImageButtons = () => {
|
|||||||
}
|
}
|
||||||
onClick={handleClickFixFaces}
|
onClick={handleClickFixFaces}
|
||||||
>
|
>
|
||||||
{t('options:restoreFaces')}
|
{t('parameters:restoreFaces')}
|
||||||
</IAIButton>
|
</IAIButton>
|
||||||
</div>
|
</div>
|
||||||
</IAIPopover>
|
</IAIPopover>
|
||||||
@ -519,12 +505,12 @@ const CurrentImageButtons = () => {
|
|||||||
triggerComponent={
|
triggerComponent={
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
icon={<FaExpandArrowsAlt />}
|
icon={<FaExpandArrowsAlt />}
|
||||||
aria-label={t('options:upscale')}
|
aria-label={t('parameters:upscale')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="current-image-postprocessing-popover">
|
<div className="current-image-postprocessing-popover">
|
||||||
<UpscaleOptions />
|
<UpscaleSettings />
|
||||||
<IAIButton
|
<IAIButton
|
||||||
isDisabled={
|
isDisabled={
|
||||||
!isESRGANAvailable ||
|
!isESRGANAvailable ||
|
||||||
@ -534,7 +520,7 @@ const CurrentImageButtons = () => {
|
|||||||
}
|
}
|
||||||
onClick={handleClickUpscale}
|
onClick={handleClickUpscale}
|
||||||
>
|
>
|
||||||
{t('options:upscaleImage')}
|
{t('parameters:upscaleImage')}
|
||||||
</IAIButton>
|
</IAIButton>
|
||||||
</div>
|
</div>
|
||||||
</IAIPopover>
|
</IAIPopover>
|
||||||
@ -543,8 +529,8 @@ const CurrentImageButtons = () => {
|
|||||||
<ButtonGroup isAttached={true}>
|
<ButtonGroup isAttached={true}>
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
icon={<FaCode />}
|
icon={<FaCode />}
|
||||||
tooltip={`${t('options:info')} (I)`}
|
tooltip={`${t('parameters:info')} (I)`}
|
||||||
aria-label={`${t('options:info')} (I)`}
|
aria-label={`${t('parameters:info')} (I)`}
|
||||||
data-selected={shouldShowImageDetails}
|
data-selected={shouldShowImageDetails}
|
||||||
onClick={handleClickShowImageDetails}
|
onClick={handleClickShowImageDetails}
|
||||||
/>
|
/>
|
||||||
@ -553,8 +539,8 @@ const CurrentImageButtons = () => {
|
|||||||
<DeleteImageModal image={currentImage}>
|
<DeleteImageModal image={currentImage}>
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
icon={<FaTrash />}
|
icon={<FaTrash />}
|
||||||
tooltip={`${t('options:deleteImage')} (Del)`}
|
tooltip={`${t('parameters:deleteImage')} (Del)`}
|
||||||
aria-label={`${t('options:deleteImage')} (Del)`}
|
aria-label={`${t('parameters:deleteImage')} (Del)`}
|
||||||
isDisabled={!currentImage || !isConnected || isProcessing}
|
isDisabled={!currentImage || !isConnected || isProcessing}
|
||||||
style={{ backgroundColor: 'var(--btn-delete-image)' }}
|
style={{ backgroundColor: 'var(--btn-delete-image)' }}
|
||||||
/>
|
/>
|
||||||
|
@ -1,23 +1,21 @@
|
|||||||
import { RootState } from 'app/store';
|
|
||||||
import { useAppSelector } from 'app/storeHooks';
|
import { useAppSelector } from 'app/storeHooks';
|
||||||
import CurrentImageButtons from './CurrentImageButtons';
|
import CurrentImageButtons from './CurrentImageButtons';
|
||||||
import { MdPhoto } from 'react-icons/md';
|
import { MdPhoto } from 'react-icons/md';
|
||||||
import CurrentImagePreview from './CurrentImagePreview';
|
import CurrentImagePreview from './CurrentImagePreview';
|
||||||
import { GalleryState } from 'features/gallery/store/gallerySlice';
|
import { GalleryState } from 'features/gallery/store/gallerySlice';
|
||||||
import { OptionsState } from 'features/options/store/optionsSlice';
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import {
|
||||||
|
activeTabNameSelector,
|
||||||
|
uiSelector,
|
||||||
|
} from 'features/ui/store/uiSelectors';
|
||||||
|
import { gallerySelector } from '../store/gallerySelectors';
|
||||||
|
|
||||||
export const currentImageDisplaySelector = createSelector(
|
export const currentImageDisplaySelector = createSelector(
|
||||||
[
|
[gallerySelector, uiSelector, activeTabNameSelector],
|
||||||
(state: RootState) => state.gallery,
|
(gallery: GalleryState, ui, activeTabName) => {
|
||||||
(state: RootState) => state.options,
|
|
||||||
activeTabNameSelector,
|
|
||||||
],
|
|
||||||
(gallery: GalleryState, options: OptionsState, activeTabName) => {
|
|
||||||
const { currentImage, intermediateImage } = gallery;
|
const { currentImage, intermediateImage } = gallery;
|
||||||
const { shouldShowImageDetails } = options;
|
const { shouldShowImageDetails } = ui;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
activeTabName,
|
activeTabName,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { IconButton, Image } from '@chakra-ui/react';
|
import { IconButton, Image } from '@chakra-ui/react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';
|
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import {
|
import {
|
||||||
GalleryCategory,
|
GalleryCategory,
|
||||||
@ -11,14 +10,15 @@ import {
|
|||||||
} from 'features/gallery/store/gallerySlice';
|
} from 'features/gallery/store/gallerySlice';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { OptionsState } from 'features/options/store/optionsSlice';
|
|
||||||
import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer';
|
import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer';
|
||||||
|
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||||
|
import { gallerySelector } from '../store/gallerySelectors';
|
||||||
|
|
||||||
export const imagesSelector = createSelector(
|
export const imagesSelector = createSelector(
|
||||||
[(state: RootState) => state.gallery, (state: RootState) => state.options],
|
[gallerySelector, uiSelector],
|
||||||
(gallery: GalleryState, options: OptionsState) => {
|
(gallery: GalleryState, ui) => {
|
||||||
const { currentCategory, currentImage, intermediateImage } = gallery;
|
const { currentCategory, currentImage, intermediateImage } = gallery;
|
||||||
const { shouldShowImageDetails } = options;
|
const { shouldShowImageDetails } = ui;
|
||||||
|
|
||||||
const tempImages =
|
const tempImages =
|
||||||
gallery.categories[
|
gallery.categories[
|
||||||
|
@ -18,7 +18,6 @@ import { ChangeEvent, ReactElement, SyntheticEvent } from 'react';
|
|||||||
import { cloneElement, forwardRef, useRef } from 'react';
|
import { cloneElement, forwardRef, useRef } from 'react';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import { deleteImage } from 'app/socketio/actions';
|
import { deleteImage } from 'app/socketio/actions';
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import {
|
import {
|
||||||
setShouldConfirmOnDelete,
|
setShouldConfirmOnDelete,
|
||||||
SystemState,
|
SystemState,
|
||||||
@ -26,9 +25,10 @@ import {
|
|||||||
import * as InvokeAI from 'app/invokeai';
|
import * as InvokeAI from 'app/invokeai';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
|
||||||
const systemSelector = createSelector(
|
const deleteImageModalSelector = createSelector(
|
||||||
(state: RootState) => state.system,
|
systemSelector,
|
||||||
(system: SystemState) => {
|
(system: SystemState) => {
|
||||||
const { shouldConfirmOnDelete, isConnected, isProcessing } = system;
|
const { shouldConfirmOnDelete, isConnected, isProcessing } = system;
|
||||||
return { shouldConfirmOnDelete, isConnected, isProcessing };
|
return { shouldConfirmOnDelete, isConnected, isProcessing };
|
||||||
@ -60,8 +60,9 @@ const DeleteImageModal = forwardRef(
|
|||||||
({ image, children }: DeleteImageModalProps, ref) => {
|
({ image, children }: DeleteImageModalProps, ref) => {
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { shouldConfirmOnDelete, isConnected, isProcessing } =
|
const { shouldConfirmOnDelete, isConnected, isProcessing } = useAppSelector(
|
||||||
useAppSelector(systemSelector);
|
deleteImageModalSelector
|
||||||
|
);
|
||||||
const cancelRef = useRef<HTMLButtonElement>(null);
|
const cancelRef = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
const handleClickDelete = (e: SyntheticEvent) => {
|
const handleClickDelete = (e: SyntheticEvent) => {
|
||||||
|
@ -4,28 +4,28 @@ import {
|
|||||||
setCurrentImage,
|
setCurrentImage,
|
||||||
setShouldHoldGalleryOpen,
|
setShouldHoldGalleryOpen,
|
||||||
} from 'features/gallery/store/gallerySlice';
|
} from 'features/gallery/store/gallerySlice';
|
||||||
import { FaCheck, FaTrashAlt } from 'react-icons/fa';
|
|
||||||
import DeleteImageModal from './DeleteImageModal';
|
|
||||||
import { DragEvent, memo, useState } from 'react';
|
|
||||||
import {
|
import {
|
||||||
setActiveTab,
|
|
||||||
setAllImageToImageParameters,
|
setAllImageToImageParameters,
|
||||||
setAllParameters,
|
setAllParameters,
|
||||||
setInitialImage,
|
setInitialImage,
|
||||||
setIsLightBoxOpen,
|
|
||||||
setNegativePrompt,
|
setNegativePrompt,
|
||||||
setPrompt,
|
setPrompt,
|
||||||
setSeed,
|
setSeed,
|
||||||
} from 'features/options/store/optionsSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
import * as InvokeAI from 'app/invokeai';
|
import { DragEvent, memo, useState } from 'react';
|
||||||
|
import { FaCheck, FaTrashAlt } from 'react-icons/fa';
|
||||||
|
import DeleteImageModal from './DeleteImageModal';
|
||||||
|
|
||||||
import * as ContextMenu from '@radix-ui/react-context-menu';
|
import * as ContextMenu from '@radix-ui/react-context-menu';
|
||||||
|
import * as InvokeAI from 'app/invokeai';
|
||||||
|
import { getPromptAndNegative } from 'common/util/getPromptAndNegative';
|
||||||
import {
|
import {
|
||||||
resizeAndScaleCanvas,
|
resizeAndScaleCanvas,
|
||||||
setInitialCanvasImage,
|
setInitialCanvasImage,
|
||||||
} from 'features/canvas/store/canvasSlice';
|
} from 'features/canvas/store/canvasSlice';
|
||||||
import { hoverableImageSelector } from 'features/gallery/store/gallerySliceSelectors';
|
import { hoverableImageSelector } from 'features/gallery/store/gallerySelectors';
|
||||||
|
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { getPromptAndNegative } from 'common/util/getPromptAndNegative';
|
|
||||||
|
|
||||||
interface HoverableImageProps {
|
interface HoverableImageProps {
|
||||||
image: InvokeAI.Image;
|
image: InvokeAI.Image;
|
||||||
@ -47,7 +47,6 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
|||||||
galleryImageObjectFit,
|
galleryImageObjectFit,
|
||||||
galleryImageMinimumWidth,
|
galleryImageMinimumWidth,
|
||||||
mayDeleteImage,
|
mayDeleteImage,
|
||||||
isLightBoxOpen,
|
|
||||||
shouldUseSingleGalleryColumn,
|
shouldUseSingleGalleryColumn,
|
||||||
} = useAppSelector(hoverableImageSelector);
|
} = useAppSelector(hoverableImageSelector);
|
||||||
const { image, isSelected } = props;
|
const { image, isSelected } = props;
|
||||||
@ -94,7 +93,6 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSendToImageToImage = () => {
|
const handleSendToImageToImage = () => {
|
||||||
if (isLightBoxOpen) dispatch(setIsLightBoxOpen(false));
|
|
||||||
dispatch(setInitialImage(image));
|
dispatch(setInitialImage(image));
|
||||||
if (activeTabName !== 'img2img') {
|
if (activeTabName !== 'img2img') {
|
||||||
dispatch(setActiveTab('img2img'));
|
dispatch(setActiveTab('img2img'));
|
||||||
@ -108,8 +106,6 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSendToCanvas = () => {
|
const handleSendToCanvas = () => {
|
||||||
if (isLightBoxOpen) dispatch(setIsLightBoxOpen(false));
|
|
||||||
|
|
||||||
dispatch(setInitialCanvasImage(image));
|
dispatch(setInitialCanvasImage(image));
|
||||||
|
|
||||||
dispatch(resizeAndScaleCanvas());
|
dispatch(resizeAndScaleCanvas());
|
||||||
@ -168,7 +164,6 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleLightBox = () => {
|
const handleLightBox = () => {
|
||||||
dispatch(setIsLightBoxOpen(true));
|
|
||||||
dispatch(setCurrentImage(image));
|
dispatch(setCurrentImage(image));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -212,7 +207,7 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
|||||||
<div className="hoverable-image-delete-button">
|
<div className="hoverable-image-delete-button">
|
||||||
<DeleteImageModal image={image}>
|
<DeleteImageModal image={image}>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label={t('options:deleteImage')}
|
aria-label={t('parameters:deleteImage')}
|
||||||
icon={<FaTrashAlt />}
|
icon={<FaTrashAlt />}
|
||||||
size="xs"
|
size="xs"
|
||||||
variant={'imageHoverIconButton'}
|
variant={'imageHoverIconButton'}
|
||||||
@ -232,20 +227,20 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ContextMenu.Item onClickCapture={handleLightBox}>
|
<ContextMenu.Item onClickCapture={handleLightBox}>
|
||||||
{t('options:openInViewer')}
|
{t('parameters:openInViewer')}
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
<ContextMenu.Item
|
<ContextMenu.Item
|
||||||
onClickCapture={handleUsePrompt}
|
onClickCapture={handleUsePrompt}
|
||||||
disabled={image?.metadata?.image?.prompt === undefined}
|
disabled={image?.metadata?.image?.prompt === undefined}
|
||||||
>
|
>
|
||||||
{t('options:usePrompt')}
|
{t('parameters:usePrompt')}
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
|
|
||||||
<ContextMenu.Item
|
<ContextMenu.Item
|
||||||
onClickCapture={handleUseSeed}
|
onClickCapture={handleUseSeed}
|
||||||
disabled={image?.metadata?.image?.seed === undefined}
|
disabled={image?.metadata?.image?.seed === undefined}
|
||||||
>
|
>
|
||||||
{t('options:useSeed')}
|
{t('parameters:useSeed')}
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
<ContextMenu.Item
|
<ContextMenu.Item
|
||||||
onClickCapture={handleUseAllParameters}
|
onClickCapture={handleUseAllParameters}
|
||||||
@ -253,23 +248,23 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
|||||||
!['txt2img', 'img2img'].includes(image?.metadata?.image?.type)
|
!['txt2img', 'img2img'].includes(image?.metadata?.image?.type)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{t('options:useAll')}
|
{t('parameters:useAll')}
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
<ContextMenu.Item
|
<ContextMenu.Item
|
||||||
onClickCapture={handleUseInitialImage}
|
onClickCapture={handleUseInitialImage}
|
||||||
disabled={image?.metadata?.image?.type !== 'img2img'}
|
disabled={image?.metadata?.image?.type !== 'img2img'}
|
||||||
>
|
>
|
||||||
{t('options:useInitImg')}
|
{t('parameters:useInitImg')}
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
<ContextMenu.Item onClickCapture={handleSendToImageToImage}>
|
<ContextMenu.Item onClickCapture={handleSendToImageToImage}>
|
||||||
{t('options:sendToImg2Img')}
|
{t('parameters:sendToImg2Img')}
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
<ContextMenu.Item onClickCapture={handleSendToCanvas}>
|
<ContextMenu.Item onClickCapture={handleSendToCanvas}>
|
||||||
{t('options:sendToUnifiedCanvas')}
|
{t('parameters:sendToUnifiedCanvas')}
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
<ContextMenu.Item data-warning>
|
<ContextMenu.Item data-warning>
|
||||||
<DeleteImageModal image={image}>
|
<DeleteImageModal image={image}>
|
||||||
<p>{t('options:deleteImage')}</p>
|
<p>{t('parameters:deleteImage')}</p>
|
||||||
</DeleteImageModal>
|
</DeleteImageModal>
|
||||||
</ContextMenu.Item>
|
</ContextMenu.Item>
|
||||||
</ContextMenu.Content>
|
</ContextMenu.Content>
|
||||||
|
@ -32,7 +32,7 @@ import { setShouldShowGallery } from 'features/gallery/store/gallerySlice';
|
|||||||
import { ButtonGroup } from '@chakra-ui/react';
|
import { ButtonGroup } from '@chakra-ui/react';
|
||||||
import { CSSTransition } from 'react-transition-group';
|
import { CSSTransition } from 'react-transition-group';
|
||||||
import { Direction } from 're-resizable/lib/resizer';
|
import { Direction } from 're-resizable/lib/resizer';
|
||||||
import { imageGallerySelector } from 'features/gallery/store/gallerySliceSelectors';
|
import { imageGallerySelector } from 'features/gallery/store/gallerySelectors';
|
||||||
import { FaImage, FaUser, FaWrench } from 'react-icons/fa';
|
import { FaImage, FaUser, FaWrench } from 'react-icons/fa';
|
||||||
import IAIPopover from 'common/components/IAIPopover';
|
import IAIPopover from 'common/components/IAIPopover';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
@ -41,7 +41,7 @@ import IAICheckbox from 'common/components/IAICheckbox';
|
|||||||
import { setDoesCanvasNeedScaling } from 'features/canvas/store/canvasSlice';
|
import { setDoesCanvasNeedScaling } from 'features/canvas/store/canvasSlice';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import IAIButton from 'common/components/IAIButton';
|
import IAIButton from 'common/components/IAIButton';
|
||||||
import { InvokeTabName } from 'features/tabs/tabMap';
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const GALLERY_SHOW_BUTTONS_MIN_WIDTH = 320;
|
const GALLERY_SHOW_BUTTONS_MIN_WIDTH = 320;
|
||||||
@ -81,13 +81,13 @@ export default function ImageGallery() {
|
|||||||
shouldAutoSwitchToNewImages,
|
shouldAutoSwitchToNewImages,
|
||||||
areMoreImagesAvailable,
|
areMoreImagesAvailable,
|
||||||
galleryWidth,
|
galleryWidth,
|
||||||
isLightBoxOpen,
|
isLightboxOpen,
|
||||||
isStaging,
|
isStaging,
|
||||||
shouldEnableResize,
|
shouldEnableResize,
|
||||||
shouldUseSingleGalleryColumn,
|
shouldUseSingleGalleryColumn,
|
||||||
} = useAppSelector(imageGallerySelector);
|
} = useAppSelector(imageGallerySelector);
|
||||||
|
|
||||||
const { galleryMinWidth, galleryMaxWidth } = isLightBoxOpen
|
const { galleryMinWidth, galleryMaxWidth } = isLightboxOpen
|
||||||
? {
|
? {
|
||||||
galleryMinWidth: LIGHTBOX_GALLERY_WIDTH,
|
galleryMinWidth: LIGHTBOX_GALLERY_WIDTH,
|
||||||
galleryMaxWidth: LIGHTBOX_GALLERY_WIDTH,
|
galleryMaxWidth: LIGHTBOX_GALLERY_WIDTH,
|
||||||
|
@ -14,11 +14,7 @@ import { useAppDispatch } from 'app/storeHooks';
|
|||||||
import * as InvokeAI from 'app/invokeai';
|
import * as InvokeAI from 'app/invokeai';
|
||||||
import {
|
import {
|
||||||
setCfgScale,
|
setCfgScale,
|
||||||
setFacetoolStrength,
|
|
||||||
setCodeformerFidelity,
|
|
||||||
setFacetoolType,
|
|
||||||
setHeight,
|
setHeight,
|
||||||
setHiresFix,
|
|
||||||
setImg2imgStrength,
|
setImg2imgStrength,
|
||||||
setMaskPath,
|
setMaskPath,
|
||||||
setPrompt,
|
setPrompt,
|
||||||
@ -28,14 +24,20 @@ import {
|
|||||||
setSeedWeights,
|
setSeedWeights,
|
||||||
setShouldFitToWidthHeight,
|
setShouldFitToWidthHeight,
|
||||||
setSteps,
|
setSteps,
|
||||||
setUpscalingLevel,
|
|
||||||
setUpscalingStrength,
|
|
||||||
setWidth,
|
setWidth,
|
||||||
setInitialImage,
|
setInitialImage,
|
||||||
setShouldShowImageDetails,
|
|
||||||
setThreshold,
|
setThreshold,
|
||||||
setPerlin,
|
setPerlin,
|
||||||
} from 'features/options/store/optionsSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
|
import {
|
||||||
|
setFacetoolStrength,
|
||||||
|
setCodeformerFidelity,
|
||||||
|
setFacetoolType,
|
||||||
|
setHiresFix,
|
||||||
|
setUpscalingLevel,
|
||||||
|
setUpscalingStrength,
|
||||||
|
} from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import { setShouldShowImageDetails } from 'features/ui/store/uiSlice';
|
||||||
import promptToString from 'common/util/promptToString';
|
import promptToString from 'common/util/promptToString';
|
||||||
import { seedWeightsToString } from 'common/util/seedWeightPairs';
|
import { seedWeightsToString } from 'common/util/seedWeightPairs';
|
||||||
import { FaCopy } from 'react-icons/fa';
|
import { FaCopy } from 'react-icons/fa';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppSelector } from 'app/storeHooks';
|
import { useAppSelector } from 'app/storeHooks';
|
||||||
import { gallerySelector } from '../store/gallerySliceSelectors';
|
import { gallerySelector } from '../store/gallerySelectors';
|
||||||
|
|
||||||
const selector = createSelector(gallerySelector, (gallery) => ({
|
const selector = createSelector(gallerySelector, (gallery) => ({
|
||||||
resultImages: gallery.categories.result.images,
|
resultImages: gallery.categories.result.images,
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { OptionsState } from 'features/options/store/optionsSlice';
|
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
|
||||||
import { GalleryState } from './gallerySlice';
|
import { GalleryState } from './gallerySlice';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
|
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
|
||||||
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
|
||||||
|
export const gallerySelector = (state: RootState) => state.gallery;
|
||||||
|
|
||||||
export const imageGallerySelector = createSelector(
|
export const imageGallerySelector = createSelector(
|
||||||
[
|
[gallerySelector, lightboxSelector, isStagingSelector, activeTabNameSelector],
|
||||||
(state: RootState) => state.gallery,
|
(gallery: GalleryState, lightbox, isStaging, activeTabName) => {
|
||||||
(state: RootState) => state.options,
|
|
||||||
isStagingSelector,
|
|
||||||
activeTabNameSelector,
|
|
||||||
],
|
|
||||||
(gallery: GalleryState, options: OptionsState, isStaging, activeTabName) => {
|
|
||||||
const {
|
const {
|
||||||
categories,
|
categories,
|
||||||
currentCategory,
|
currentCategory,
|
||||||
@ -30,7 +27,7 @@ export const imageGallerySelector = createSelector(
|
|||||||
shouldUseSingleGalleryColumn,
|
shouldUseSingleGalleryColumn,
|
||||||
} = gallery;
|
} = gallery;
|
||||||
|
|
||||||
const { isLightBoxOpen } = options;
|
const { isLightboxOpen } = lightbox;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentImageUuid,
|
currentImageUuid,
|
||||||
@ -50,10 +47,10 @@ export const imageGallerySelector = createSelector(
|
|||||||
categories[currentCategory].areMoreImagesAvailable,
|
categories[currentCategory].areMoreImagesAvailable,
|
||||||
currentCategory,
|
currentCategory,
|
||||||
galleryWidth,
|
galleryWidth,
|
||||||
isLightBoxOpen,
|
isLightboxOpen,
|
||||||
isStaging,
|
isStaging,
|
||||||
shouldEnableResize:
|
shouldEnableResize:
|
||||||
isLightBoxOpen ||
|
isLightboxOpen ||
|
||||||
(activeTabName === 'unifiedCanvas' && shouldPinGallery)
|
(activeTabName === 'unifiedCanvas' && shouldPinGallery)
|
||||||
? false
|
? false
|
||||||
: true,
|
: true,
|
||||||
@ -68,25 +65,15 @@ export const imageGallerySelector = createSelector(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const hoverableImageSelector = createSelector(
|
export const hoverableImageSelector = createSelector(
|
||||||
[
|
[gallerySelector, systemSelector, lightboxSelector, activeTabNameSelector],
|
||||||
(state: RootState) => state.options,
|
(gallery: GalleryState, system, lightbox, activeTabName) => {
|
||||||
(state: RootState) => state.gallery,
|
|
||||||
(state: RootState) => state.system,
|
|
||||||
activeTabNameSelector,
|
|
||||||
],
|
|
||||||
(
|
|
||||||
options: OptionsState,
|
|
||||||
gallery: GalleryState,
|
|
||||||
system: SystemState,
|
|
||||||
activeTabName
|
|
||||||
) => {
|
|
||||||
return {
|
return {
|
||||||
mayDeleteImage: system.isConnected && !system.isProcessing,
|
mayDeleteImage: system.isConnected && !system.isProcessing,
|
||||||
galleryImageObjectFit: gallery.galleryImageObjectFit,
|
galleryImageObjectFit: gallery.galleryImageObjectFit,
|
||||||
galleryImageMinimumWidth: gallery.galleryImageMinimumWidth,
|
galleryImageMinimumWidth: gallery.galleryImageMinimumWidth,
|
||||||
shouldUseSingleGalleryColumn: gallery.shouldUseSingleGalleryColumn,
|
shouldUseSingleGalleryColumn: gallery.shouldUseSingleGalleryColumn,
|
||||||
activeTabName,
|
activeTabName,
|
||||||
isLightBoxOpen: options.isLightBoxOpen,
|
isLightboxOpen: lightbox.isLightboxOpen,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -95,5 +82,3 @@ export const hoverableImageSelector = createSelector(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const gallerySelector = (state: RootState) => state.gallery;
|
|
@ -3,7 +3,7 @@ import type { PayloadAction } from '@reduxjs/toolkit';
|
|||||||
import _, { clamp } from 'lodash';
|
import _, { clamp } from 'lodash';
|
||||||
import * as InvokeAI from 'app/invokeai';
|
import * as InvokeAI from 'app/invokeai';
|
||||||
import { IRect } from 'konva/lib/types';
|
import { IRect } from 'konva/lib/types';
|
||||||
import { InvokeTabName } from 'features/tabs/tabMap';
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
|
|
||||||
export type GalleryCategory = 'user' | 'result';
|
export type GalleryCategory = 'user' | 'result';
|
||||||
|
|
||||||
@ -241,6 +241,7 @@ export const gallerySlice = createSlice({
|
|||||||
setShouldShowGallery: (state, action: PayloadAction<boolean>) => {
|
setShouldShowGallery: (state, action: PayloadAction<boolean>) => {
|
||||||
state.shouldShowGallery = action.payload;
|
state.shouldShowGallery = action.payload;
|
||||||
},
|
},
|
||||||
|
|
||||||
setGalleryScrollPosition: (state, action: PayloadAction<number>) => {
|
setGalleryScrollPosition: (state, action: PayloadAction<number>) => {
|
||||||
state.galleryScrollPosition = action.payload;
|
state.galleryScrollPosition = action.payload;
|
||||||
},
|
},
|
||||||
|
@ -2,9 +2,9 @@ import { AnyAction, ThunkAction } from '@reduxjs/toolkit';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import * as InvokeAI from 'app/invokeai';
|
import * as InvokeAI from 'app/invokeai';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
||||||
import { setInitialImage } from 'features/options/store/optionsSlice';
|
import { setInitialImage } from 'features/parameters/store/generationSlice';
|
||||||
import { addImage } from '../gallerySlice';
|
import { addImage } from '../gallerySlice';
|
||||||
|
|
||||||
type UploadImageConfig = {
|
type UploadImageConfig = {
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
} from 'features/gallery/store/gallerySlice';
|
} from 'features/gallery/store/gallerySlice';
|
||||||
import ImageGallery from 'features/gallery/components/ImageGallery';
|
import ImageGallery from 'features/gallery/components/ImageGallery';
|
||||||
import ImageMetadataViewer from 'features/gallery/components/ImageMetaDataViewer/ImageMetadataViewer';
|
import ImageMetadataViewer from 'features/gallery/components/ImageMetaDataViewer/ImageMetadataViewer';
|
||||||
import { setIsLightBoxOpen } from 'features/options/store/optionsSlice';
|
import { setIsLightboxOpen } from 'features/lightbox/store/lightboxSlice';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { BiExit } from 'react-icons/bi';
|
import { BiExit } from 'react-icons/bi';
|
||||||
@ -20,7 +20,7 @@ import ReactPanZoom from './ReactPanZoom';
|
|||||||
export default function Lightbox() {
|
export default function Lightbox() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const isLightBoxOpen = useAppSelector(
|
const isLightBoxOpen = useAppSelector(
|
||||||
(state: RootState) => state.options.isLightBoxOpen
|
(state: RootState) => state.lightbox.isLightboxOpen
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -52,7 +52,7 @@ export default function Lightbox() {
|
|||||||
useHotkeys(
|
useHotkeys(
|
||||||
'Esc',
|
'Esc',
|
||||||
() => {
|
() => {
|
||||||
if (isLightBoxOpen) dispatch(setIsLightBoxOpen(false));
|
if (isLightBoxOpen) dispatch(setIsLightboxOpen(false));
|
||||||
},
|
},
|
||||||
[isLightBoxOpen]
|
[isLightBoxOpen]
|
||||||
);
|
);
|
||||||
@ -64,7 +64,7 @@ export default function Lightbox() {
|
|||||||
aria-label="Exit Viewer"
|
aria-label="Exit Viewer"
|
||||||
className="lightbox-close-btn"
|
className="lightbox-close-btn"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
dispatch(setIsLightBoxOpen(false));
|
dispatch(setIsLightboxOpen(false));
|
||||||
}}
|
}}
|
||||||
fontSize={20}
|
fontSize={20}
|
||||||
/>
|
/>
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { RootState } from 'app/store';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
export const lightboxSelector = createSelector(
|
||||||
|
(state: RootState) => state.lightbox,
|
||||||
|
(lightbox) => lightbox,
|
||||||
|
{
|
||||||
|
memoizeOptions: {
|
||||||
|
equalityCheck: _.isEqual,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
@ -0,0 +1,26 @@
|
|||||||
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
export interface LightboxState {
|
||||||
|
isLightboxOpen: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialLightboxState: LightboxState = {
|
||||||
|
isLightboxOpen: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialState: LightboxState = initialLightboxState;
|
||||||
|
|
||||||
|
export const lightboxSlice = createSlice({
|
||||||
|
name: 'lightbox',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
setIsLightboxOpen: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.isLightboxOpen = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { setIsLightboxOpen } = lightboxSlice.actions;
|
||||||
|
|
||||||
|
export default lightboxSlice.reducer;
|
@ -1,12 +0,0 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
|
||||||
import SeamlessOptions from './SeamlessOptions';
|
|
||||||
|
|
||||||
const ImageToImageOutputOptions = () => {
|
|
||||||
return (
|
|
||||||
<Flex gap={2} direction={'column'}>
|
|
||||||
<SeamlessOptions />
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ImageToImageOutputOptions;
|
|
@ -1,14 +0,0 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
|
||||||
import HiresOptions from './HiresOptions';
|
|
||||||
import SeamlessOptions from './SeamlessOptions';
|
|
||||||
|
|
||||||
const OutputOptions = () => {
|
|
||||||
return (
|
|
||||||
<Flex gap={2} direction={'column'}>
|
|
||||||
<SeamlessOptions />
|
|
||||||
<HiresOptions />
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default OutputOptions;
|
|
@ -1,24 +0,0 @@
|
|||||||
import React, { ChangeEvent } from 'react';
|
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
|
||||||
import IAICheckbox from 'common/components/IAICheckbox';
|
|
||||||
import { setShowAdvancedOptions } from 'features/options/store/optionsSlice';
|
|
||||||
|
|
||||||
export default function MainAdvancedOptionsCheckbox() {
|
|
||||||
const showAdvancedOptions = useAppSelector(
|
|
||||||
(state: RootState) => state.options.showAdvancedOptions
|
|
||||||
);
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
|
||||||
const handleShowAdvancedOptions = (e: ChangeEvent<HTMLInputElement>) =>
|
|
||||||
dispatch(setShowAdvancedOptions(e.target.checked));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IAICheckbox
|
|
||||||
label="Advanced Options"
|
|
||||||
styleClass="advanced-options-checkbox"
|
|
||||||
onChange={handleShowAdvancedOptions}
|
|
||||||
isChecked={showAdvancedOptions}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import { tabMap } from 'features/tabs/tabMap';
|
|
||||||
import { OptionsState } from './optionsSlice';
|
|
||||||
|
|
||||||
export const activeTabNameSelector = createSelector(
|
|
||||||
(state: RootState) => state.options,
|
|
||||||
(options: OptionsState) => tabMap[options.activeTab],
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
equalityCheck: _.isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const mayGenerateMultipleImagesSelector = createSelector(
|
|
||||||
(state: RootState) => state.options,
|
|
||||||
(options: OptionsState) => {
|
|
||||||
const { shouldRandomizeSeed, shouldGenerateVariations } = options;
|
|
||||||
|
|
||||||
return shouldRandomizeSeed || shouldGenerateVariations;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: _.isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const optionsSelector = (state: RootState): OptionsState =>
|
|
||||||
state.options;
|
|
@ -1,12 +1,12 @@
|
|||||||
@use '../../../../styles/Mixins/' as *;
|
@use '../../../../styles/Mixins/' as *;
|
||||||
|
|
||||||
.advanced-settings {
|
.advanced-parameters {
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
display: grid;
|
display: grid;
|
||||||
row-gap: 0.5rem;
|
row-gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.advanced-settings-item {
|
.advanced-parameters-item {
|
||||||
display: grid;
|
display: grid;
|
||||||
max-width: $options-bar-max-width;
|
max-width: $options-bar-max-width;
|
||||||
border: none;
|
border: none;
|
||||||
@ -20,7 +20,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.advanced-settings-panel {
|
.advanced-parameters-panel {
|
||||||
background-color: var(--tab-panel-bg);
|
background-color: var(--tab-panel-bg);
|
||||||
border-radius: 0 0 0.4rem 0.4rem;
|
border-radius: 0 0 0.4rem 0.4rem;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
@ -39,7 +39,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.advanced-settings-header {
|
.advanced-parameters-header {
|
||||||
border-radius: 0.4rem;
|
border-radius: 0.4rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
@ -21,8 +21,8 @@ export default function InvokeAccordionItem(props: InvokeAccordionItemProps) {
|
|||||||
const { header, feature, content, additionalHeaderComponents } = props;
|
const { header, feature, content, additionalHeaderComponents } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AccordionItem className="advanced-settings-item">
|
<AccordionItem className="advanced-parameters-item">
|
||||||
<AccordionButton className="advanced-settings-header">
|
<AccordionButton className="advanced-parameters-header">
|
||||||
<Flex width={'100%'} gap={'0.5rem'} align={'center'}>
|
<Flex width={'100%'} gap={'0.5rem'} align={'center'}>
|
||||||
<Box flexGrow={1} textAlign={'left'}>
|
<Box flexGrow={1} textAlign={'left'}>
|
||||||
{header}
|
{header}
|
||||||
@ -32,7 +32,7 @@ export default function InvokeAccordionItem(props: InvokeAccordionItemProps) {
|
|||||||
<AccordionIcon />
|
<AccordionIcon />
|
||||||
</Flex>
|
</Flex>
|
||||||
</AccordionButton>
|
</AccordionButton>
|
||||||
<AccordionPanel className="advanced-settings-panel">
|
<AccordionPanel className="advanced-parameters-panel">
|
||||||
{content}
|
{content}
|
||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
@ -69,7 +69,7 @@ const BoundingBoxSettings = () => {
|
|||||||
return (
|
return (
|
||||||
<Flex direction="column" gap="1rem">
|
<Flex direction="column" gap="1rem">
|
||||||
<IAISlider
|
<IAISlider
|
||||||
label={t('options:width')}
|
label={t('parameters:width')}
|
||||||
min={64}
|
min={64}
|
||||||
max={1024}
|
max={1024}
|
||||||
step={64}
|
step={64}
|
||||||
@ -83,7 +83,7 @@ const BoundingBoxSettings = () => {
|
|||||||
handleReset={handleResetWidth}
|
handleReset={handleResetWidth}
|
||||||
/>
|
/>
|
||||||
<IAISlider
|
<IAISlider
|
||||||
label={t('options:height')}
|
label={t('parameters:height')}
|
||||||
min={64}
|
min={64}
|
||||||
max={1024}
|
max={1024}
|
||||||
step={64}
|
step={64}
|
||||||
@ -106,7 +106,7 @@ export const BoundingBoxSettingsHeader = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Box flex="1" textAlign="left">
|
<Box flex="1" textAlign="left">
|
||||||
{t('options:boundingBoxHeader')}
|
{t('parameters:boundingBoxHeader')}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
@ -12,20 +12,20 @@ import {
|
|||||||
BoundingBoxScale,
|
BoundingBoxScale,
|
||||||
BOUNDING_BOX_SCALES_DICT,
|
BOUNDING_BOX_SCALES_DICT,
|
||||||
} from 'features/canvas/store/canvasTypes';
|
} from 'features/canvas/store/canvasTypes';
|
||||||
import { optionsSelector } from 'features/options/store/optionsSelectors';
|
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||||
import {
|
import {
|
||||||
setInfillMethod,
|
setInfillMethod,
|
||||||
setTileSize,
|
setTileSize,
|
||||||
} from 'features/options/store/optionsSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { ChangeEvent } from 'react';
|
import { ChangeEvent } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[optionsSelector, systemSelector, canvasSelector],
|
[generationSelector, systemSelector, canvasSelector],
|
||||||
(options, system, canvas) => {
|
(parameters, system, canvas) => {
|
||||||
const { tileSize, infillMethod } = options;
|
const { tileSize, infillMethod } = parameters;
|
||||||
|
|
||||||
const { infill_methods: availableInfillMethods } = system;
|
const { infill_methods: availableInfillMethods } = system;
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ const selector = createSelector(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const InfillAndScalingOptions = () => {
|
const InfillAndScalingSettings = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const {
|
const {
|
||||||
tileSize,
|
tileSize,
|
||||||
@ -108,7 +108,7 @@ const InfillAndScalingOptions = () => {
|
|||||||
return (
|
return (
|
||||||
<Flex direction="column" gap="1rem">
|
<Flex direction="column" gap="1rem">
|
||||||
<IAISelect
|
<IAISelect
|
||||||
label={t('options:scaleBeforeProcessing')}
|
label={t('parameters:scaleBeforeProcessing')}
|
||||||
validValues={BOUNDING_BOX_SCALES_DICT}
|
validValues={BOUNDING_BOX_SCALES_DICT}
|
||||||
value={boundingBoxScale}
|
value={boundingBoxScale}
|
||||||
onChange={handleChangeBoundingBoxScaleMethod}
|
onChange={handleChangeBoundingBoxScaleMethod}
|
||||||
@ -117,7 +117,7 @@ const InfillAndScalingOptions = () => {
|
|||||||
isInputDisabled={!isManual}
|
isInputDisabled={!isManual}
|
||||||
isResetDisabled={!isManual}
|
isResetDisabled={!isManual}
|
||||||
isSliderDisabled={!isManual}
|
isSliderDisabled={!isManual}
|
||||||
label={t('options:scaledWidth')}
|
label={t('parameters:scaledWidth')}
|
||||||
min={64}
|
min={64}
|
||||||
max={1024}
|
max={1024}
|
||||||
step={64}
|
step={64}
|
||||||
@ -134,7 +134,7 @@ const InfillAndScalingOptions = () => {
|
|||||||
isInputDisabled={!isManual}
|
isInputDisabled={!isManual}
|
||||||
isResetDisabled={!isManual}
|
isResetDisabled={!isManual}
|
||||||
isSliderDisabled={!isManual}
|
isSliderDisabled={!isManual}
|
||||||
label={t('options:scaledHeight')}
|
label={t('parameters:scaledHeight')}
|
||||||
min={64}
|
min={64}
|
||||||
max={1024}
|
max={1024}
|
||||||
step={64}
|
step={64}
|
||||||
@ -148,7 +148,7 @@ const InfillAndScalingOptions = () => {
|
|||||||
handleReset={handleResetScaledHeight}
|
handleReset={handleResetScaledHeight}
|
||||||
/>
|
/>
|
||||||
<IAISelect
|
<IAISelect
|
||||||
label={t('options:infillMethod')}
|
label={t('parameters:infillMethod')}
|
||||||
value={infillMethod}
|
value={infillMethod}
|
||||||
validValues={availableInfillMethods}
|
validValues={availableInfillMethods}
|
||||||
onChange={(e) => dispatch(setInfillMethod(e.target.value))}
|
onChange={(e) => dispatch(setInfillMethod(e.target.value))}
|
||||||
@ -158,7 +158,7 @@ const InfillAndScalingOptions = () => {
|
|||||||
isResetDisabled={infillMethod !== 'tile'}
|
isResetDisabled={infillMethod !== 'tile'}
|
||||||
isSliderDisabled={infillMethod !== 'tile'}
|
isSliderDisabled={infillMethod !== 'tile'}
|
||||||
sliderMarkRightOffset={-4}
|
sliderMarkRightOffset={-4}
|
||||||
label={t('options:tileSize')}
|
label={t('parameters:tileSize')}
|
||||||
min={16}
|
min={16}
|
||||||
max={64}
|
max={64}
|
||||||
sliderNumberInputProps={{ max: 256 }}
|
sliderNumberInputProps={{ max: 256 }}
|
||||||
@ -177,4 +177,4 @@ const InfillAndScalingOptions = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default InfillAndScalingOptions;
|
export default InfillAndScalingSettings;
|
@ -1,19 +1,20 @@
|
|||||||
import type { RootState } from 'app/store';
|
import type { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setSeamBlur } from 'features/options/store/optionsSlice';
|
import { setSeamBlur } from 'features/parameters/store/generationSlice';
|
||||||
import React from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function SeamBlur() {
|
export default function SeamBlur() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const seamBlur = useAppSelector((state: RootState) => state.options.seamBlur);
|
const seamBlur = useAppSelector(
|
||||||
|
(state: RootState) => state.generation.seamBlur
|
||||||
|
);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<IAISlider
|
||||||
sliderMarkRightOffset={-4}
|
sliderMarkRightOffset={-4}
|
||||||
label={t('options:seamBlur')}
|
label={t('parameters:seamBlur')}
|
||||||
min={0}
|
min={0}
|
||||||
max={64}
|
max={64}
|
||||||
sliderNumberInputProps={{ max: 512 }}
|
sliderNumberInputProps={{ max: 512 }}
|
@ -4,7 +4,7 @@ import SeamSize from './SeamSize';
|
|||||||
import SeamSteps from './SeamSteps';
|
import SeamSteps from './SeamSteps';
|
||||||
import SeamStrength from './SeamStrength';
|
import SeamStrength from './SeamStrength';
|
||||||
|
|
||||||
const SeamCorrectionOptions = () => {
|
const SeamCorrectionSettings = () => {
|
||||||
return (
|
return (
|
||||||
<Flex direction="column" gap="1rem">
|
<Flex direction="column" gap="1rem">
|
||||||
<SeamSize />
|
<SeamSize />
|
||||||
@ -15,4 +15,4 @@ const SeamCorrectionOptions = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SeamCorrectionOptions;
|
export default SeamCorrectionSettings;
|
@ -1,7 +1,7 @@
|
|||||||
import type { RootState } from 'app/store';
|
import type { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setSeamSize } from 'features/options/store/optionsSlice';
|
import { setSeamSize } from 'features/parameters/store/generationSlice';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
@ -9,12 +9,12 @@ export default function SeamSize() {
|
|||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const seamSize = useAppSelector((state: RootState) => state.options.seamSize);
|
const seamSize = useAppSelector((state: RootState) => state.generation.seamSize);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<IAISlider
|
||||||
sliderMarkRightOffset={-6}
|
sliderMarkRightOffset={-6}
|
||||||
label={t('options:seamSize')}
|
label={t('parameters:seamSize')}
|
||||||
min={1}
|
min={1}
|
||||||
max={256}
|
max={256}
|
||||||
sliderNumberInputProps={{ max: 512 }}
|
sliderNumberInputProps={{ max: 512 }}
|
@ -1,21 +1,21 @@
|
|||||||
import type { RootState } from 'app/store';
|
import type { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setSeamSteps } from 'features/options/store/optionsSlice';
|
import { setSeamSteps } from 'features/parameters/store/generationSlice';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function SeamSteps() {
|
export default function SeamSteps() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const seamSteps = useAppSelector(
|
const seamSteps = useAppSelector(
|
||||||
(state: RootState) => state.options.seamSteps
|
(state: RootState) => state.generation.seamSteps
|
||||||
);
|
);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<IAISlider
|
||||||
sliderMarkRightOffset={-4}
|
sliderMarkRightOffset={-4}
|
||||||
label={t('options:seamSteps')}
|
label={t('parameters:seamSteps')}
|
||||||
min={1}
|
min={1}
|
||||||
max={100}
|
max={100}
|
||||||
sliderNumberInputProps={{ max: 999 }}
|
sliderNumberInputProps={{ max: 999 }}
|
@ -1,7 +1,7 @@
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setSeamStrength } from 'features/options/store/optionsSlice';
|
import { setSeamStrength } from 'features/parameters/store/generationSlice';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
@ -9,13 +9,13 @@ export default function SeamStrength() {
|
|||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const seamStrength = useAppSelector(
|
const seamStrength = useAppSelector(
|
||||||
(state: RootState) => state.options.seamStrength
|
(state: RootState) => state.generation.seamStrength
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<IAISlider
|
||||||
sliderMarkRightOffset={-7}
|
sliderMarkRightOffset={-7}
|
||||||
label={t('options:seamStrength')}
|
label={t('parameters:seamStrength')}
|
||||||
min={0.01}
|
min={0.01}
|
||||||
max={0.99}
|
max={0.99}
|
||||||
step={0.01}
|
step={0.01}
|
@ -1,46 +1,36 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
|
||||||
|
import { FacetoolType } from 'features/parameters/store/postprocessingSlice';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FacetoolType,
|
|
||||||
OptionsState,
|
|
||||||
setCodeformerFidelity,
|
setCodeformerFidelity,
|
||||||
setFacetoolStrength,
|
setFacetoolStrength,
|
||||||
setFacetoolType,
|
setFacetoolType,
|
||||||
} from 'features/options/store/optionsSlice';
|
} from 'features/parameters/store/postprocessingSlice';
|
||||||
|
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import IAISelect from 'common/components/IAISelect';
|
import IAISelect from 'common/components/IAISelect';
|
||||||
import { FACETOOL_TYPES } from 'app/constants';
|
import { FACETOOL_TYPES } from 'app/constants';
|
||||||
import { ChangeEvent } from 'react';
|
import { ChangeEvent } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||||
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
|
||||||
const optionsSelector = createSelector(
|
const optionsSelector = createSelector(
|
||||||
(state: RootState) => state.options,
|
[postprocessingSelector, systemSelector],
|
||||||
(options: OptionsState) => {
|
(
|
||||||
|
{ facetoolStrength, facetoolType, codeformerFidelity },
|
||||||
|
{ isGFPGANAvailable }
|
||||||
|
) => {
|
||||||
return {
|
return {
|
||||||
facetoolStrength: options.facetoolStrength,
|
facetoolStrength,
|
||||||
facetoolType: options.facetoolType,
|
facetoolType,
|
||||||
codeformerFidelity: options.codeformerFidelity,
|
codeformerFidelity,
|
||||||
};
|
isGFPGANAvailable,
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const systemSelector = createSelector(
|
|
||||||
(state: RootState) => state.system,
|
|
||||||
(system: SystemState) => {
|
|
||||||
return {
|
|
||||||
isGFPGANAvailable: system.isGFPGANAvailable,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -53,11 +43,14 @@ const systemSelector = createSelector(
|
|||||||
/**
|
/**
|
||||||
* Displays face-fixing/GFPGAN options (strength).
|
* Displays face-fixing/GFPGAN options (strength).
|
||||||
*/
|
*/
|
||||||
const FaceRestoreOptions = () => {
|
const FaceRestoreSettings = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { facetoolStrength, facetoolType, codeformerFidelity } =
|
const {
|
||||||
useAppSelector(optionsSelector);
|
facetoolStrength,
|
||||||
const { isGFPGANAvailable } = useAppSelector(systemSelector);
|
facetoolType,
|
||||||
|
codeformerFidelity,
|
||||||
|
isGFPGANAvailable,
|
||||||
|
} = useAppSelector(optionsSelector);
|
||||||
|
|
||||||
const handleChangeStrength = (v: number) => dispatch(setFacetoolStrength(v));
|
const handleChangeStrength = (v: number) => dispatch(setFacetoolStrength(v));
|
||||||
|
|
||||||
@ -72,14 +65,14 @@ const FaceRestoreOptions = () => {
|
|||||||
return (
|
return (
|
||||||
<Flex direction={'column'} gap={2}>
|
<Flex direction={'column'} gap={2}>
|
||||||
<IAISelect
|
<IAISelect
|
||||||
label={t('options:type')}
|
label={t('parameters:type')}
|
||||||
validValues={FACETOOL_TYPES.concat()}
|
validValues={FACETOOL_TYPES.concat()}
|
||||||
value={facetoolType}
|
value={facetoolType}
|
||||||
onChange={handleChangeFacetoolType}
|
onChange={handleChangeFacetoolType}
|
||||||
/>
|
/>
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
isDisabled={!isGFPGANAvailable}
|
isDisabled={!isGFPGANAvailable}
|
||||||
label={t('options:strength')}
|
label={t('parameters:strength')}
|
||||||
step={0.05}
|
step={0.05}
|
||||||
min={0}
|
min={0}
|
||||||
max={1}
|
max={1}
|
||||||
@ -91,7 +84,7 @@ const FaceRestoreOptions = () => {
|
|||||||
{facetoolType === 'codeformer' && (
|
{facetoolType === 'codeformer' && (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
isDisabled={!isGFPGANAvailable}
|
isDisabled={!isGFPGANAvailable}
|
||||||
label={t('options:codeformerFidelity')}
|
label={t('parameters:codeformerFidelity')}
|
||||||
step={0.05}
|
step={0.05}
|
||||||
min={0}
|
min={0}
|
||||||
max={1}
|
max={1}
|
||||||
@ -105,4 +98,4 @@ const FaceRestoreOptions = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FaceRestoreOptions;
|
export default FaceRestoreSettings;
|
@ -2,7 +2,7 @@ import { ChangeEvent } from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISwitch from 'common/components/IAISwitch';
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
import { setShouldRunFacetool } from 'features/options/store/optionsSlice';
|
import { setShouldRunFacetool } from 'features/parameters/store/postprocessingSlice';
|
||||||
|
|
||||||
export default function FaceRestoreToggle() {
|
export default function FaceRestoreToggle() {
|
||||||
const isGFPGANAvailable = useAppSelector(
|
const isGFPGANAvailable = useAppSelector(
|
||||||
@ -10,7 +10,7 @@ export default function FaceRestoreToggle() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const shouldRunFacetool = useAppSelector(
|
const shouldRunFacetool = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldRunFacetool
|
(state: RootState) => state.postprocessing.shouldRunFacetool
|
||||||
);
|
);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
@ -2,14 +2,14 @@ import React, { ChangeEvent } from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISwitch from 'common/components/IAISwitch';
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
import { setShouldFitToWidthHeight } from 'features/options/store/optionsSlice';
|
import { setShouldFitToWidthHeight } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function ImageFit() {
|
export default function ImageFit() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const shouldFitToWidthHeight = useAppSelector(
|
const shouldFitToWidthHeight = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldFitToWidthHeight
|
(state: RootState) => state.generation.shouldFitToWidthHeight
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleChangeFit = (e: ChangeEvent<HTMLInputElement>) =>
|
const handleChangeFit = (e: ChangeEvent<HTMLInputElement>) =>
|
||||||
@ -19,7 +19,7 @@ export default function ImageFit() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISwitch
|
<IAISwitch
|
||||||
label={t('options:imageFit')}
|
label={t('parameters:imageFit')}
|
||||||
isChecked={shouldFitToWidthHeight}
|
isChecked={shouldFitToWidthHeight}
|
||||||
onChange={handleChangeFit}
|
onChange={handleChangeFit}
|
||||||
/>
|
/>
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setImg2imgStrength } from 'features/options/store/optionsSlice';
|
import { setImg2imgStrength } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
interface ImageToImageStrengthProps {
|
interface ImageToImageStrengthProps {
|
||||||
@ -12,9 +12,9 @@ interface ImageToImageStrengthProps {
|
|||||||
|
|
||||||
export default function ImageToImageStrength(props: ImageToImageStrengthProps) {
|
export default function ImageToImageStrength(props: ImageToImageStrengthProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { label = `${t('options:strength')}`, styleClass } = props;
|
const { label = `${t('parameters:strength')}`, styleClass } = props;
|
||||||
const img2imgStrength = useAppSelector(
|
const img2imgStrength = useAppSelector(
|
||||||
(state: RootState) => state.options.img2imgStrength
|
(state: RootState) => state.generation.img2imgStrength
|
||||||
);
|
);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
@ -1,21 +1,31 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { ChangeEvent } from 'react';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import type { RootState } from 'app/store';
|
import type { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import IAISwitch from 'common/components/IAISwitch';
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
|
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||||
import {
|
import {
|
||||||
setHiresFix,
|
setHiresFix,
|
||||||
setHiresStrength,
|
setHiresStrength,
|
||||||
} from 'features/options/store/optionsSlice';
|
} from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import { isEqual } from 'lodash';
|
||||||
|
import { ChangeEvent } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
|
||||||
|
|
||||||
function HighResStrength() {
|
const hiresStrengthSelector = createSelector(
|
||||||
const hiresFix = useAppSelector((state: RootState) => state.options.hiresFix);
|
[postprocessingSelector],
|
||||||
const hiresStrength = useAppSelector(
|
({ hiresFix, hiresStrength }) => ({ hiresFix, hiresStrength }),
|
||||||
(state: RootState) => state.options.hiresStrength
|
{
|
||||||
|
memoizeOptions: {
|
||||||
|
resultEqualityCheck: isEqual,
|
||||||
|
},
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const HiresStrength = () => {
|
||||||
|
const { hiresFix, hiresStrength } = useAppSelector(hiresStrengthSelector);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -30,7 +40,7 @@ function HighResStrength() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<IAISlider
|
||||||
label={t('options:hiresStrength')}
|
label={t('parameters:hiresStrength')}
|
||||||
step={0.01}
|
step={0.01}
|
||||||
min={0.01}
|
min={0.01}
|
||||||
max={0.99}
|
max={0.99}
|
||||||
@ -47,15 +57,17 @@ function HighResStrength() {
|
|||||||
isResetDisabled={!hiresFix}
|
isResetDisabled={!hiresFix}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hires Fix Toggle
|
* Hires Fix Toggle
|
||||||
*/
|
*/
|
||||||
const HiresOptions = () => {
|
const HiresSettings = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const hiresFix = useAppSelector((state: RootState) => state.options.hiresFix);
|
const hiresFix = useAppSelector(
|
||||||
|
(state: RootState) => state.postprocessing.hiresFix
|
||||||
|
);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -65,14 +77,14 @@ const HiresOptions = () => {
|
|||||||
return (
|
return (
|
||||||
<Flex gap={2} direction={'column'}>
|
<Flex gap={2} direction={'column'}>
|
||||||
<IAISwitch
|
<IAISwitch
|
||||||
label={t('options:hiresOptim')}
|
label={t('parameters:hiresOptim')}
|
||||||
fontSize={'md'}
|
fontSize={'md'}
|
||||||
isChecked={hiresFix}
|
isChecked={hiresFix}
|
||||||
onChange={handleChangeHiresFix}
|
onChange={handleChangeHiresFix}
|
||||||
/>
|
/>
|
||||||
<HighResStrength />
|
<HiresStrength />
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default HiresOptions;
|
export default HiresSettings;
|
@ -0,0 +1,12 @@
|
|||||||
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
import SeamlessSettings from './SeamlessSettings';
|
||||||
|
|
||||||
|
const ImageToImageOutputSettings = () => {
|
||||||
|
return (
|
||||||
|
<Flex gap={2} direction={'column'}>
|
||||||
|
<SeamlessSettings />
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ImageToImageOutputSettings;
|
@ -0,0 +1,14 @@
|
|||||||
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
import HiresSettings from './HiresSettings';
|
||||||
|
import SeamlessSettings from './SeamlessSettings';
|
||||||
|
|
||||||
|
const OutputSettings = () => {
|
||||||
|
return (
|
||||||
|
<Flex gap={2} direction={'column'}>
|
||||||
|
<SeamlessSettings />
|
||||||
|
<HiresSettings />
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default OutputSettings;
|
@ -3,16 +3,16 @@ import { ChangeEvent } from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISwitch from 'common/components/IAISwitch';
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
import { setSeamless } from 'features/options/store/optionsSlice';
|
import { setSeamless } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Seamless tiling toggle
|
* Seamless tiling toggle
|
||||||
*/
|
*/
|
||||||
const SeamlessOptions = () => {
|
const SeamlessSettings = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const seamless = useAppSelector((state: RootState) => state.options.seamless);
|
const seamless = useAppSelector((state: RootState) => state.generation.seamless);
|
||||||
|
|
||||||
const handleChangeSeamless = (e: ChangeEvent<HTMLInputElement>) =>
|
const handleChangeSeamless = (e: ChangeEvent<HTMLInputElement>) =>
|
||||||
dispatch(setSeamless(e.target.checked));
|
dispatch(setSeamless(e.target.checked));
|
||||||
@ -22,7 +22,7 @@ const SeamlessOptions = () => {
|
|||||||
return (
|
return (
|
||||||
<Flex gap={2} direction={'column'}>
|
<Flex gap={2} direction={'column'}>
|
||||||
<IAISwitch
|
<IAISwitch
|
||||||
label={t('options:seamlessTiling')}
|
label={t('parameters:seamlessTiling')}
|
||||||
fontSize={'md'}
|
fontSize={'md'}
|
||||||
isChecked={seamless}
|
isChecked={seamless}
|
||||||
onChange={handleChangeSeamless}
|
onChange={handleChangeSeamless}
|
||||||
@ -31,4 +31,4 @@ const SeamlessOptions = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SeamlessOptions;
|
export default SeamlessSettings;
|
@ -2,19 +2,19 @@ import React from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import { setPerlin } from 'features/options/store/optionsSlice';
|
import { setPerlin } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function Perlin() {
|
export default function Perlin() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const perlin = useAppSelector((state: RootState) => state.options.perlin);
|
const perlin = useAppSelector((state: RootState) => state.generation.perlin);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleChangePerlin = (v: number) => dispatch(setPerlin(v));
|
const handleChangePerlin = (v: number) => dispatch(setPerlin(v));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
label={t('options:perlinNoise')}
|
label={t('parameters:perlinNoise')}
|
||||||
min={0}
|
min={0}
|
||||||
max={1}
|
max={1}
|
||||||
step={0.05}
|
step={0.05}
|
@ -4,7 +4,7 @@ import React from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISwitch from 'common/components/IAISwitch';
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
import { setShouldRandomizeSeed } from 'features/options/store/optionsSlice';
|
import { setShouldRandomizeSeed } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function RandomizeSeed() {
|
export default function RandomizeSeed() {
|
||||||
@ -12,7 +12,7 @@ export default function RandomizeSeed() {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const shouldRandomizeSeed = useAppSelector(
|
const shouldRandomizeSeed = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldRandomizeSeed
|
(state: RootState) => state.generation.shouldRandomizeSeed
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleChangeShouldRandomizeSeed = (e: ChangeEvent<HTMLInputElement>) =>
|
const handleChangeShouldRandomizeSeed = (e: ChangeEvent<HTMLInputElement>) =>
|
||||||
@ -20,7 +20,7 @@ export default function RandomizeSeed() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISwitch
|
<IAISwitch
|
||||||
label={t('options:randomizeSeed')}
|
label={t('parameters:randomizeSeed')}
|
||||||
isChecked={shouldRandomizeSeed}
|
isChecked={shouldRandomizeSeed}
|
||||||
onChange={handleChangeShouldRandomizeSeed}
|
onChange={handleChangeShouldRandomizeSeed}
|
||||||
/>
|
/>
|
@ -3,16 +3,16 @@ import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import { setSeed } from 'features/options/store/optionsSlice';
|
import { setSeed } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function Seed() {
|
export default function Seed() {
|
||||||
const seed = useAppSelector((state: RootState) => state.options.seed);
|
const seed = useAppSelector((state: RootState) => state.generation.seed);
|
||||||
const shouldRandomizeSeed = useAppSelector(
|
const shouldRandomizeSeed = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldRandomizeSeed
|
(state: RootState) => state.generation.shouldRandomizeSeed
|
||||||
);
|
);
|
||||||
const shouldGenerateVariations = useAppSelector(
|
const shouldGenerateVariations = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldGenerateVariations
|
(state: RootState) => state.generation.shouldGenerateVariations
|
||||||
);
|
);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -23,7 +23,7 @@ export default function Seed() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
label={t('options:seed')}
|
label={t('parameters:seed')}
|
||||||
step={1}
|
step={1}
|
||||||
precision={0}
|
precision={0}
|
||||||
flexGrow={1}
|
flexGrow={1}
|
@ -8,7 +8,7 @@ import Perlin from './Perlin';
|
|||||||
/**
|
/**
|
||||||
* Seed & variation options. Includes iteration, seed, seed randomization, variation options.
|
* Seed & variation options. Includes iteration, seed, seed randomization, variation options.
|
||||||
*/
|
*/
|
||||||
const SeedOptions = () => {
|
const SeedSettings = () => {
|
||||||
return (
|
return (
|
||||||
<Flex gap={2} direction={'column'}>
|
<Flex gap={2} direction={'column'}>
|
||||||
<RandomizeSeed />
|
<RandomizeSeed />
|
||||||
@ -26,4 +26,4 @@ const SeedOptions = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SeedOptions;
|
export default SeedSettings;
|
@ -4,13 +4,13 @@ import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import randomInt from 'common/util/randomInt';
|
import randomInt from 'common/util/randomInt';
|
||||||
import { setSeed } from 'features/options/store/optionsSlice';
|
import { setSeed } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function ShuffleSeed() {
|
export default function ShuffleSeed() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const shouldRandomizeSeed = useAppSelector(
|
const shouldRandomizeSeed = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldRandomizeSeed
|
(state: RootState) => state.generation.shouldRandomizeSeed
|
||||||
);
|
);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ export default function ShuffleSeed() {
|
|||||||
onClick={handleClickRandomizeSeed}
|
onClick={handleClickRandomizeSeed}
|
||||||
padding="0 1.5rem"
|
padding="0 1.5rem"
|
||||||
>
|
>
|
||||||
<p>{t('options:shuffle')}</p>
|
<p>{t('parameters:shuffle')}</p>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -2,13 +2,13 @@ import React from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import { setThreshold } from 'features/options/store/optionsSlice';
|
import { setThreshold } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function Threshold() {
|
export default function Threshold() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const threshold = useAppSelector(
|
const threshold = useAppSelector(
|
||||||
(state: RootState) => state.options.threshold
|
(state: RootState) => state.generation.threshold
|
||||||
);
|
);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ export default function Threshold() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
label={t('options:noiseThreshold')}
|
label={t('parameters:noiseThreshold')}
|
||||||
min={0}
|
min={0}
|
||||||
max={1000}
|
max={1000}
|
||||||
step={0.1}
|
step={0.1}
|
@ -1,4 +1,4 @@
|
|||||||
.upscale-options {
|
.upscale-settings {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto 1fr;
|
grid-template-columns: auto 1fr;
|
||||||
column-gap: 1rem;
|
column-gap: 1rem;
|
@ -1,42 +1,29 @@
|
|||||||
import { RootState } from 'app/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
|
||||||
|
import { UpscalingLevel } from 'features/parameters/store/postprocessingSlice';
|
||||||
import {
|
import {
|
||||||
setUpscalingLevel,
|
setUpscalingLevel,
|
||||||
setUpscalingStrength,
|
setUpscalingStrength,
|
||||||
UpscalingLevel,
|
} from 'features/parameters/store/postprocessingSlice';
|
||||||
OptionsState,
|
|
||||||
} from 'features/options/store/optionsSlice';
|
|
||||||
|
|
||||||
import { UPSCALING_LEVELS } from 'app/constants';
|
import { UPSCALING_LEVELS } from 'app/constants';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
|
||||||
import { ChangeEvent } from 'react';
|
import { ChangeEvent } from 'react';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import IAISelect from 'common/components/IAISelect';
|
import IAISelect from 'common/components/IAISelect';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||||
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
|
||||||
const optionsSelector = createSelector(
|
const parametersSelector = createSelector(
|
||||||
(state: RootState) => state.options,
|
[postprocessingSelector, systemSelector],
|
||||||
(options: OptionsState) => {
|
|
||||||
return {
|
|
||||||
upscalingLevel: options.upscalingLevel,
|
|
||||||
upscalingStrength: options.upscalingStrength,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const systemSelector = createSelector(
|
({ upscalingLevel, upscalingStrength }, { isESRGANAvailable }) => {
|
||||||
(state: RootState) => state.system,
|
|
||||||
(system: SystemState) => {
|
|
||||||
return {
|
return {
|
||||||
isESRGANAvailable: system.isESRGANAvailable,
|
upscalingLevel,
|
||||||
|
upscalingStrength,
|
||||||
|
isESRGANAvailable,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -49,11 +36,10 @@ const systemSelector = createSelector(
|
|||||||
/**
|
/**
|
||||||
* Displays upscaling/ESRGAN options (level and strength).
|
* Displays upscaling/ESRGAN options (level and strength).
|
||||||
*/
|
*/
|
||||||
const UpscaleOptions = () => {
|
const UpscaleSettings = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { upscalingLevel, upscalingStrength } = useAppSelector(optionsSelector);
|
const { upscalingLevel, upscalingStrength, isESRGANAvailable } =
|
||||||
|
useAppSelector(parametersSelector);
|
||||||
const { isESRGANAvailable } = useAppSelector(systemSelector);
|
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -63,17 +49,17 @@ const UpscaleOptions = () => {
|
|||||||
const handleChangeStrength = (v: number) => dispatch(setUpscalingStrength(v));
|
const handleChangeStrength = (v: number) => dispatch(setUpscalingStrength(v));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="upscale-options">
|
<div className="upscale-settings">
|
||||||
<IAISelect
|
<IAISelect
|
||||||
isDisabled={!isESRGANAvailable}
|
isDisabled={!isESRGANAvailable}
|
||||||
label={t('options:scale')}
|
label={t('parameters:scale')}
|
||||||
value={upscalingLevel}
|
value={upscalingLevel}
|
||||||
onChange={handleChangeLevel}
|
onChange={handleChangeLevel}
|
||||||
validValues={UPSCALING_LEVELS}
|
validValues={UPSCALING_LEVELS}
|
||||||
/>
|
/>
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
isDisabled={!isESRGANAvailable}
|
isDisabled={!isESRGANAvailable}
|
||||||
label={t('options:strength')}
|
label={t('parameters:strength')}
|
||||||
step={0.05}
|
step={0.05}
|
||||||
min={0}
|
min={0}
|
||||||
max={1}
|
max={1}
|
||||||
@ -85,4 +71,4 @@ const UpscaleOptions = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default UpscaleOptions;
|
export default UpscaleSettings;
|
@ -2,7 +2,7 @@ import { ChangeEvent } from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISwitch from 'common/components/IAISwitch';
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
import { setShouldRunESRGAN } from 'features/options/store/optionsSlice';
|
import { setShouldRunESRGAN } from 'features/parameters/store/postprocessingSlice';
|
||||||
|
|
||||||
export default function UpscaleToggle() {
|
export default function UpscaleToggle() {
|
||||||
const isESRGANAvailable = useAppSelector(
|
const isESRGANAvailable = useAppSelector(
|
||||||
@ -10,7 +10,7 @@ export default function UpscaleToggle() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const shouldRunESRGAN = useAppSelector(
|
const shouldRunESRGAN = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldRunESRGAN
|
(state: RootState) => state.postprocessing.shouldRunESRGAN
|
||||||
);
|
);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
@ -2,11 +2,11 @@ import React, { ChangeEvent } from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISwitch from 'common/components/IAISwitch';
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
import { setShouldGenerateVariations } from 'features/options/store/optionsSlice';
|
import { setShouldGenerateVariations } from 'features/parameters/store/generationSlice';
|
||||||
|
|
||||||
export default function GenerateVariationsToggle() {
|
export default function GenerateVariationsToggle() {
|
||||||
const shouldGenerateVariations = useAppSelector(
|
const shouldGenerateVariations = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldGenerateVariations
|
(state: RootState) => state.generation.shouldGenerateVariations
|
||||||
);
|
);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
@ -3,16 +3,16 @@ import { RootState } from 'app/store';
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAIInput from 'common/components/IAIInput';
|
import IAIInput from 'common/components/IAIInput';
|
||||||
import { validateSeedWeights } from 'common/util/seedWeightPairs';
|
import { validateSeedWeights } from 'common/util/seedWeightPairs';
|
||||||
import { setSeedWeights } from 'features/options/store/optionsSlice';
|
import { setSeedWeights } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function SeedWeights() {
|
export default function SeedWeights() {
|
||||||
const seedWeights = useAppSelector(
|
const seedWeights = useAppSelector(
|
||||||
(state: RootState) => state.options.seedWeights
|
(state: RootState) => state.generation.seedWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
const shouldGenerateVariations = useAppSelector(
|
const shouldGenerateVariations = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldGenerateVariations
|
(state: RootState) => state.generation.shouldGenerateVariations
|
||||||
);
|
);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -24,7 +24,7 @@ export default function SeedWeights() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIInput
|
<IAIInput
|
||||||
label={t('options:seedWeights')}
|
label={t('parameters:seedWeights')}
|
||||||
value={seedWeights}
|
value={seedWeights}
|
||||||
isInvalid={
|
isInvalid={
|
||||||
shouldGenerateVariations &&
|
shouldGenerateVariations &&
|
@ -2,16 +2,16 @@ import React from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import { setVariationAmount } from 'features/options/store/optionsSlice';
|
import { setVariationAmount } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function VariationAmount() {
|
export default function VariationAmount() {
|
||||||
const variationAmount = useAppSelector(
|
const variationAmount = useAppSelector(
|
||||||
(state: RootState) => state.options.variationAmount
|
(state: RootState) => state.generation.variationAmount
|
||||||
);
|
);
|
||||||
|
|
||||||
const shouldGenerateVariations = useAppSelector(
|
const shouldGenerateVariations = useAppSelector(
|
||||||
(state: RootState) => state.options.shouldGenerateVariations
|
(state: RootState) => state.generation.shouldGenerateVariations
|
||||||
);
|
);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -22,7 +22,7 @@ export default function VariationAmount() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
label={t('options:variationAmount')}
|
label={t('parameters:variationAmount')}
|
||||||
value={variationAmount}
|
value={variationAmount}
|
||||||
step={0.01}
|
step={0.01}
|
||||||
min={0}
|
min={0}
|
@ -5,7 +5,7 @@ import VariationAmount from './VariationAmount';
|
|||||||
/**
|
/**
|
||||||
* Seed & variation options. Includes iteration, seed, seed randomization, variation options.
|
* Seed & variation options. Includes iteration, seed, seed randomization, variation options.
|
||||||
*/
|
*/
|
||||||
const VariationsOptions = () => {
|
const VariationsSettings = () => {
|
||||||
return (
|
return (
|
||||||
<Flex gap={2} direction={'column'}>
|
<Flex gap={2} direction={'column'}>
|
||||||
<VariationAmount />
|
<VariationAmount />
|
||||||
@ -14,4 +14,4 @@ const VariationsOptions = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default VariationsOptions;
|
export default VariationsSettings;
|
@ -2,26 +2,26 @@ import React from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import { setCfgScale } from 'features/options/store/optionsSlice';
|
import { setCfgScale } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function MainCFGScale() {
|
export default function MainCFGScale() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const cfgScale = useAppSelector((state: RootState) => state.options.cfgScale);
|
const cfgScale = useAppSelector((state: RootState) => state.generation.cfgScale);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleChangeCfgScale = (v: number) => dispatch(setCfgScale(v));
|
const handleChangeCfgScale = (v: number) => dispatch(setCfgScale(v));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
label={t('options:cfgScale')}
|
label={t('parameters:cfgScale')}
|
||||||
step={0.5}
|
step={0.5}
|
||||||
min={1.01}
|
min={1.01}
|
||||||
max={200}
|
max={200}
|
||||||
onChange={handleChangeCfgScale}
|
onChange={handleChangeCfgScale}
|
||||||
value={cfgScale}
|
value={cfgScale}
|
||||||
width="auto"
|
width="auto"
|
||||||
styleClass="main-option-block"
|
styleClass="main-settings-block"
|
||||||
textAlign="center"
|
textAlign="center"
|
||||||
isInteger={false}
|
isInteger={false}
|
||||||
/>
|
/>
|
@ -4,12 +4,12 @@ import { HEIGHTS } from 'app/constants';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISelect from 'common/components/IAISelect';
|
import IAISelect from 'common/components/IAISelect';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { setHeight } from 'features/options/store/optionsSlice';
|
import { setHeight } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function MainHeight() {
|
export default function MainHeight() {
|
||||||
const height = useAppSelector((state: RootState) => state.options.height);
|
const height = useAppSelector((state: RootState) => state.generation.height);
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -20,12 +20,12 @@ export default function MainHeight() {
|
|||||||
return (
|
return (
|
||||||
<IAISelect
|
<IAISelect
|
||||||
isDisabled={activeTabName === 'unifiedCanvas'}
|
isDisabled={activeTabName === 'unifiedCanvas'}
|
||||||
label={t('options:height')}
|
label={t('parameters:height')}
|
||||||
value={height}
|
value={height}
|
||||||
flexGrow={1}
|
flexGrow={1}
|
||||||
onChange={handleChangeHeight}
|
onChange={handleChangeHeight}
|
||||||
validValues={HEIGHTS}
|
validValues={HEIGHTS}
|
||||||
styleClass="main-option-block"
|
styleClass="main-settings-block"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -5,15 +5,15 @@ import type { RootState } from 'app/store';
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import {
|
import {
|
||||||
OptionsState,
|
GenerationState,
|
||||||
setIterations,
|
setIterations,
|
||||||
} from 'features/options/store/optionsSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const mainIterationsSelector = createSelector(
|
const mainIterationsSelector = createSelector(
|
||||||
[(state: RootState) => state.options],
|
[(state: RootState) => state.generation],
|
||||||
(options: OptionsState) => {
|
(parameters: GenerationState) => {
|
||||||
const { iterations } = options;
|
const { iterations } = parameters;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
iterations,
|
iterations,
|
||||||
@ -35,7 +35,7 @@ export default function MainIterations() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
label={t('options:images')}
|
label={t('parameters:images')}
|
||||||
step={1}
|
step={1}
|
||||||
min={1}
|
min={1}
|
||||||
max={9999}
|
max={9999}
|
||||||
@ -43,7 +43,7 @@ export default function MainIterations() {
|
|||||||
value={iterations}
|
value={iterations}
|
||||||
width="auto"
|
width="auto"
|
||||||
labelFontSize={0.5}
|
labelFontSize={0.5}
|
||||||
styleClass="main-option-block"
|
styleClass="main-settings-block"
|
||||||
textAlign="center"
|
textAlign="center"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
@ -1,23 +1,23 @@
|
|||||||
@use '../../../../styles/Mixins/' as *;
|
@use '../../../../styles/Mixins/' as *;
|
||||||
|
|
||||||
.main-options {
|
.main-settings {
|
||||||
display: grid;
|
display: grid;
|
||||||
row-gap: 1rem;
|
row-gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-options-list {
|
.main-settings-list {
|
||||||
display: grid;
|
display: grid;
|
||||||
row-gap: 1rem;
|
row-gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-options-row {
|
.main-settings-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, auto);
|
grid-template-columns: repeat(3, auto);
|
||||||
column-gap: 0.5rem;
|
column-gap: 0.5rem;
|
||||||
max-width: $options-bar-max-width;
|
max-width: $options-bar-max-width;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-option-block {
|
.main-settings-block {
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
display: grid !important;
|
display: grid !important;
|
||||||
grid-template-columns: auto !important;
|
grid-template-columns: auto !important;
|
||||||
@ -33,10 +33,3 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.advanced-options-checkbox {
|
|
||||||
background-color: var(--background-color-secondary);
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
border-radius: 0.4rem;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
@ -7,16 +7,16 @@ import MainWidth from './MainWidth';
|
|||||||
|
|
||||||
export const inputWidth = 'auto';
|
export const inputWidth = 'auto';
|
||||||
|
|
||||||
export default function MainOptions() {
|
export default function MainSettings() {
|
||||||
return (
|
return (
|
||||||
<div className="main-options">
|
<div className="main-settings">
|
||||||
<div className="main-options-list">
|
<div className="main-settings-list">
|
||||||
<div className="main-options-row">
|
<div className="main-settings-row">
|
||||||
<MainIterations />
|
<MainIterations />
|
||||||
<MainSteps />
|
<MainSteps />
|
||||||
<MainCFGScale />
|
<MainCFGScale />
|
||||||
</div>
|
</div>
|
||||||
<div className="main-options-row">
|
<div className="main-settings-row">
|
||||||
<MainWidth />
|
<MainWidth />
|
||||||
<MainHeight />
|
<MainHeight />
|
||||||
<MainSampler />
|
<MainSampler />
|
@ -1,15 +1,16 @@
|
|||||||
import React, { ChangeEvent } from 'react';
|
|
||||||
import { DIFFUSERS_SAMPLERS, SAMPLERS } from 'app/constants';
|
import { DIFFUSERS_SAMPLERS, SAMPLERS } from 'app/constants';
|
||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISelect from 'common/components/IAISelect';
|
import IAISelect from 'common/components/IAISelect';
|
||||||
import { setSampler } from 'features/options/store/optionsSlice';
|
import { setSampler } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { activeModelSelector } from 'features/system/store/systemSelectors';
|
import { activeModelSelector } from 'features/system/store/systemSelectors';
|
||||||
|
import { ChangeEvent } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function MainSampler() {
|
export default function MainSampler() {
|
||||||
const sampler = useAppSelector((state: RootState) => state.options.sampler);
|
const sampler = useAppSelector(
|
||||||
|
(state: RootState) => state.generation.sampler
|
||||||
|
);
|
||||||
const activeModel = useAppSelector(activeModelSelector);
|
const activeModel = useAppSelector(activeModelSelector);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -19,7 +20,7 @@ export default function MainSampler() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISelect
|
<IAISelect
|
||||||
label={t('options:sampler')}
|
label={t('parameters:sampler')}
|
||||||
value={sampler}
|
value={sampler}
|
||||||
onChange={handleChangeSampler}
|
onChange={handleChangeSampler}
|
||||||
validValues={
|
validValues={
|
@ -2,26 +2,26 @@ import React from 'react';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import { setSteps } from 'features/options/store/optionsSlice';
|
import { setSteps } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function MainSteps() {
|
export default function MainSteps() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const steps = useAppSelector((state: RootState) => state.options.steps);
|
const steps = useAppSelector((state: RootState) => state.generation.steps);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleChangeSteps = (v: number) => dispatch(setSteps(v));
|
const handleChangeSteps = (v: number) => dispatch(setSteps(v));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
label={t('options:steps')}
|
label={t('parameters:steps')}
|
||||||
min={1}
|
min={1}
|
||||||
max={9999}
|
max={9999}
|
||||||
step={1}
|
step={1}
|
||||||
onChange={handleChangeSteps}
|
onChange={handleChangeSteps}
|
||||||
value={steps}
|
value={steps}
|
||||||
width="auto"
|
width="auto"
|
||||||
styleClass="main-option-block"
|
styleClass="main-settings-block"
|
||||||
textAlign="center"
|
textAlign="center"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
@ -3,12 +3,12 @@ import { WIDTHS } from 'app/constants';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISelect from 'common/components/IAISelect';
|
import IAISelect from 'common/components/IAISelect';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { setWidth } from 'features/options/store/optionsSlice';
|
import { setWidth } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function MainWidth() {
|
export default function MainWidth() {
|
||||||
const width = useAppSelector((state: RootState) => state.options.width);
|
const width = useAppSelector((state: RootState) => state.generation.width);
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -20,12 +20,12 @@ export default function MainWidth() {
|
|||||||
return (
|
return (
|
||||||
<IAISelect
|
<IAISelect
|
||||||
isDisabled={activeTabName === 'unifiedCanvas'}
|
isDisabled={activeTabName === 'unifiedCanvas'}
|
||||||
label={t('options:width')}
|
label={t('parameters:width')}
|
||||||
value={width}
|
value={width}
|
||||||
flexGrow={1}
|
flexGrow={1}
|
||||||
onChange={handleChangeWidth}
|
onChange={handleChangeWidth}
|
||||||
validValues={WIDTHS}
|
validValues={WIDTHS}
|
||||||
styleClass="main-option-block"
|
styleClass="main-settings-block"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -7,18 +7,18 @@ import InvokeAccordionItem, {
|
|||||||
} from './AccordionItems/InvokeAccordionItem';
|
} from './AccordionItems/InvokeAccordionItem';
|
||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
|
|
||||||
type OptionsAccordionType = {
|
type ParametersAccordionType = {
|
||||||
[optionAccordionKey: string]: InvokeAccordionItemProps;
|
[parametersAccordionKey: string]: InvokeAccordionItemProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
type OptionAccordionsType = {
|
type ParametersAccordionsType = {
|
||||||
accordionInfo: OptionsAccordionType;
|
accordionInfo: ParametersAccordionType;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main container for generation and processing parameters.
|
* Main container for generation and processing parameters.
|
||||||
*/
|
*/
|
||||||
const OptionsAccordion = (props: OptionAccordionsType) => {
|
const ParametersAccordion = (props: ParametersAccordionsType) => {
|
||||||
const { accordionInfo } = props;
|
const { accordionInfo } = props;
|
||||||
|
|
||||||
const openAccordions = useAppSelector(
|
const openAccordions = useAppSelector(
|
||||||
@ -59,11 +59,11 @@ const OptionsAccordion = (props: OptionAccordionsType) => {
|
|||||||
allowMultiple
|
allowMultiple
|
||||||
reduceMotion
|
reduceMotion
|
||||||
onChange={handleChangeAccordionState}
|
onChange={handleChangeAccordionState}
|
||||||
className="advanced-settings"
|
className="advanced-parameters"
|
||||||
>
|
>
|
||||||
{renderAccordions()}
|
{renderAccordions()}
|
||||||
</Accordion>
|
</Accordion>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default OptionsAccordion;
|
export default ParametersAccordion;
|
@ -1,6 +1,5 @@
|
|||||||
import { MdCancel } from 'react-icons/md';
|
import { MdCancel } from 'react-icons/md';
|
||||||
import { cancelProcessing } from 'app/socketio/actions';
|
import { cancelProcessing } from 'app/socketio/actions';
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAIIconButton, {
|
import IAIIconButton, {
|
||||||
IAIIconButtonProps,
|
IAIIconButtonProps,
|
||||||
@ -10,9 +9,10 @@ import { createSelector } from '@reduxjs/toolkit';
|
|||||||
import { SystemState } from 'features/system/store/systemSlice';
|
import { SystemState } from 'features/system/store/systemSlice';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
|
||||||
const cancelButtonSelector = createSelector(
|
const cancelButtonSelector = createSelector(
|
||||||
(state: RootState) => state.system,
|
systemSelector,
|
||||||
(system: SystemState) => {
|
(system: SystemState) => {
|
||||||
return {
|
return {
|
||||||
isProcessing: system.isProcessing,
|
isProcessing: system.isProcessing,
|
||||||
@ -51,8 +51,8 @@ export default function CancelButton(
|
|||||||
return (
|
return (
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
icon={<MdCancel />}
|
icon={<MdCancel />}
|
||||||
tooltip={t('options:cancel')}
|
tooltip={t('parameters:cancel')}
|
||||||
aria-label={t('options:cancel')}
|
aria-label={t('parameters:cancel')}
|
||||||
isDisabled={!isConnected || !isProcessing || !isCancelable}
|
isDisabled={!isConnected || !isProcessing || !isCancelable}
|
||||||
onClick={handleClickCancel}
|
onClick={handleClickCancel}
|
||||||
styleClass="cancel-btn"
|
styleClass="cancel-btn"
|
@ -7,7 +7,7 @@ import IAIButton, { IAIButtonProps } from 'common/components/IAIButton';
|
|||||||
import IAIIconButton, {
|
import IAIIconButton, {
|
||||||
IAIIconButtonProps,
|
IAIIconButtonProps,
|
||||||
} from 'common/components/IAIIconButton';
|
} from 'common/components/IAIIconButton';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
interface InvokeButton
|
interface InvokeButton
|
||||||
@ -44,19 +44,19 @@ export default function InvokeButton(props: InvokeButton) {
|
|||||||
<div style={{ flexGrow: 4 }}>
|
<div style={{ flexGrow: 4 }}>
|
||||||
{iconButton ? (
|
{iconButton ? (
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
aria-label={t('options:invoke')}
|
aria-label={t('parameters:invoke')}
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={<FaPlay />}
|
icon={<FaPlay />}
|
||||||
isDisabled={!isReady}
|
isDisabled={!isReady}
|
||||||
onClick={handleClickGenerate}
|
onClick={handleClickGenerate}
|
||||||
className="invoke-btn"
|
className="invoke-btn"
|
||||||
tooltip={t('options:invoke')}
|
tooltip={t('parameters:invoke')}
|
||||||
tooltipProps={{ placement: 'bottom' }}
|
tooltipProps={{ placement: 'bottom' }}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<IAIButton
|
<IAIButton
|
||||||
aria-label={t('options:invoke')}
|
aria-label={t('parameters:invoke')}
|
||||||
type="submit"
|
type="submit"
|
||||||
isDisabled={!isReady}
|
isDisabled={!isReady}
|
||||||
onClick={handleClickGenerate}
|
onClick={handleClickGenerate}
|
@ -1,17 +1,14 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { FaRecycle } from 'react-icons/fa';
|
import { FaRecycle } from 'react-icons/fa';
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
import {
|
import { setShouldLoopback } from 'features/parameters/store/postprocessingSlice';
|
||||||
OptionsState,
|
|
||||||
setShouldLoopback,
|
|
||||||
} from 'features/options/store/optionsSlice';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||||
|
|
||||||
const loopbackSelector = createSelector(
|
const loopbackSelector = createSelector(
|
||||||
(state: RootState) => state.options,
|
postprocessingSelector,
|
||||||
(options: OptionsState) => options.shouldLoopback
|
({ shouldLoopback }) => shouldLoopback
|
||||||
);
|
);
|
||||||
|
|
||||||
const LoopbackButton = () => {
|
const LoopbackButton = () => {
|
||||||
@ -22,8 +19,8 @@ const LoopbackButton = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
aria-label={t('options:toggleLoopback')}
|
aria-label={t('parameters:toggleLoopback')}
|
||||||
tooltip={t('options:toggleLoopback')}
|
tooltip={t('parameters:toggleLoopback')}
|
||||||
styleClass="loopback-btn"
|
styleClass="loopback-btn"
|
||||||
asCheckbox={true}
|
asCheckbox={true}
|
||||||
isChecked={shouldLoopback}
|
isChecked={shouldLoopback}
|
@ -2,7 +2,7 @@ import InvokeButton from './InvokeButton';
|
|||||||
import CancelButton from './CancelButton';
|
import CancelButton from './CancelButton';
|
||||||
import LoopbackButton from './Loopback';
|
import LoopbackButton from './Loopback';
|
||||||
import { useAppSelector } from 'app/storeHooks';
|
import { useAppSelector } from 'app/storeHooks';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Buttons to start and cancel image generation.
|
* Buttons to start and cancel image generation.
|
@ -1,12 +1,12 @@
|
|||||||
import { FormControl, Textarea } from '@chakra-ui/react';
|
import { FormControl, Textarea } from '@chakra-ui/react';
|
||||||
import type { RootState } from 'app/store';
|
import type { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import { setNegativePrompt } from 'features/options/store/optionsSlice';
|
import { setNegativePrompt } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export function NegativePromptInput() {
|
const NegativePromptInput = () => {
|
||||||
const negativePrompt = useAppSelector(
|
const negativePrompt = useAppSelector(
|
||||||
(state: RootState) => state.options.negativePrompt
|
(state: RootState) => state.generation.negativePrompt
|
||||||
);
|
);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
@ -20,7 +20,7 @@ export function NegativePromptInput() {
|
|||||||
value={negativePrompt}
|
value={negativePrompt}
|
||||||
onChange={(e) => dispatch(setNegativePrompt(e.target.value))}
|
onChange={(e) => dispatch(setNegativePrompt(e.target.value))}
|
||||||
background="var(--prompt-bg-color)"
|
background="var(--prompt-bg-color)"
|
||||||
placeholder={t('options:negativePrompts')}
|
placeholder={t('parameters:negativePrompts')}
|
||||||
_placeholder={{ fontSize: '0.8rem' }}
|
_placeholder={{ fontSize: '0.8rem' }}
|
||||||
borderColor="var(--border-color)"
|
borderColor="var(--border-color)"
|
||||||
_hover={{
|
_hover={{
|
||||||
@ -35,4 +35,6 @@ export function NegativePromptInput() {
|
|||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default NegativePromptInput;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user