mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into install/refactor-configure-and-model-select
This commit is contained in:
commit
c55bbd1a85
12
.github/workflows/build-container.yml
vendored
12
.github/workflows/build-container.yml
vendored
@ -6,12 +6,12 @@ on:
|
||||
- 'update/ci/docker/*'
|
||||
- 'update/docker/*'
|
||||
paths:
|
||||
- '/pyproject.toml'
|
||||
- '/ldm/**'
|
||||
- '/invokeai/backend/**'
|
||||
- '/invokeai/configs/**'
|
||||
- '/invokeai/frontend/dist/**'
|
||||
- '/docker/Dockerfile'
|
||||
- 'pyproject.toml'
|
||||
- 'ldm/**'
|
||||
- 'invokeai/backend/**'
|
||||
- 'invokeai/configs/**'
|
||||
- 'invokeai/frontend/dist/**'
|
||||
- 'docker/Dockerfile'
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
workflow_dispatch:
|
||||
|
10
.github/workflows/test-invoke-pip-skip.yml
vendored
10
.github/workflows/test-invoke-pip-skip.yml
vendored
@ -2,11 +2,11 @@ name: Test invoke.py pip
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '/pyproject.toml'
|
||||
- '/ldm/**'
|
||||
- '/invokeai/backend/**'
|
||||
- '/invokeai/configs/**'
|
||||
- '/invokeai/frontend/dist/**'
|
||||
- 'pyproject.toml'
|
||||
- 'ldm/**'
|
||||
- 'invokeai/backend/**'
|
||||
- 'invokeai/configs/**'
|
||||
- 'invokeai/frontend/dist/**'
|
||||
merge_group:
|
||||
workflow_dispatch:
|
||||
|
||||
|
20
.github/workflows/test-invoke-pip.yml
vendored
20
.github/workflows/test-invoke-pip.yml
vendored
@ -4,18 +4,18 @@ on:
|
||||
branches:
|
||||
- 'main'
|
||||
paths:
|
||||
- '/pyproject.toml'
|
||||
- '/ldm/**'
|
||||
- '/invokeai/backend/**'
|
||||
- '/invokeai/configs/**'
|
||||
- '/invokeai/frontend/dist/**'
|
||||
- 'pyproject.toml'
|
||||
- 'ldm/**'
|
||||
- 'invokeai/backend/**'
|
||||
- 'invokeai/configs/**'
|
||||
- 'invokeai/frontend/dist/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- '/pyproject.toml'
|
||||
- '/ldm/**'
|
||||
- '/invokeai/backend/**'
|
||||
- '/invokeai/configs/**'
|
||||
- '/invokeai/frontend/dist/**'
|
||||
- 'pyproject.toml'
|
||||
- 'ldm/**'
|
||||
- 'invokeai/backend/**'
|
||||
- 'invokeai/configs/**'
|
||||
- 'invokeai/frontend/dist/**'
|
||||
types:
|
||||
- 'ready_for_review'
|
||||
- 'opened'
|
||||
|
@ -311,7 +311,7 @@ After you save the modified `models.yaml` file relaunch
|
||||
### Installation via the WebUI
|
||||
|
||||
To access the WebUI Model Manager, click on the button that looks like
|
||||
a cute in the upper right side of the browser screen. This will bring
|
||||
a cube in the upper right side of the browser screen. This will bring
|
||||
up a dialogue that lists the models you have already installed, and
|
||||
allows you to load, delete or edit them:
|
||||
|
||||
|
638
invokeai/frontend/dist/assets/index-12bd70ca.js
vendored
638
invokeai/frontend/dist/assets/index-12bd70ca.js
vendored
File diff suppressed because one or more lines are too long
1
invokeai/frontend/dist/assets/index-14cb2922.css
vendored
Normal file
1
invokeai/frontend/dist/assets/index-14cb2922.css
vendored
Normal file
File diff suppressed because one or more lines are too long
638
invokeai/frontend/dist/assets/index-9237ac63.js
vendored
Normal file
638
invokeai/frontend/dist/assets/index-9237ac63.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
4
invokeai/frontend/dist/index.html
vendored
4
invokeai/frontend/dist/index.html
vendored
@ -5,8 +5,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
||||
<link rel="shortcut icon" type="icon" href="./assets/favicon-0d253ced.ico" />
|
||||
<script type="module" crossorigin src="./assets/index-12bd70ca.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index-c1af841f.css">
|
||||
<script type="module" crossorigin src="./assets/index-9237ac63.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index-14cb2922.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -1,10 +1,12 @@
|
||||
{
|
||||
"general": "General",
|
||||
"images": "Images",
|
||||
"steps": "Steps",
|
||||
"cfgScale": "CFG Scale",
|
||||
"width": "Width",
|
||||
"height": "Height",
|
||||
"sampler": "Sampler",
|
||||
"imageToImage": "Image To Image",
|
||||
"seed": "Seed",
|
||||
"randomizeSeed": "Randomize Seed",
|
||||
"shuffle": "Shuffle",
|
||||
|
@ -1,10 +1,12 @@
|
||||
{
|
||||
"general": "General",
|
||||
"images": "Images",
|
||||
"steps": "Steps",
|
||||
"cfgScale": "CFG Scale",
|
||||
"width": "Width",
|
||||
"height": "Height",
|
||||
"sampler": "Sampler",
|
||||
"imageToImage": "Image To Image",
|
||||
"seed": "Seed",
|
||||
"randomizeSeed": "Randomize Seed",
|
||||
"shuffle": "Shuffle",
|
||||
|
@ -5,6 +5,7 @@
|
||||
"confirmOnDelete": "Confirm On Delete",
|
||||
"displayHelpIcons": "Display Help Icons",
|
||||
"useCanvasBeta": "Use Canvas Beta Layout",
|
||||
"useSlidersForAll": "Use Sliders For All Options",
|
||||
"enableImageDebugging": "Enable Image Debugging",
|
||||
"resetWebUI": "Reset Web UI",
|
||||
"resetWebUIDesc1": "Resetting the web UI only resets the browser's local cache of your images and remembered settings. It does not delete any images from disk.",
|
||||
|
@ -1,10 +1,12 @@
|
||||
{
|
||||
"general": "General",
|
||||
"images": "Images",
|
||||
"steps": "Steps",
|
||||
"cfgScale": "CFG Scale",
|
||||
"width": "Width",
|
||||
"height": "Height",
|
||||
"sampler": "Sampler",
|
||||
"imageToImage": "Image To Image",
|
||||
"seed": "Seed",
|
||||
"randomizeSeed": "Randomize Seed",
|
||||
"shuffle": "Shuffle",
|
||||
|
@ -1,10 +1,12 @@
|
||||
{
|
||||
"general": "General",
|
||||
"images": "Images",
|
||||
"steps": "Steps",
|
||||
"cfgScale": "CFG Scale",
|
||||
"width": "Width",
|
||||
"height": "Height",
|
||||
"sampler": "Sampler",
|
||||
"imageToImage": "Image To Image",
|
||||
"seed": "Seed",
|
||||
"randomizeSeed": "Randomize Seed",
|
||||
"shuffle": "Shuffle",
|
||||
|
@ -5,6 +5,7 @@
|
||||
"confirmOnDelete": "Confirm On Delete",
|
||||
"displayHelpIcons": "Display Help Icons",
|
||||
"useCanvasBeta": "Use Canvas Beta Layout",
|
||||
"useSlidersForAll": "Use Sliders For All Options",
|
||||
"enableImageDebugging": "Enable Image Debugging",
|
||||
"resetWebUI": "Reset Web UI",
|
||||
"resetWebUIDesc1": "Resetting the web UI only resets the browser's local cache of your images and remembered settings. It does not delete any images from disk.",
|
||||
|
@ -6,7 +6,6 @@
|
||||
min-width: max-content;
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-color-secondary);
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ export default function IAISlider(props: IAIFullSliderProps) {
|
||||
tooltipSuffix = '',
|
||||
withSliderMarks = false,
|
||||
sliderMarkLeftOffset = 0,
|
||||
sliderMarkRightOffset = -7,
|
||||
sliderMarkRightOffset = -1,
|
||||
withInput = false,
|
||||
isInteger = false,
|
||||
inputWidth = '5.5rem',
|
||||
@ -164,6 +164,7 @@ export default function IAISlider(props: IAIFullSliderProps) {
|
||||
>
|
||||
<FormLabel
|
||||
className="invokeai__slider-component-label"
|
||||
fontSize="sm"
|
||||
{...sliderFormLabelProps}
|
||||
>
|
||||
{label}
|
||||
|
55
invokeai/frontend/src/common/components/SubItemHook.tsx
Normal file
55
invokeai/frontend/src/common/components/SubItemHook.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
|
||||
interface SubItemHookProps {
|
||||
active?: boolean;
|
||||
width?: string | number;
|
||||
height?: string | number;
|
||||
side?: 'left' | 'right';
|
||||
}
|
||||
|
||||
export default function SubItemHook(props: SubItemHookProps) {
|
||||
const {
|
||||
active = true,
|
||||
width = '1rem',
|
||||
height = '1.3rem',
|
||||
side = 'right',
|
||||
} = props;
|
||||
return (
|
||||
<>
|
||||
{side === 'right' && (
|
||||
<Box
|
||||
width={width}
|
||||
height={height}
|
||||
margin="-0.5rem 0.5rem 0 0.5rem"
|
||||
borderLeft={
|
||||
active
|
||||
? '3px solid var(--subhook-color)'
|
||||
: '3px solid var(--tab-hover-color)'
|
||||
}
|
||||
borderBottom={
|
||||
active
|
||||
? '3px solid var(--subhook-color)'
|
||||
: '3px solid var(--tab-hover-color)'
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{side === 'left' && (
|
||||
<Box
|
||||
width={width}
|
||||
height={height}
|
||||
margin="-0.5rem 0.5rem 0 0.5rem"
|
||||
borderRight={
|
||||
active
|
||||
? '3px solid var(--subhook-color)'
|
||||
: '3px solid var(--tab-hover-color)'
|
||||
}
|
||||
borderBottom={
|
||||
active
|
||||
? '3px solid var(--subhook-color)'
|
||||
: '3px solid var(--tab-hover-color)'
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
@ -170,6 +170,9 @@ export const frontendToBackendParameters = (
|
||||
let esrganParameters: false | BackendEsrGanParameters = false;
|
||||
let facetoolParameters: false | BackendFacetoolParameters = false;
|
||||
|
||||
// Multiplying it by 10000 so the Slider can have values between 0 and 1 which makes more sense
|
||||
generationParameters.threshold = threshold * 1000;
|
||||
|
||||
if (negativePrompt !== '') {
|
||||
generationParameters.prompt = `${prompt} [${negativePrompt}]`;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ const BoundingBoxSettings = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex direction="column" gap="1rem">
|
||||
<Flex direction="column" gap={2}>
|
||||
<IAISlider
|
||||
label={t('parameters:width')}
|
||||
min={64}
|
||||
@ -82,6 +82,7 @@ const BoundingBoxSettings = () => {
|
||||
inputReadOnly
|
||||
withReset
|
||||
handleReset={handleResetWidth}
|
||||
sliderMarkRightOffset={-7}
|
||||
/>
|
||||
<IAISlider
|
||||
label={t('parameters:height')}
|
||||
@ -96,6 +97,7 @@ const BoundingBoxSettings = () => {
|
||||
inputReadOnly
|
||||
withReset
|
||||
handleReset={handleResetHeight}
|
||||
sliderMarkRightOffset={-7}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
|
@ -107,7 +107,7 @@ const InfillAndScalingSettings = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex direction="column" gap="1rem">
|
||||
<Flex direction="column" gap={4}>
|
||||
<IAISelect
|
||||
label={t('parameters:scaleBeforeProcessing')}
|
||||
validValues={BOUNDING_BOX_SCALES_DICT}
|
||||
@ -130,6 +130,7 @@ const InfillAndScalingSettings = () => {
|
||||
inputReadOnly
|
||||
withReset
|
||||
handleReset={handleResetScaledWidth}
|
||||
sliderMarkRightOffset={-7}
|
||||
/>
|
||||
<IAISlider
|
||||
isInputDisabled={!isManual}
|
||||
@ -147,6 +148,7 @@ const InfillAndScalingSettings = () => {
|
||||
inputReadOnly
|
||||
withReset
|
||||
handleReset={handleResetScaledHeight}
|
||||
sliderMarkRightOffset={-7}
|
||||
/>
|
||||
<IAISelect
|
||||
label={t('parameters:infillMethod')}
|
||||
|
@ -6,7 +6,7 @@ import SeamStrength from './SeamStrength';
|
||||
|
||||
const SeamCorrectionSettings = () => {
|
||||
return (
|
||||
<Flex direction="column" gap="1rem">
|
||||
<Flex direction="column" gap={2}>
|
||||
<SeamSize />
|
||||
<SeamBlur />
|
||||
<SeamStrength />
|
||||
|
@ -0,0 +1,36 @@
|
||||
import type { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setCodeformerFidelity } from 'features/parameters/store/postprocessingSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function CodeformerFidelity() {
|
||||
const isGFPGANAvailable = useAppSelector(
|
||||
(state: RootState) => state.system.isGFPGANAvailable
|
||||
);
|
||||
|
||||
const codeformerFidelity = useAppSelector(
|
||||
(state: RootState) => state.postprocessing.codeformerFidelity
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
return (
|
||||
<IAISlider
|
||||
isSliderDisabled={!isGFPGANAvailable}
|
||||
isInputDisabled={!isGFPGANAvailable}
|
||||
isResetDisabled={!isGFPGANAvailable}
|
||||
label={t('parameters:codeformerFidelity')}
|
||||
step={0.05}
|
||||
min={0}
|
||||
max={1}
|
||||
onChange={(v) => dispatch(setCodeformerFidelity(v))}
|
||||
handleReset={() => dispatch(setCodeformerFidelity(1))}
|
||||
value={codeformerFidelity}
|
||||
withReset
|
||||
withSliderMarks
|
||||
withInput
|
||||
/>
|
||||
);
|
||||
}
|
@ -1,99 +1,23 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
|
||||
import { FacetoolType } from 'features/parameters/store/postprocessingSlice';
|
||||
|
||||
import {
|
||||
setCodeformerFidelity,
|
||||
setFacetoolStrength,
|
||||
setFacetoolType,
|
||||
} from 'features/parameters/store/postprocessingSlice';
|
||||
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { FACETOOL_TYPES } from 'app/constants';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
import IAISelect from 'common/components/IAISelect';
|
||||
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||
import { isEqual } from 'lodash';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const optionsSelector = createSelector(
|
||||
[postprocessingSelector, systemSelector],
|
||||
(
|
||||
{ facetoolStrength, facetoolType, codeformerFidelity },
|
||||
{ isGFPGANAvailable }
|
||||
) => {
|
||||
return {
|
||||
facetoolStrength,
|
||||
facetoolType,
|
||||
codeformerFidelity,
|
||||
isGFPGANAvailable,
|
||||
};
|
||||
},
|
||||
{
|
||||
memoizeOptions: {
|
||||
resultEqualityCheck: isEqual,
|
||||
},
|
||||
}
|
||||
);
|
||||
import { useAppSelector } from 'app/storeHooks';
|
||||
import type { RootState } from 'app/store';
|
||||
import FaceRestoreType from './FaceRestoreType';
|
||||
import FaceRestoreStrength from './FaceRestoreStrength';
|
||||
import CodeformerFidelity from './CodeformerFidelity';
|
||||
|
||||
/**
|
||||
* Displays face-fixing/GFPGAN options (strength).
|
||||
*/
|
||||
const FaceRestoreSettings = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const {
|
||||
facetoolStrength,
|
||||
facetoolType,
|
||||
codeformerFidelity,
|
||||
isGFPGANAvailable,
|
||||
} = useAppSelector(optionsSelector);
|
||||
|
||||
const handleChangeStrength = (v: number) => dispatch(setFacetoolStrength(v));
|
||||
|
||||
const handleChangeCodeformerFidelity = (v: number) =>
|
||||
dispatch(setCodeformerFidelity(v));
|
||||
|
||||
const handleChangeFacetoolType = (e: ChangeEvent<HTMLSelectElement>) =>
|
||||
dispatch(setFacetoolType(e.target.value as FacetoolType));
|
||||
|
||||
const { t } = useTranslation();
|
||||
const facetoolType = useAppSelector(
|
||||
(state: RootState) => state.postprocessing.facetoolType
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex direction="column" gap={2}>
|
||||
<IAISelect
|
||||
label={t('parameters:type')}
|
||||
validValues={FACETOOL_TYPES.concat()}
|
||||
value={facetoolType}
|
||||
onChange={handleChangeFacetoolType}
|
||||
/>
|
||||
<IAINumberInput
|
||||
isDisabled={!isGFPGANAvailable}
|
||||
label={t('parameters:strength')}
|
||||
step={0.05}
|
||||
min={0}
|
||||
max={1}
|
||||
onChange={handleChangeStrength}
|
||||
value={facetoolStrength}
|
||||
width="90px"
|
||||
isInteger={false}
|
||||
/>
|
||||
{facetoolType === 'codeformer' && (
|
||||
<IAINumberInput
|
||||
isDisabled={!isGFPGANAvailable}
|
||||
label={t('parameters:codeformerFidelity')}
|
||||
step={0.05}
|
||||
min={0}
|
||||
max={1}
|
||||
onChange={handleChangeCodeformerFidelity}
|
||||
value={codeformerFidelity}
|
||||
width="90px"
|
||||
isInteger={false}
|
||||
/>
|
||||
)}
|
||||
<Flex direction="column" gap={2} minWidth="20rem">
|
||||
<FaceRestoreType />
|
||||
<FaceRestoreStrength />
|
||||
{facetoolType === 'codeformer' && <CodeformerFidelity />}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,36 @@
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setFacetoolStrength } from 'features/parameters/store/postprocessingSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function FaceRestoreStrength() {
|
||||
const isGFPGANAvailable = useAppSelector(
|
||||
(state: RootState) => state.system.isGFPGANAvailable
|
||||
);
|
||||
|
||||
const facetoolStrength = useAppSelector(
|
||||
(state: RootState) => state.postprocessing.facetoolStrength
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
return (
|
||||
<IAISlider
|
||||
isSliderDisabled={!isGFPGANAvailable}
|
||||
isInputDisabled={!isGFPGANAvailable}
|
||||
isResetDisabled={!isGFPGANAvailable}
|
||||
label={t('parameters:strength')}
|
||||
step={0.05}
|
||||
min={0}
|
||||
max={1}
|
||||
onChange={(v) => dispatch(setFacetoolStrength(v))}
|
||||
handleReset={() => dispatch(setFacetoolStrength(0.75))}
|
||||
value={facetoolStrength}
|
||||
withReset
|
||||
withSliderMarks
|
||||
withInput
|
||||
/>
|
||||
);
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
import { FACETOOL_TYPES } from 'app/constants';
|
||||
import { type RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAISelect from 'common/components/IAISelect';
|
||||
import {
|
||||
type FacetoolType,
|
||||
setFacetoolType,
|
||||
} from 'features/parameters/store/postprocessingSlice';
|
||||
import { type ChangeEvent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function FaceRestoreType() {
|
||||
const facetoolType = useAppSelector(
|
||||
(state: RootState) => state.postprocessing.facetoolType
|
||||
);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChangeFacetoolType = (e: ChangeEvent<HTMLSelectElement>) =>
|
||||
dispatch(setFacetoolType(e.target.value as FacetoolType));
|
||||
|
||||
return (
|
||||
<IAISelect
|
||||
label={t('parameters:type')}
|
||||
validValues={FACETOOL_TYPES.concat()}
|
||||
value={facetoolType}
|
||||
onChange={handleChangeFacetoolType}
|
||||
/>
|
||||
);
|
||||
}
|
@ -4,6 +4,7 @@ import type { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import IAISwitch from 'common/components/IAISwitch';
|
||||
import SubItemHook from 'common/components/SubItemHook';
|
||||
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||
import {
|
||||
setHiresFix,
|
||||
@ -39,23 +40,27 @@ const HiresStrength = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<IAISlider
|
||||
label={t('parameters:hiresStrength')}
|
||||
step={0.01}
|
||||
min={0.01}
|
||||
max={0.99}
|
||||
onChange={handleHiresStrength}
|
||||
value={hiresStrength}
|
||||
isInteger={false}
|
||||
withInput
|
||||
withSliderMarks
|
||||
inputWidth="5.5rem"
|
||||
withReset
|
||||
handleReset={handleHiResStrengthReset}
|
||||
isSliderDisabled={!hiresFix}
|
||||
isInputDisabled={!hiresFix}
|
||||
isResetDisabled={!hiresFix}
|
||||
/>
|
||||
<Flex>
|
||||
<SubItemHook active={hiresFix} />
|
||||
<IAISlider
|
||||
label={t('parameters:hiresStrength')}
|
||||
step={0.01}
|
||||
min={0.01}
|
||||
max={0.99}
|
||||
onChange={handleHiresStrength}
|
||||
value={hiresStrength}
|
||||
isInteger={false}
|
||||
withInput
|
||||
withSliderMarks
|
||||
inputWidth={'5.5rem'}
|
||||
withReset
|
||||
handleReset={handleHiResStrengthReset}
|
||||
isSliderDisabled={!hiresFix}
|
||||
isInputDisabled={!hiresFix}
|
||||
isResetDisabled={!hiresFix}
|
||||
sliderMarkRightOffset={-7}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@ -75,7 +80,7 @@ const HiresSettings = () => {
|
||||
dispatch(setHiresFix(e.target.checked));
|
||||
|
||||
return (
|
||||
<Flex gap={2} direction="column">
|
||||
<Flex rowGap="0.8rem" direction={'column'}>
|
||||
<IAISwitch
|
||||
label={t('parameters:hiresOptim')}
|
||||
fontSize="md"
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setPerlin } from 'features/parameters/store/generationSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -9,17 +9,18 @@ export default function Perlin() {
|
||||
const perlin = useAppSelector((state: RootState) => state.generation.perlin);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChangePerlin = (v: number) => dispatch(setPerlin(v));
|
||||
|
||||
return (
|
||||
<IAINumberInput
|
||||
<IAISlider
|
||||
label={t('parameters:perlinNoise')}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.05}
|
||||
onChange={handleChangePerlin}
|
||||
onChange={(v) => dispatch(setPerlin(v))}
|
||||
handleReset={() => dispatch(setPerlin(0))}
|
||||
value={perlin}
|
||||
isInteger={false}
|
||||
withInput
|
||||
withReset
|
||||
withSliderMarks
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setThreshold } from 'features/parameters/store/generationSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -11,17 +11,19 @@ export default function Threshold() {
|
||||
);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChangeThreshold = (v: number) => dispatch(setThreshold(v));
|
||||
|
||||
return (
|
||||
<IAINumberInput
|
||||
<IAISlider
|
||||
label={t('parameters:noiseThreshold')}
|
||||
min={0}
|
||||
max={1000}
|
||||
step={0.1}
|
||||
onChange={handleChangeThreshold}
|
||||
max={1}
|
||||
step={0.005}
|
||||
onChange={(v) => dispatch(setThreshold(v))}
|
||||
handleReset={() => dispatch(setThreshold(0))}
|
||||
value={threshold}
|
||||
isInteger={false}
|
||||
withInput
|
||||
withReset
|
||||
withSliderMarks
|
||||
inputWidth="6rem"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setUpscalingDenoising } from 'features/parameters/store/postprocessingSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function UpscaleDenoisingStrength() {
|
||||
const isESRGANAvailable = useAppSelector(
|
||||
(state: RootState) => state.system.isESRGANAvailable
|
||||
);
|
||||
|
||||
const upscalingDenoising = useAppSelector(
|
||||
(state: RootState) => state.postprocessing.upscalingDenoising
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
return (
|
||||
<IAISlider
|
||||
label={t('parameters:denoisingStrength')}
|
||||
value={upscalingDenoising}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.01}
|
||||
onChange={(v) => {
|
||||
dispatch(setUpscalingDenoising(v));
|
||||
}}
|
||||
handleReset={() => dispatch(setUpscalingDenoising(0.75))}
|
||||
withSliderMarks
|
||||
withInput
|
||||
withReset
|
||||
isSliderDisabled={!isESRGANAvailable}
|
||||
isInputDisabled={!isESRGANAvailable}
|
||||
isResetDisabled={!isESRGANAvailable}
|
||||
/>
|
||||
);
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
import { UPSCALING_LEVELS } from 'app/constants';
|
||||
import type { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAISelect from 'common/components/IAISelect';
|
||||
import {
|
||||
setUpscalingLevel,
|
||||
type UpscalingLevel,
|
||||
} from 'features/parameters/store/postprocessingSlice';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function UpscaleScale() {
|
||||
const isESRGANAvailable = useAppSelector(
|
||||
(state: RootState) => state.system.isESRGANAvailable
|
||||
);
|
||||
|
||||
const upscalingLevel = useAppSelector(
|
||||
(state: RootState) => state.postprocessing.upscalingLevel
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleChangeLevel = (e: ChangeEvent<HTMLSelectElement>) =>
|
||||
dispatch(setUpscalingLevel(Number(e.target.value) as UpscalingLevel));
|
||||
|
||||
return (
|
||||
<IAISelect
|
||||
isDisabled={!isESRGANAvailable}
|
||||
label={t('parameters:scale')}
|
||||
value={upscalingLevel}
|
||||
onChange={handleChangeLevel}
|
||||
validValues={UPSCALING_LEVELS}
|
||||
/>
|
||||
);
|
||||
}
|
@ -1,104 +1,17 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
|
||||
import {
|
||||
setUpscalingDenoising,
|
||||
setUpscalingLevel,
|
||||
setUpscalingStrength,
|
||||
UpscalingLevel,
|
||||
} from 'features/parameters/store/postprocessingSlice';
|
||||
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { UPSCALING_LEVELS } from 'app/constants';
|
||||
import IAISelect from 'common/components/IAISelect';
|
||||
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||
import { isEqual } from 'lodash';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
|
||||
const parametersSelector = createSelector(
|
||||
[postprocessingSelector, systemSelector],
|
||||
|
||||
(
|
||||
{ upscalingLevel, upscalingStrength, upscalingDenoising },
|
||||
{ isESRGANAvailable }
|
||||
) => {
|
||||
return {
|
||||
upscalingLevel,
|
||||
upscalingDenoising,
|
||||
upscalingStrength,
|
||||
isESRGANAvailable,
|
||||
};
|
||||
},
|
||||
{
|
||||
memoizeOptions: {
|
||||
resultEqualityCheck: isEqual,
|
||||
},
|
||||
}
|
||||
);
|
||||
import UpscaleDenoisingStrength from './UpscaleDenoisingStrength';
|
||||
import UpscaleStrength from './UpscaleStrength';
|
||||
import UpscaleScale from './UpscaleScale';
|
||||
|
||||
/**
|
||||
* Displays upscaling/ESRGAN options (level and strength).
|
||||
*/
|
||||
const UpscaleSettings = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const {
|
||||
upscalingLevel,
|
||||
upscalingStrength,
|
||||
upscalingDenoising,
|
||||
isESRGANAvailable,
|
||||
} = useAppSelector(parametersSelector);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChangeLevel = (e: ChangeEvent<HTMLSelectElement>) =>
|
||||
dispatch(setUpscalingLevel(Number(e.target.value) as UpscalingLevel));
|
||||
|
||||
const handleChangeStrength = (v: number) => dispatch(setUpscalingStrength(v));
|
||||
|
||||
return (
|
||||
<Flex flexDir="column" rowGap="1rem" minWidth="20rem">
|
||||
<IAISelect
|
||||
isDisabled={!isESRGANAvailable}
|
||||
label={t('parameters:scale')}
|
||||
value={upscalingLevel}
|
||||
onChange={handleChangeLevel}
|
||||
validValues={UPSCALING_LEVELS}
|
||||
/>
|
||||
<IAISlider
|
||||
label={t('parameters:denoisingStrength')}
|
||||
value={upscalingDenoising}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.01}
|
||||
onChange={(v) => {
|
||||
dispatch(setUpscalingDenoising(v));
|
||||
}}
|
||||
handleReset={() => dispatch(setUpscalingDenoising(0.75))}
|
||||
withSliderMarks
|
||||
withInput
|
||||
withReset
|
||||
isSliderDisabled={!isESRGANAvailable}
|
||||
isInputDisabled={!isESRGANAvailable}
|
||||
isResetDisabled={!isESRGANAvailable}
|
||||
/>
|
||||
<IAISlider
|
||||
label={`${t('parameters:upscale')} ${t('parameters:strength')}`}
|
||||
value={upscalingStrength}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.05}
|
||||
onChange={handleChangeStrength}
|
||||
handleReset={() => dispatch(setUpscalingStrength(0.75))}
|
||||
withSliderMarks
|
||||
withInput
|
||||
withReset
|
||||
isSliderDisabled={!isESRGANAvailable}
|
||||
isInputDisabled={!isESRGANAvailable}
|
||||
isResetDisabled={!isESRGANAvailable}
|
||||
/>
|
||||
<Flex flexDir="column" rowGap={2} minWidth="20rem">
|
||||
<UpscaleScale />
|
||||
<UpscaleDenoisingStrength />
|
||||
<UpscaleStrength />
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,35 @@
|
||||
import type { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setUpscalingStrength } from 'features/parameters/store/postprocessingSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function UpscaleStrength() {
|
||||
const isESRGANAvailable = useAppSelector(
|
||||
(state: RootState) => state.system.isESRGANAvailable
|
||||
);
|
||||
const upscalingStrength = useAppSelector(
|
||||
(state: RootState) => state.postprocessing.upscalingStrength
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
return (
|
||||
<IAISlider
|
||||
label={`${t('parameters:upscale')} ${t('parameters:strength')}`}
|
||||
value={upscalingStrength}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.05}
|
||||
onChange={(v) => dispatch(setUpscalingStrength(v))}
|
||||
handleReset={() => dispatch(setUpscalingStrength(0.75))}
|
||||
withSliderMarks
|
||||
withInput
|
||||
withReset
|
||||
isSliderDisabled={!isESRGANAvailable}
|
||||
isInputDisabled={!isESRGANAvailable}
|
||||
isResetDisabled={!isESRGANAvailable}
|
||||
/>
|
||||
);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setVariationAmount } from 'features/parameters/store/generationSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -16,19 +16,22 @@ export default function VariationAmount() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const handleChangevariationAmount = (v: number) =>
|
||||
dispatch(setVariationAmount(v));
|
||||
|
||||
return (
|
||||
<IAINumberInput
|
||||
<IAISlider
|
||||
label={t('parameters:variationAmount')}
|
||||
value={variationAmount}
|
||||
step={0.01}
|
||||
min={0}
|
||||
max={1}
|
||||
isDisabled={!shouldGenerateVariations}
|
||||
onChange={handleChangevariationAmount}
|
||||
isInteger={false}
|
||||
isSliderDisabled={!shouldGenerateVariations}
|
||||
isInputDisabled={!shouldGenerateVariations}
|
||||
isResetDisabled={!shouldGenerateVariations}
|
||||
onChange={(v) => dispatch(setVariationAmount(v))}
|
||||
handleReset={() => dispatch(setVariationAmount(0.1))}
|
||||
withInput
|
||||
withReset
|
||||
withSliderMarks
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setCfgScale } from 'features/parameters/store/generationSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -9,11 +10,29 @@ export default function MainCFGScale() {
|
||||
const cfgScale = useAppSelector(
|
||||
(state: RootState) => state.generation.cfgScale
|
||||
);
|
||||
const shouldUseSliders = useAppSelector(
|
||||
(state: RootState) => state.ui.shouldUseSliders
|
||||
);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChangeCfgScale = (v: number) => dispatch(setCfgScale(v));
|
||||
|
||||
return (
|
||||
return shouldUseSliders ? (
|
||||
<IAISlider
|
||||
label={t('parameters:cfgScale')}
|
||||
step={0.5}
|
||||
min={1.01}
|
||||
max={30}
|
||||
onChange={handleChangeCfgScale}
|
||||
handleReset={() => dispatch(setCfgScale(7.5))}
|
||||
value={cfgScale}
|
||||
sliderMarkRightOffset={-5}
|
||||
sliderNumberInputProps={{ max: 200 }}
|
||||
withInput
|
||||
withReset
|
||||
withSliderMarks
|
||||
/>
|
||||
) : (
|
||||
<IAINumberInput
|
||||
label={t('parameters:cfgScale')}
|
||||
step={0.5}
|
||||
|
@ -2,29 +2,50 @@ import { HEIGHTS } from 'app/constants';
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAISelect from 'common/components/IAISelect';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setHeight } from 'features/parameters/store/generationSlice';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import { ChangeEvent } from 'react';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function MainHeight() {
|
||||
const height = useAppSelector((state: RootState) => state.generation.height);
|
||||
const shouldUseSliders = useAppSelector(
|
||||
(state: RootState) => state.ui.shouldUseSliders
|
||||
);
|
||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChangeHeight = (e: ChangeEvent<HTMLSelectElement>) =>
|
||||
dispatch(setHeight(Number(e.target.value)));
|
||||
|
||||
return (
|
||||
return shouldUseSliders ? (
|
||||
<IAISlider
|
||||
isSliderDisabled={activeTabName === 'unifiedCanvas'}
|
||||
isInputDisabled={activeTabName === 'unifiedCanvas'}
|
||||
isResetDisabled={activeTabName === 'unifiedCanvas'}
|
||||
label={t('parameters:height')}
|
||||
value={height}
|
||||
min={64}
|
||||
step={64}
|
||||
max={2048}
|
||||
onChange={(v) => dispatch(setHeight(v))}
|
||||
handleReset={() => dispatch(setHeight(512))}
|
||||
withInput
|
||||
withReset
|
||||
withSliderMarks
|
||||
sliderMarkRightOffset={-8}
|
||||
inputWidth="6.2rem"
|
||||
sliderNumberInputProps={{ max: 15360 }}
|
||||
/>
|
||||
) : (
|
||||
<IAISelect
|
||||
isDisabled={activeTabName === 'unifiedCanvas'}
|
||||
label={t('parameters:height')}
|
||||
value={height}
|
||||
flexGrow={1}
|
||||
onChange={handleChangeHeight}
|
||||
onChange={(e) => dispatch(setHeight(Number(e.target.value)))}
|
||||
validValues={HEIGHTS}
|
||||
styleClass="main-settings-block"
|
||||
width="5.5rem"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1,39 +1,41 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import type { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
import {
|
||||
GenerationState,
|
||||
setIterations,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { isEqual } from 'lodash';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setIterations } from 'features/parameters/store/generationSlice';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const mainIterationsSelector = createSelector(
|
||||
[(state: RootState) => state.generation],
|
||||
(parameters: GenerationState) => {
|
||||
const { iterations } = parameters;
|
||||
|
||||
return {
|
||||
iterations,
|
||||
};
|
||||
},
|
||||
{
|
||||
memoizeOptions: {
|
||||
resultEqualityCheck: isEqual,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export default function MainIterations() {
|
||||
const iterations = useAppSelector(
|
||||
(state: RootState) => state.generation.iterations
|
||||
);
|
||||
|
||||
const shouldUseSliders = useAppSelector(
|
||||
(state: RootState) => state.ui.shouldUseSliders
|
||||
);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { iterations } = useAppSelector(mainIterationsSelector);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChangeIterations = (v: number) => dispatch(setIterations(v));
|
||||
|
||||
return (
|
||||
return shouldUseSliders ? (
|
||||
<IAISlider
|
||||
label={t('parameters:images')}
|
||||
step={1}
|
||||
min={1}
|
||||
max={16}
|
||||
onChange={handleChangeIterations}
|
||||
handleReset={() => dispatch(setIterations(1))}
|
||||
value={iterations}
|
||||
withInput
|
||||
withReset
|
||||
withSliderMarks
|
||||
sliderMarkRightOffset={-5}
|
||||
sliderNumberInputProps={{ max: 9999 }}
|
||||
/>
|
||||
) : (
|
||||
<IAINumberInput
|
||||
label={t('parameters:images')}
|
||||
step={1}
|
||||
|
@ -1,3 +1,8 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { type RootState } from 'app/store';
|
||||
import { useAppSelector } from 'app/storeHooks';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import ParametersAccordion from '../ParametersAccordion';
|
||||
import MainCFGScale from './MainCFGScale';
|
||||
import MainHeight from './MainHeight';
|
||||
import MainIterations from './MainIterations';
|
||||
@ -8,20 +13,40 @@ import MainWidth from './MainWidth';
|
||||
export const inputWidth = 'auto';
|
||||
|
||||
export default function MainSettings() {
|
||||
return (
|
||||
<div className="main-settings">
|
||||
<div className="main-settings-list">
|
||||
<div className="main-settings-row">
|
||||
const { t } = useTranslation();
|
||||
|
||||
const shouldUseSliders = useAppSelector(
|
||||
(state: RootState) => state.ui.shouldUseSliders
|
||||
);
|
||||
|
||||
const accordionItems = {
|
||||
main: {
|
||||
header: `${t('parameters:general')}`,
|
||||
feature: undefined,
|
||||
content: shouldUseSliders ? (
|
||||
<Flex flexDir="column" rowGap={2}>
|
||||
<MainIterations />
|
||||
<MainSteps />
|
||||
<MainCFGScale />
|
||||
</div>
|
||||
<div className="main-settings-row">
|
||||
<MainWidth />
|
||||
<MainHeight />
|
||||
<MainSampler />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
</Flex>
|
||||
) : (
|
||||
<Flex flexDirection="column" rowGap={2}>
|
||||
<Flex gap={2}>
|
||||
<MainIterations />
|
||||
<MainSteps />
|
||||
<MainCFGScale />
|
||||
</Flex>
|
||||
<Flex>
|
||||
<MainWidth />
|
||||
<MainHeight />
|
||||
<MainSampler />
|
||||
</Flex>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
};
|
||||
return <ParametersAccordion accordionInfo={accordionItems} />;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ export default function MainSampler() {
|
||||
activeModel.format === 'diffusers' ? DIFFUSERS_SAMPLERS : SAMPLERS
|
||||
}
|
||||
styleClass="main-settings-block"
|
||||
minWidth="9rem"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1,17 +1,36 @@
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setSteps } from 'features/parameters/store/generationSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function MainSteps() {
|
||||
const dispatch = useAppDispatch();
|
||||
const steps = useAppSelector((state: RootState) => state.generation.steps);
|
||||
const shouldUseSliders = useAppSelector(
|
||||
(state: RootState) => state.ui.shouldUseSliders
|
||||
);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChangeSteps = (v: number) => dispatch(setSteps(v));
|
||||
|
||||
return (
|
||||
return shouldUseSliders ? (
|
||||
<IAISlider
|
||||
label={t('parameters:steps')}
|
||||
min={1}
|
||||
step={1}
|
||||
onChange={handleChangeSteps}
|
||||
handleReset={() => dispatch(setSteps(20))}
|
||||
value={steps}
|
||||
withInput
|
||||
withReset
|
||||
withSliderMarks
|
||||
sliderMarkRightOffset={-6}
|
||||
sliderNumberInputProps={{ max: 9999 }}
|
||||
/>
|
||||
) : (
|
||||
<IAINumberInput
|
||||
label={t('parameters:steps')}
|
||||
min={1}
|
||||
|
@ -2,30 +2,51 @@ import { WIDTHS } from 'app/constants';
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAISelect from 'common/components/IAISelect';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setWidth } from 'features/parameters/store/generationSlice';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function MainWidth() {
|
||||
const width = useAppSelector((state: RootState) => state.generation.width);
|
||||
const shouldUseSliders = useAppSelector(
|
||||
(state: RootState) => state.ui.shouldUseSliders
|
||||
);
|
||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleChangeWidth = (e: ChangeEvent<HTMLSelectElement>) =>
|
||||
dispatch(setWidth(Number(e.target.value)));
|
||||
|
||||
return (
|
||||
return shouldUseSliders ? (
|
||||
<IAISlider
|
||||
isSliderDisabled={activeTabName === 'unifiedCanvas'}
|
||||
isInputDisabled={activeTabName === 'unifiedCanvas'}
|
||||
isResetDisabled={activeTabName === 'unifiedCanvas'}
|
||||
label={t('parameters:width')}
|
||||
value={width}
|
||||
min={64}
|
||||
step={64}
|
||||
max={2048}
|
||||
onChange={(v) => dispatch(setWidth(v))}
|
||||
handleReset={() => dispatch(setWidth(512))}
|
||||
withInput
|
||||
withReset
|
||||
withSliderMarks
|
||||
sliderMarkRightOffset={-8}
|
||||
inputWidth="6.2rem"
|
||||
inputReadOnly
|
||||
sliderNumberInputProps={{ max: 15360 }}
|
||||
/>
|
||||
) : (
|
||||
<IAISelect
|
||||
isDisabled={activeTabName === 'unifiedCanvas'}
|
||||
label={t('parameters:width')}
|
||||
value={width}
|
||||
flexGrow={1}
|
||||
onChange={handleChangeWidth}
|
||||
onChange={(e) => dispatch(setWidth(Number(e.target.value)))}
|
||||
validValues={WIDTHS}
|
||||
styleClass="main-settings-block"
|
||||
width="5.5rem"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ export interface PostprocessingState {
|
||||
|
||||
const initialPostprocessingState: PostprocessingState = {
|
||||
codeformerFidelity: 0.75,
|
||||
facetoolStrength: 0.8,
|
||||
facetoolStrength: 0.75,
|
||||
facetoolType: 'gfpgan',
|
||||
hiresFix: false,
|
||||
hiresStrength: 0.75,
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
} from '@chakra-ui/react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { IN_PROGRESS_IMAGE_TYPES } from 'app/constants';
|
||||
import { RootState } from 'app/store';
|
||||
import { type RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
import IAISelect from 'common/components/IAISelect';
|
||||
@ -27,9 +27,14 @@ import {
|
||||
setShouldConfirmOnDelete,
|
||||
setShouldDisplayGuides,
|
||||
setShouldDisplayInProgressType,
|
||||
type SystemState,
|
||||
} from 'features/system/store/systemSlice';
|
||||
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||
import { setShouldUseCanvasBetaLayout } from 'features/ui/store/uiSlice';
|
||||
import {
|
||||
setShouldUseCanvasBetaLayout,
|
||||
setShouldUseSliders,
|
||||
} from 'features/ui/store/uiSlice';
|
||||
import { type UIState } from 'features/ui/store/uiTypes';
|
||||
import { isEqual, map } from 'lodash';
|
||||
import { persistor } from 'persistor';
|
||||
import { ChangeEvent, cloneElement, ReactElement } from 'react';
|
||||
@ -37,7 +42,7 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
const selector = createSelector(
|
||||
[systemSelector, uiSelector],
|
||||
(system, ui) => {
|
||||
(system: SystemState, ui: UIState) => {
|
||||
const {
|
||||
shouldDisplayInProgressType,
|
||||
shouldConfirmOnDelete,
|
||||
@ -47,7 +52,7 @@ const selector = createSelector(
|
||||
enableImageDebugging,
|
||||
} = system;
|
||||
|
||||
const { shouldUseCanvasBetaLayout } = ui;
|
||||
const { shouldUseCanvasBetaLayout, shouldUseSliders } = ui;
|
||||
|
||||
return {
|
||||
shouldDisplayInProgressType,
|
||||
@ -57,6 +62,7 @@ const selector = createSelector(
|
||||
saveIntermediatesInterval,
|
||||
enableImageDebugging,
|
||||
shouldUseCanvasBetaLayout,
|
||||
shouldUseSliders,
|
||||
};
|
||||
},
|
||||
{
|
||||
@ -100,6 +106,7 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
|
||||
saveIntermediatesInterval,
|
||||
enableImageDebugging,
|
||||
shouldUseCanvasBetaLayout,
|
||||
shouldUseSliders,
|
||||
} = useAppSelector(selector);
|
||||
|
||||
/**
|
||||
@ -191,6 +198,14 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
|
||||
dispatch(setShouldUseCanvasBetaLayout(e.target.checked))
|
||||
}
|
||||
/>
|
||||
<IAISwitch
|
||||
styleClass="settings-modal-item"
|
||||
label={t('settings:useSlidersForAll')}
|
||||
isChecked={shouldUseSliders}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch(setShouldUseSliders(e.target.checked))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="settings-modal-items">
|
||||
|
@ -0,0 +1,26 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import ImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageFit';
|
||||
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
|
||||
import ParametersAccordion from 'features/parameters/components/ParametersAccordion';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function ImageToImageOptions() {
|
||||
const { t } = useTranslation();
|
||||
const imageToImageAccordionItems = {
|
||||
imageToImage: {
|
||||
header: `${t('parameters:imageToImage')}`,
|
||||
feature: undefined,
|
||||
content: (
|
||||
<Flex gap={2} flexDir="column">
|
||||
<ImageToImageStrength
|
||||
label={t('parameters:img2imgStrength')}
|
||||
styleClass="main-settings-block image-to-image-strength-main-option"
|
||||
/>
|
||||
<ImageFit />
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
};
|
||||
return <ParametersAccordion accordionInfo={imageToImageAccordionItems} />;
|
||||
}
|
@ -2,8 +2,6 @@ import { Flex } from '@chakra-ui/react';
|
||||
import { Feature } from 'app/features';
|
||||
import FaceRestoreSettings from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreSettings';
|
||||
import FaceRestoreToggle from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreToggle';
|
||||
import ImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageFit';
|
||||
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
|
||||
import ImageToImageOutputSettings from 'features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings';
|
||||
import SeedSettings from 'features/parameters/components/AdvancedParameters/Seed/SeedSettings';
|
||||
import UpscaleSettings from 'features/parameters/components/AdvancedParameters/Upscale/UpscaleSettings';
|
||||
@ -17,6 +15,7 @@ import NegativePromptInput from 'features/parameters/components/PromptInput/Nega
|
||||
import PromptInput from 'features/parameters/components/PromptInput/PromptInput';
|
||||
import InvokeOptionsPanel from 'features/ui/components/InvokeParametersPanel';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import ImageToImageOptions from './ImageToImageOptions';
|
||||
|
||||
export default function ImageToImagePanel() {
|
||||
const { t } = useTranslation();
|
||||
@ -60,11 +59,7 @@ export default function ImageToImagePanel() {
|
||||
</Flex>
|
||||
<ProcessButtons />
|
||||
<MainSettings />
|
||||
<ImageToImageStrength
|
||||
label={t('parameters:img2imgStrength')}
|
||||
styleClass="main-settings-block image-to-image-strength-main-option"
|
||||
/>
|
||||
<ImageFit />
|
||||
<ImageToImageOptions />
|
||||
<ParametersAccordion accordionInfo={imageToImageAccordions} />
|
||||
</InvokeOptionsPanel>
|
||||
);
|
||||
|
@ -32,7 +32,7 @@
|
||||
.parameters-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 1rem;
|
||||
row-gap: 0.5rem;
|
||||
height: 100%;
|
||||
@include HideScrollbar;
|
||||
background-color: var(--background-color);
|
||||
|
@ -20,6 +20,11 @@ export default function UnifiedCanvasPanel() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const unifiedCanvasAccordions = {
|
||||
seed: {
|
||||
header: `${t('parameters:seed')}`,
|
||||
feature: Feature.SEED,
|
||||
content: <SeedSettings />,
|
||||
},
|
||||
boundingBox: {
|
||||
header: `${t('parameters:boundingBoxHeader')}`,
|
||||
feature: Feature.BOUNDING_BOX,
|
||||
@ -35,11 +40,6 @@ export default function UnifiedCanvasPanel() {
|
||||
feature: Feature.INFILL_AND_SCALING,
|
||||
content: <InfillAndScalingSettings />,
|
||||
},
|
||||
seed: {
|
||||
header: `${t('parameters:seed')}`,
|
||||
feature: Feature.SEED,
|
||||
content: <SeedSettings />,
|
||||
},
|
||||
variations: {
|
||||
header: `${t('parameters:variations')}`,
|
||||
feature: Feature.VARIATIONS,
|
||||
@ -48,6 +48,19 @@ export default function UnifiedCanvasPanel() {
|
||||
},
|
||||
};
|
||||
|
||||
const unifiedCanvasImg2ImgAccordion = {
|
||||
unifiedCanvasImg2Img: {
|
||||
header: `${t('parameters:imageToImage')}`,
|
||||
feature: undefined,
|
||||
content: (
|
||||
<ImageToImageStrength
|
||||
label={t('parameters:img2imgStrength')}
|
||||
styleClass="main-settings-block image-to-image-strength-main-option"
|
||||
/>
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<InvokeOptionsPanel>
|
||||
<Flex flexDir="column" rowGap="0.5rem">
|
||||
@ -56,10 +69,7 @@ export default function UnifiedCanvasPanel() {
|
||||
</Flex>
|
||||
<ProcessButtons />
|
||||
<MainSettings />
|
||||
<ImageToImageStrength
|
||||
label={t('parameters:img2imgStrength')}
|
||||
styleClass="main-settings-block image-to-image-strength-main-option"
|
||||
/>
|
||||
<ParametersAccordion accordionInfo={unifiedCanvasImg2ImgAccordion} />
|
||||
<ParametersAccordion accordionInfo={unifiedCanvasAccordions} />
|
||||
</InvokeOptionsPanel>
|
||||
);
|
||||
|
@ -14,6 +14,7 @@ const initialtabsState: UIState = {
|
||||
shouldShowImageDetails: false,
|
||||
shouldUseCanvasBetaLayout: false,
|
||||
shouldShowExistingModelsInSearch: false,
|
||||
shouldUseSliders: false,
|
||||
addNewModelUIOption: null,
|
||||
};
|
||||
|
||||
@ -66,6 +67,9 @@ export const uiSlice = createSlice({
|
||||
) => {
|
||||
state.shouldShowExistingModelsInSearch = action.payload;
|
||||
},
|
||||
setShouldUseSliders: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldUseSliders = action.payload;
|
||||
},
|
||||
setAddNewModelUIOption: (state, action: PayloadAction<AddNewModelType>) => {
|
||||
state.addNewModelUIOption = action.payload;
|
||||
},
|
||||
@ -83,6 +87,7 @@ export const {
|
||||
setShouldShowImageDetails,
|
||||
setShouldUseCanvasBetaLayout,
|
||||
setShouldShowExistingModelsInSearch,
|
||||
setShouldUseSliders,
|
||||
setAddNewModelUIOption,
|
||||
} = uiSlice.actions;
|
||||
|
||||
|
@ -11,5 +11,6 @@ export interface UIState {
|
||||
shouldShowImageDetails: boolean;
|
||||
shouldUseCanvasBetaLayout: boolean;
|
||||
shouldShowExistingModelsInSearch: boolean;
|
||||
shouldUseSliders: boolean;
|
||||
addNewModelUIOption: AddNewModelType;
|
||||
}
|
||||
|
@ -137,4 +137,7 @@
|
||||
// Scrollbar
|
||||
--scrollbar-color: var(--accent-color);
|
||||
--scrollbar-color-hover: var(--accent-color-bright);
|
||||
|
||||
// SubHook
|
||||
--subhook-color: var(--accent-color);
|
||||
}
|
||||
|
@ -135,4 +135,7 @@
|
||||
// Scrollbar
|
||||
--scrollbar-color: var(--accent-color);
|
||||
--scrollbar-color-hover: var(--accent-color-bright);
|
||||
|
||||
// SubHook
|
||||
--subhook-color: var(--accent-color);
|
||||
}
|
||||
|
@ -132,4 +132,7 @@
|
||||
// Scrollbar
|
||||
--scrollbar-color: rgb(180, 180, 184);
|
||||
--scrollbar-color-hover: rgb(150, 150, 154);
|
||||
|
||||
// SubHook
|
||||
--subhook-color: rgb(0, 0, 0);
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -580,7 +580,7 @@ def import_model(model_path: str, gen, opt, completer):
|
||||
(3) a huggingface repository id; or (4) a local directory containing a
|
||||
diffusers model.
|
||||
"""
|
||||
model_path = model_path.replace('\\','/') # windows
|
||||
model.path = model_path.replace('\\','/') # windows
|
||||
model_name = None
|
||||
|
||||
if model_path.startswith(('http:','https:','ftp:')):
|
||||
@ -652,7 +652,7 @@ def import_checkpoint_list(models: List[Path], gen, opt, completer)->List[str]:
|
||||
print(f'>> Model {model.stem} imported successfully')
|
||||
model_names.append(model_name)
|
||||
else:
|
||||
print(f'** Model {model} failed to import')
|
||||
printf('** Model {model} failed to import')
|
||||
print()
|
||||
return model_names
|
||||
|
||||
@ -787,7 +787,6 @@ def optimize_model(model_name_or_path: Union[Path,str], gen, opt, completer):
|
||||
manager = gen.model_manager
|
||||
ckpt_path = None
|
||||
original_config_file = None
|
||||
|
||||
if model_name_or_path == gen.model_name:
|
||||
print("** Can't convert the active model. !switch to another model first. **")
|
||||
return
|
||||
|
@ -322,7 +322,6 @@ def download_with_resume(url: str, dest: Path, access_token: str = None) -> Path
|
||||
else:
|
||||
dest.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
if dest.exists():
|
||||
exist_size = dest.stat().st_size
|
||||
header["Range"] = f"bytes={exist_size}-"
|
||||
|
Loading…
Reference in New Issue
Block a user