diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 751d56372f..fe104a762b 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -454,9 +454,10 @@ "seed": "Seed", "imageToImage": "Image to Image", "randomizeSeed": "Randomize Seed", - "shuffle": "Shuffle", + "shuffle": "Shuffle Seed", "noiseThreshold": "Noise Threshold", "perlinNoise": "Perlin Noise", + "noiseSettings": "Noise", "variations": "Variations", "variationAmount": "Variation Amount", "seedWeights": "Seed Weights", @@ -471,6 +472,8 @@ "scale": "Scale", "otherOptions": "Other Options", "seamlessTiling": "Seamless Tiling", + "seamlessXAxis": "X Axis", + "seamlessYAxis": "Y Axis", "hiresOptim": "High Res Optimization", "hiresStrength": "High Res Strength", "imageFit": "Fit Initial Image To Output Size", diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/userInvokedCreate.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/userInvokedCreate.ts index d24385ea97..f07aa4530e 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/userInvokedCreate.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/userInvokedCreate.ts @@ -10,7 +10,7 @@ const moduleLog = log.child({ namespace: 'invoke' }); export const addUserInvokedCreateListener = () => { startAppListening({ predicate: (action): action is ReturnType => - userInvoked.match(action) && action.payload === 'generate', + userInvoked.match(action) && action.payload === 'text', effect: (action, { getState, dispatch }) => { const state = getState(); diff --git a/invokeai/frontend/web/src/common/components/IAICollapse.tsx b/invokeai/frontend/web/src/common/components/IAICollapse.tsx new file mode 100644 index 0000000000..25d2dee56c --- /dev/null +++ b/invokeai/frontend/web/src/common/components/IAICollapse.tsx @@ -0,0 +1,61 @@ +import { ChevronDownIcon, ChevronUpIcon } from '@chakra-ui/icons'; +import { Box, Collapse, Flex, Spacer, Switch } from '@chakra-ui/react'; +import { PropsWithChildren, memo } from 'react'; + +export type IAIToggleCollapseProps = PropsWithChildren & { + label: string; + isOpen: boolean; + onToggle: () => void; + withSwitch?: boolean; +}; + +const IAICollapse = (props: IAIToggleCollapseProps) => { + const { label, isOpen, onToggle, children, withSwitch = false } = props; + return ( + + + {label} + + {withSwitch && } + {!withSwitch && ( + + )} + + + + {children} + + + + ); +}; + +export default memo(IAICollapse); diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamBlur.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamBlur.tsx similarity index 95% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamBlur.tsx rename to invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamBlur.tsx index 693313e606..5c20ba7a13 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamBlur.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamBlur.tsx @@ -4,7 +4,7 @@ import IAISlider from 'common/components/IAISlider'; import { setSeamBlur } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; -export default function SeamBlur() { +export default function ParamSeamBlur() { const dispatch = useAppDispatch(); const seamBlur = useAppSelector( (state: RootState) => state.generation.seamBlur diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamSize.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamSize.tsx similarity index 95% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamSize.tsx rename to invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamSize.tsx index 02403ac5ec..8e56cded7b 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamSize.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamSize.tsx @@ -4,7 +4,7 @@ import IAISlider from 'common/components/IAISlider'; import { setSeamSize } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; -export default function SeamSize() { +export default function ParamSeamSize() { const dispatch = useAppDispatch(); const { t } = useTranslation(); diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamSteps.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamSteps.tsx similarity index 95% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamSteps.tsx rename to invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamSteps.tsx index 0319b26820..8ca5226621 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamSteps.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamSteps.tsx @@ -4,7 +4,7 @@ import IAISlider from 'common/components/IAISlider'; import { setSeamSteps } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; -export default function SeamSteps() { +export default function ParamSeamSteps() { const { t } = useTranslation(); const seamSteps = useAppSelector( (state: RootState) => state.generation.seamSteps diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamStrength.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamStrength.tsx similarity index 94% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamStrength.tsx rename to invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamStrength.tsx index 7d447cfda1..de74156cd3 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamStrength.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/ParamSeamStrength.tsx @@ -4,7 +4,7 @@ import IAISlider from 'common/components/IAISlider'; import { setSeamStrength } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; -export default function SeamStrength() { +export default function ParamSeamStrength() { const dispatch = useAppDispatch(); const { t } = useTranslation(); const seamStrength = useAppSelector( diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamCorrectionSettings.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamCorrectionSettings.tsx index 176dfe1590..a49eac26a1 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamCorrectionSettings.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamCorrectionSettings.tsx @@ -1,16 +1,16 @@ import { VStack } from '@chakra-ui/react'; -import SeamBlur from './SeamBlur'; -import SeamSize from './SeamSize'; -import SeamSteps from './SeamSteps'; -import SeamStrength from './SeamStrength'; +import ParamSeamBlur from './ParamSeamBlur'; +import ParamSeamSize from './ParamSeamSize'; +import ParamSeamSteps from './ParamSeamSteps'; +import ParamSeamStrength from './ParamSeamStrength'; const SeamCorrectionSettings = () => { return ( - - - - + + + + ); }; diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings.tsx deleted file mode 100644 index c2dea1cbf8..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { VStack } from '@chakra-ui/react'; -import SeamlessSettings from './SeamlessSettings'; - -const ImageToImageOutputSettings = () => { - return ( - - - - ); -}; - -export default ImageToImageOutputSettings; diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/OutputSettings.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/OutputSettings.tsx deleted file mode 100644 index 93ba63d065..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/OutputSettings.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { VStack } from '@chakra-ui/react'; -import { HiresStrength, HiresToggle } from './HiresSettings'; -import SeamlessSettings from './SeamlessSettings'; - -const OutputSettings = () => { - return ( - - - - - - ); -}; - -export default OutputSettings; diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/SymmetrySettings.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/SymmetrySettings.tsx deleted file mode 100644 index 21e014b715..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/SymmetrySettings.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { VStack } from '@chakra-ui/react'; -import { RootState } from 'app/store/store'; -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import IAISlider from 'common/components/IAISlider'; -import { - setHorizontalSymmetrySteps, - setVerticalSymmetrySteps, -} from 'features/parameters/store/generationSlice'; -import { useTranslation } from 'react-i18next'; - -export default function SymmetrySettings() { - const horizontalSymmetrySteps = useAppSelector( - (state: RootState) => state.generation.horizontalSymmetrySteps - ); - - const verticalSymmetrySteps = useAppSelector( - (state: RootState) => state.generation.verticalSymmetrySteps - ); - - const steps = useAppSelector((state: RootState) => state.generation.steps); - - const dispatch = useAppDispatch(); - - const { t } = useTranslation(); - - return ( - - dispatch(setHorizontalSymmetrySteps(v))} - min={0} - max={steps} - step={1} - withInput - withSliderMarks - withReset - handleReset={() => dispatch(setHorizontalSymmetrySteps(0))} - /> - dispatch(setVerticalSymmetrySteps(v))} - min={0} - max={steps} - step={1} - withInput - withSliderMarks - withReset - handleReset={() => dispatch(setVerticalSymmetrySteps(0))} - /> - - ); -} diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/SeedSettings.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/SeedSettings.tsx deleted file mode 100644 index 576358d2e1..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/SeedSettings.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { VStack } from '@chakra-ui/react'; -import Perlin from './Perlin'; -import RandomizeSeed from './RandomizeSeed'; -import Seed from './Seed'; -import Threshold from './Threshold'; - -/** - * Seed & variation options. Includes iteration, seed, seed randomization, variation options. - */ -const SeedSettings = () => { - return ( - - - - - - ); -}; - -export default SeedSettings; diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/GenerateVariations.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/GenerateVariations.tsx deleted file mode 100644 index ec9a8ae276..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/GenerateVariations.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { RootState } from 'app/store/store'; -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import IAISwitch from 'common/components/IAISwitch'; -import { setShouldGenerateVariations } from 'features/parameters/store/generationSlice'; -import { ChangeEvent } from 'react'; - -export default function GenerateVariationsToggle() { - const shouldGenerateVariations = useAppSelector( - (state: RootState) => state.generation.shouldGenerateVariations - ); - - const dispatch = useAppDispatch(); - - const handleChangeShouldGenerateVariations = ( - e: ChangeEvent - ) => dispatch(setShouldGenerateVariations(e.target.checked)); - - return ( - - ); -} diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/VariationsSettings.tsx b/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/VariationsSettings.tsx deleted file mode 100644 index d3bc43f7ae..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/VariationsSettings.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { VStack } from '@chakra-ui/react'; -import SeedWeights from './SeedWeights'; -import VariationAmount from './VariationAmount'; - -/** - * Seed & variation options. Includes iteration, seed, seed randomization, variation options. - */ -const VariationsSettings = () => { - return ( - - - - - ); -}; - -export default VariationsSettings; diff --git a/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainSettings.tsx b/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainSettings.tsx index db2701e0c9..d7f918e1f0 100644 --- a/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainSettings.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainSettings.tsx @@ -1,14 +1,15 @@ +import { memo } from 'react'; import { Box, Flex, VStack } from '@chakra-ui/react'; import { RootState } from 'app/store/store'; import { useAppSelector } from 'app/store/storeHooks'; + import ModelSelect from 'features/system/components/ModelSelect'; -import { memo } from 'react'; -import HeightSlider from './HeightSlider'; -import MainCFGScale from './MainCFGScale'; -import MainIterations from './MainIterations'; -import MainSampler from './MainSampler'; -import MainSteps from './MainSteps'; -import WidthSlider from './WidthSlider'; +import ParamHeight from 'features/parameters/components/Parameters/ParamHeight'; +import ParamCFGScale from 'features/parameters/components/Parameters/ParamCFGScale'; +import ParamIterations from 'features/parameters/components/Parameters/ParamIterations'; +import ParamScheduler from 'features/parameters/components/Parameters/ParamScheduler'; +import ParamSteps from 'features/parameters/components/Parameters/ParamSteps'; +import ParamWidth from 'features/parameters/components/Parameters/ParamWidth'; const MainSettings = () => { const shouldUseSliders = useAppSelector( @@ -17,14 +18,14 @@ const MainSettings = () => { return shouldUseSliders ? ( - - - - - + + + + + - + @@ -34,15 +35,15 @@ const MainSettings = () => { ) : ( - - - + + + - - + + - + diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresCollapse.tsx new file mode 100644 index 0000000000..06ecd6762b --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresCollapse.tsx @@ -0,0 +1,37 @@ +import { Flex } from '@chakra-ui/react'; +import { useTranslation } from 'react-i18next'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { RootState } from 'app/store/store'; +import IAICollapse from 'common/components/IAICollapse'; +import { memo } from 'react'; +import { ParamHiresStrength } from './ParamHiresStrength'; +import { setHiresFix } from 'features/parameters/store/postprocessingSlice'; + +/** + * Seed & variation options. Includes iteration, seed, seed randomization, variation options. + */ +const ParamHiresCollapse = () => { + const { t } = useTranslation(); + const hiresFix = useAppSelector( + (state: RootState) => state.postprocessing.hiresFix + ); + + const dispatch = useAppDispatch(); + + const handleToggle = () => dispatch(setHiresFix(!hiresFix)); + + return ( + + + + + + ); +}; + +export default memo(ParamHiresCollapse); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresHeight.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresHeight.tsx new file mode 100644 index 0000000000..80a15f591b --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresHeight.tsx @@ -0,0 +1,3 @@ +// TODO + +export default {}; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresSteps.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresSteps.tsx new file mode 100644 index 0000000000..80a15f591b --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresSteps.tsx @@ -0,0 +1,3 @@ +// TODO + +export default {}; diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/HiresSettings.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresStrength.tsx similarity index 61% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/HiresSettings.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresStrength.tsx index 7f20a1d6c3..2655841590 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/HiresSettings.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresStrength.tsx @@ -1,15 +1,9 @@ import { createSelector } from '@reduxjs/toolkit'; -import type { RootState } from 'app/store/store'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAISlider from 'common/components/IAISlider'; -import IAISwitch from 'common/components/IAISwitch'; import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors'; -import { - setHiresFix, - setHiresStrength, -} from 'features/parameters/store/postprocessingSlice'; +import { setHiresStrength } from 'features/parameters/store/postprocessingSlice'; import { isEqual } from 'lodash-es'; -import { ChangeEvent } from 'react'; import { useTranslation } from 'react-i18next'; const hiresStrengthSelector = createSelector( @@ -22,7 +16,7 @@ const hiresStrengthSelector = createSelector( } ); -export const HiresStrength = () => { +export const ParamHiresStrength = () => { const { hiresFix, hiresStrength } = useAppSelector(hiresStrengthSelector); const dispatch = useAppDispatch(); @@ -55,28 +49,3 @@ export const HiresStrength = () => { /> ); }; - -/** - * Hires Fix Toggle - */ -export const HiresToggle = () => { - const dispatch = useAppDispatch(); - - const hiresFix = useAppSelector( - (state: RootState) => state.postprocessing.hiresFix - ); - - const { t } = useTranslation(); - - const handleChangeHiresFix = (e: ChangeEvent) => - dispatch(setHiresFix(e.target.checked)); - - return ( - - ); -}; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresToggle.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresToggle.tsx new file mode 100644 index 0000000000..0fc600e9e8 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresToggle.tsx @@ -0,0 +1,31 @@ +import type { RootState } from 'app/store/store'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import IAISwitch from 'common/components/IAISwitch'; +import { setHiresFix } from 'features/parameters/store/postprocessingSlice'; +import { ChangeEvent } from 'react'; +import { useTranslation } from 'react-i18next'; + +/** + * Hires Fix Toggle + */ +export const ParamHiresToggle = () => { + const dispatch = useAppDispatch(); + + const hiresFix = useAppSelector( + (state: RootState) => state.postprocessing.hiresFix + ); + + const { t } = useTranslation(); + + const handleChangeHiresFix = (e: ChangeEvent) => + dispatch(setHiresFix(e.target.checked)); + + return ( + + ); +}; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresWidth.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresWidth.tsx new file mode 100644 index 0000000000..80a15f591b --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Hires/ParamHiresWidth.tsx @@ -0,0 +1,3 @@ +// TODO + +export default {}; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseCollapse.tsx new file mode 100644 index 0000000000..30947e9709 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseCollapse.tsx @@ -0,0 +1,37 @@ +import { useTranslation } from 'react-i18next'; +import { Flex } from '@chakra-ui/react'; +import IAICollapse from 'common/components/IAICollapse'; +import ParamPerlinNoise from './ParamPerlinNoise'; +import ParamNoiseThreshold from './ParamNoiseThreshold'; +import { RootState } from 'app/store/store'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { setShouldUseNoiseSettings } from 'features/parameters/store/generationSlice'; +import { memo } from 'react'; + +const ParamNoiseCollapse = () => { + const { t } = useTranslation(); + const shouldUseNoiseSettings = useAppSelector( + (state: RootState) => state.generation.shouldUseNoiseSettings + ); + + const dispatch = useAppDispatch(); + + const handleToggle = () => + dispatch(setShouldUseNoiseSettings(!shouldUseNoiseSettings)); + + return ( + + + + + + + ); +}; + +export default memo(ParamNoiseCollapse); diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/Threshold.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseThreshold.tsx similarity index 94% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/Threshold.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseThreshold.tsx index 14ca46b53c..e339734992 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/Threshold.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseThreshold.tsx @@ -4,7 +4,7 @@ import IAISlider from 'common/components/IAISlider'; import { setThreshold } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; -export default function Threshold() { +export default function ParamNoiseThreshold() { const dispatch = useAppDispatch(); const threshold = useAppSelector( (state: RootState) => state.generation.threshold diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/Perlin.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamPerlinNoise.tsx similarity index 94% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/Perlin.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamPerlinNoise.tsx index d2f4ea4249..ad710eae54 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/Perlin.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamPerlinNoise.tsx @@ -4,7 +4,7 @@ import IAISlider from 'common/components/IAISlider'; import { setPerlin } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; -export default function Perlin() { +export default function ParamPerlinNoise() { const dispatch = useAppDispatch(); const perlin = useAppSelector((state: RootState) => state.generation.perlin); const { t } = useTranslation(); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/OtherSettings.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/OtherSettings.tsx new file mode 100644 index 0000000000..b41b0690e1 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/OtherSettings.tsx @@ -0,0 +1,18 @@ +import { VStack } from '@chakra-ui/react'; +import ParamSeamlessToggle from './Seamless/ParamSeamlessToggle'; +// import ParamSeamlessAxes from '../../Parameters/Seamless/ParamSeamlessAxes'; +import { ParamHiresToggle } from './Hires/ParamHiresToggle'; +import { ParamHiresStrength } from './Hires/ParamHiresStrength'; + +const OtherSettings = () => { + return ( + + + {/* */} + + + + ); +}; + +export default OtherSettings; diff --git a/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainCFGScale.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamCFGScale.tsx similarity index 97% rename from invokeai/frontend/web/src/features/parameters/components/MainParameters/MainCFGScale.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/ParamCFGScale.tsx index 928cccafd1..111e3d3ae8 100644 --- a/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainCFGScale.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamCFGScale.tsx @@ -30,7 +30,7 @@ const selector = createSelector( } ); -const GuidanceScale = () => { +const ParamCFGScale = () => { const { cfgScale, initial, @@ -82,4 +82,4 @@ const GuidanceScale = () => { ); }; -export default memo(GuidanceScale); +export default memo(ParamCFGScale); diff --git a/invokeai/frontend/web/src/features/parameters/components/MainParameters/HeightSlider.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamHeight.tsx similarity index 96% rename from invokeai/frontend/web/src/features/parameters/components/MainParameters/HeightSlider.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/ParamHeight.tsx index 35e97fb266..9ba1aeaaf8 100644 --- a/invokeai/frontend/web/src/features/parameters/components/MainParameters/HeightSlider.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamHeight.tsx @@ -31,7 +31,7 @@ const selector = createSelector( } ); -const HeightSlider = () => { +const ParamHeight = () => { const { height, initial, @@ -74,4 +74,4 @@ const HeightSlider = () => { ); }; -export default memo(HeightSlider); +export default memo(ParamHeight); diff --git a/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainIterations.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamIterations.tsx similarity index 96% rename from invokeai/frontend/web/src/features/parameters/components/MainParameters/MainIterations.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/ParamIterations.tsx index d1d142d7ff..5a5b782c04 100644 --- a/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainIterations.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamIterations.tsx @@ -32,7 +32,7 @@ const selector = createSelector( } ); -const MainIterations = () => { +const ParamIterations = () => { const { iterations, initial, @@ -83,4 +83,4 @@ const MainIterations = () => { ); }; -export default memo(MainIterations); +export default memo(ParamIterations); diff --git a/invokeai/frontend/web/src/features/parameters/components/PromptInput/NegativePromptInput.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamNegativeConditioning.tsx similarity index 91% rename from invokeai/frontend/web/src/features/parameters/components/PromptInput/NegativePromptInput.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/ParamNegativeConditioning.tsx index ea3f12db42..d3790d4c24 100644 --- a/invokeai/frontend/web/src/features/parameters/components/PromptInput/NegativePromptInput.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamNegativeConditioning.tsx @@ -4,7 +4,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { setNegativePrompt } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; -const NegativePromptInput = () => { +const ParamNegativeConditioning = () => { const negativePrompt = useAppSelector( (state: RootState) => state.generation.negativePrompt ); @@ -29,4 +29,4 @@ const NegativePromptInput = () => { ); }; -export default NegativePromptInput; +export default ParamNegativeConditioning; diff --git a/invokeai/frontend/web/src/features/parameters/components/PromptInput/PromptInput.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamPositiveConditioning.tsx similarity index 96% rename from invokeai/frontend/web/src/features/parameters/components/PromptInput/PromptInput.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/ParamPositiveConditioning.tsx index eb0340b0ee..70e9b81957 100644 --- a/invokeai/frontend/web/src/features/parameters/components/PromptInput/PromptInput.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamPositiveConditioning.tsx @@ -35,7 +35,7 @@ const promptInputSelector = createSelector( /** * Prompt input text area. */ -const PromptInput = () => { +const ParamPositiveConditioning = () => { const dispatch = useAppDispatch(); const { prompt, activeTabName } = useAppSelector(promptInputSelector); const { isReady } = useAppSelector(readinessSelector); @@ -88,4 +88,4 @@ const PromptInput = () => { ); }; -export default PromptInput; +export default ParamPositiveConditioning; diff --git a/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainSampler.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamScheduler.tsx similarity index 92% rename from invokeai/frontend/web/src/features/parameters/components/MainParameters/MainSampler.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/ParamScheduler.tsx index b71ff20e01..ef1574b64c 100644 --- a/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainSampler.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamScheduler.tsx @@ -6,7 +6,7 @@ import { setSampler } from 'features/parameters/store/generationSlice'; import { ChangeEvent, memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -const Scheduler = () => { +const ParamScheduler = () => { const sampler = useAppSelector( (state: RootState) => state.generation.sampler ); @@ -29,4 +29,4 @@ const Scheduler = () => { ); }; -export default memo(Scheduler); +export default memo(ParamScheduler); diff --git a/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainSteps.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamSteps.tsx similarity index 97% rename from invokeai/frontend/web/src/features/parameters/components/MainParameters/MainSteps.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/ParamSteps.tsx index 43e399848e..f43cdd425b 100644 --- a/invokeai/frontend/web/src/features/parameters/components/MainParameters/MainSteps.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamSteps.tsx @@ -36,7 +36,7 @@ const selector = createSelector( } ); -const MainSteps = () => { +const ParamSteps = () => { const { steps, initial, min, sliderMax, inputMax, step, shouldUseSliders } = useAppSelector(selector); const dispatch = useAppDispatch(); @@ -84,4 +84,4 @@ const MainSteps = () => { ); }; -export default memo(MainSteps); +export default memo(ParamSteps); diff --git a/invokeai/frontend/web/src/features/parameters/components/MainParameters/WidthSlider.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamWidth.tsx similarity index 96% rename from invokeai/frontend/web/src/features/parameters/components/MainParameters/WidthSlider.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/ParamWidth.tsx index 0b871245c7..e8deb2ba70 100644 --- a/invokeai/frontend/web/src/features/parameters/components/MainParameters/WidthSlider.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ParamWidth.tsx @@ -30,7 +30,7 @@ const selector = createSelector( } ); -const WidthSlider = () => { +const ParamWidth = () => { const { width, initial, @@ -73,4 +73,4 @@ const WidthSlider = () => { ); }; -export default memo(WidthSlider); +export default memo(ParamWidth); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse.tsx new file mode 100644 index 0000000000..c8645d3607 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse.tsx @@ -0,0 +1,51 @@ +import { useTranslation } from 'react-i18next'; +import { Box, Flex } from '@chakra-ui/react'; +import IAICollapse from 'common/components/IAICollapse'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { setSeamless } from 'features/parameters/store/generationSlice'; +import { memo } from 'react'; +import { createSelector } from '@reduxjs/toolkit'; +import { generationSelector } from 'features/parameters/store/generationSelectors'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import ParamSeamlessXAxis from './ParamSeamlessXAxis'; +import ParamSeamlessYAxis from './ParamSeamlessYAxis'; + +const selector = createSelector( + generationSelector, + (generation) => { + const { shouldUseSeamless, seamlessXAxis, seamlessYAxis } = generation; + + return { shouldUseSeamless, seamlessXAxis, seamlessYAxis }; + }, + defaultSelectorOptions +); + +const ParamSeamlessCollapse = () => { + const { t } = useTranslation(); + const { shouldUseSeamless, seamlessXAxis, seamlessYAxis } = + useAppSelector(selector); + + const dispatch = useAppDispatch(); + + const handleToggle = () => dispatch(setSeamless(!shouldUseSeamless)); + + return ( + + + + + + + + + + + ); +}; + +export default memo(ParamSeamlessCollapse); diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/SeamlessSettings.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessToggle.tsx similarity index 91% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/SeamlessSettings.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessToggle.tsx index fb333c6f00..1a3b046bcf 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/SeamlessSettings.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessToggle.tsx @@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next'; /** * Seamless tiling toggle */ -const SeamlessSettings = () => { +const ParamSeamlessToggle = () => { const dispatch = useAppDispatch(); const seamless = useAppSelector( @@ -30,4 +30,4 @@ const SeamlessSettings = () => { ); }; -export default SeamlessSettings; +export default ParamSeamlessToggle; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessXAxis.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessXAxis.tsx new file mode 100644 index 0000000000..31e2aced9c --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessXAxis.tsx @@ -0,0 +1,43 @@ +import { useTranslation } from 'react-i18next'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { ChangeEvent, memo, useCallback } from 'react'; +import { createSelector } from '@reduxjs/toolkit'; +import { generationSelector } from 'features/parameters/store/generationSelectors'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import IAISwitch from 'common/components/IAISwitch'; +import { setSeamlessXAxis } from 'features/parameters/store/generationSlice'; + +const selector = createSelector( + generationSelector, + (generation) => { + const { seamlessXAxis } = generation; + + return { seamlessXAxis }; + }, + defaultSelectorOptions +); + +const ParamSeamlessXAxis = () => { + const { t } = useTranslation(); + const { seamlessXAxis } = useAppSelector(selector); + + const dispatch = useAppDispatch(); + + const handleChange = useCallback( + (e: ChangeEvent) => { + dispatch(setSeamlessXAxis(e.target.checked)); + }, + [dispatch] + ); + + return ( + + ); +}; + +export default memo(ParamSeamlessXAxis); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessYAxis.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessYAxis.tsx new file mode 100644 index 0000000000..edd78443c7 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seamless/ParamSeamlessYAxis.tsx @@ -0,0 +1,43 @@ +import { useTranslation } from 'react-i18next'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { ChangeEvent, memo, useCallback } from 'react'; +import { createSelector } from '@reduxjs/toolkit'; +import { generationSelector } from 'features/parameters/store/generationSelectors'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import IAISwitch from 'common/components/IAISwitch'; +import { setSeamlessYAxis } from 'features/parameters/store/generationSlice'; + +const selector = createSelector( + generationSelector, + (generation) => { + const { seamlessYAxis } = generation; + + return { seamlessYAxis }; + }, + defaultSelectorOptions +); + +const ParamSeamlessYAxis = () => { + const { t } = useTranslation(); + const { seamlessYAxis } = useAppSelector(selector); + + const dispatch = useAppDispatch(); + + const handleChange = useCallback( + (e: ChangeEvent) => { + dispatch(setSeamlessYAxis(e.target.checked)); + }, + [dispatch] + ); + + return ( + + ); +}; + +export default memo(ParamSeamlessYAxis); diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/Seed.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeed.tsx similarity index 54% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/Seed.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeed.tsx index 96c929a462..c5a00d32c8 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/Seed.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeed.tsx @@ -1,13 +1,14 @@ -import { HStack } from '@chakra-ui/react'; +import { Flex, HStack } from '@chakra-ui/react'; import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants'; import { RootState } from 'app/store/store'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAINumberInput from 'common/components/IAINumberInput'; import { setSeed } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; -import ShuffleSeed from './ShuffleSeed'; +import ParamSeedShuffle from './ParamSeedShuffle'; +import ParamSeedRandomize from './ParamSeedRandomize'; -export default function Seed() { +export default function ParamSeed() { const seed = useAppSelector((state: RootState) => state.generation.seed); const shouldRandomizeSeed = useAppSelector( (state: RootState) => state.generation.shouldRandomizeSeed @@ -23,25 +24,22 @@ export default function Seed() { const handleChangeSeed = (v: number) => dispatch(setSeed(v)); return ( - - - - + ); } diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeedCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeedCollapse.tsx new file mode 100644 index 0000000000..2867029f7e --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeedCollapse.tsx @@ -0,0 +1,48 @@ +import { Flex } from '@chakra-ui/react'; +import ParamSeed from './ParamSeed'; +import { memo, useCallback } from 'react'; +import ParamSeedShuffle from './ParamSeedShuffle'; +import { useTranslation } from 'react-i18next'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { createSelector } from '@reduxjs/toolkit'; +import { generationSelector } from 'features/parameters/store/generationSelectors'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import { setShouldRandomizeSeed } from 'features/parameters/store/generationSlice'; +import IAICollapse from 'common/components/IAICollapse'; + +const selector = createSelector( + generationSelector, + (generation) => { + const { shouldRandomizeSeed } = generation; + + return { shouldRandomizeSeed }; + }, + defaultSelectorOptions +); + +const ParamSeedSettings = () => { + const { t } = useTranslation(); + const dispatch = useAppDispatch(); + const { shouldRandomizeSeed } = useAppSelector(selector); + + const handleToggle = useCallback( + () => dispatch(setShouldRandomizeSeed(!shouldRandomizeSeed)), + [dispatch, shouldRandomizeSeed] + ); + + return ( + + + + + + + ); +}; + +export default memo(ParamSeedSettings); diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/RandomizeSeed.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeedRandomize.tsx similarity index 64% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/RandomizeSeed.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeedRandomize.tsx index ea60124f74..13380f3660 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/RandomizeSeed.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeedRandomize.tsx @@ -5,7 +5,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAISwitch from 'common/components/IAISwitch'; import { setShouldRandomizeSeed } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; -import { Switch } from '@chakra-ui/react'; +import { FormControl, FormLabel, Switch } from '@chakra-ui/react'; // export default function RandomizeSeed() { // const dispatch = useAppDispatch(); @@ -27,7 +27,7 @@ import { Switch } from '@chakra-ui/react'; // ); // } -const SeedToggle = () => { +const ParamSeedRandomize = () => { const dispatch = useAppDispatch(); const { t } = useTranslation(); @@ -36,15 +36,33 @@ const SeedToggle = () => { ); const handleChangeShouldRandomizeSeed = (e: ChangeEvent) => - dispatch(setShouldRandomizeSeed(!e.target.checked)); + dispatch(setShouldRandomizeSeed(e.target.checked)); return ( - + + + {t('parameters.randomizeSeed')} + + + ); }; -export default memo(SeedToggle); +export default memo(ParamSeedRandomize); diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/ShuffleSeed.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeedShuffle.tsx similarity index 75% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/ShuffleSeed.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeedShuffle.tsx index f2d222de7c..9dba81104c 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Seed/ShuffleSeed.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeedShuffle.tsx @@ -1,14 +1,15 @@ -import { Button } from '@chakra-ui/react'; +import { Box } from '@chakra-ui/react'; import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants'; import { RootState } from 'app/store/store'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import IAIButton from 'common/components/IAIButton'; import IAIIconButton from 'common/components/IAIIconButton'; import randomInt from 'common/util/randomInt'; import { setSeed } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; import { FaRandom } from 'react-icons/fa'; -export default function ShuffleSeed() { +export default function ParamSeedShuffle() { const dispatch = useAppDispatch(); const shouldRandomizeSeed = useAppSelector( (state: RootState) => state.generation.shouldRandomizeSeed @@ -19,20 +20,14 @@ export default function ShuffleSeed() { dispatch(setSeed(randomInt(NUMPY_RAND_MIN, NUMPY_RAND_MAX))); return ( - } onClick={handleClickRandomizeSeed} - /> - // + > + {t('parameters.shuffle')} + ); } diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse.tsx new file mode 100644 index 0000000000..97c51d4461 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse.tsx @@ -0,0 +1,37 @@ +import { memo } from 'react'; +import { Flex } from '@chakra-ui/react'; +import ParamSymmetryHorizontal from './ParamSymmetryHorizontal'; +import ParamSymmetryVertical from './ParamSymmetryVertical'; + +import { useTranslation } from 'react-i18next'; +import IAICollapse from 'common/components/IAICollapse'; +import { RootState } from 'app/store/store'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { setShouldUseSymmetry } from 'features/parameters/store/generationSlice'; + +const ParamSymmetryCollapse = () => { + const { t } = useTranslation(); + const shouldUseSymmetry = useAppSelector( + (state: RootState) => state.generation.shouldUseSymmetry + ); + + const dispatch = useAppDispatch(); + + const handleToggle = () => dispatch(setShouldUseSymmetry(!shouldUseSymmetry)); + + return ( + + + + + + + ); +}; + +export default memo(ParamSymmetryCollapse); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryHorizontal.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryHorizontal.tsx new file mode 100644 index 0000000000..99af147f2c --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryHorizontal.tsx @@ -0,0 +1,32 @@ +import { RootState } from 'app/store/store'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import IAISlider from 'common/components/IAISlider'; +import { setHorizontalSymmetrySteps } from 'features/parameters/store/generationSlice'; +import { useTranslation } from 'react-i18next'; + +export default function ParamSymmetryHorizontal() { + const horizontalSymmetrySteps = useAppSelector( + (state: RootState) => state.generation.horizontalSymmetrySteps + ); + + const steps = useAppSelector((state: RootState) => state.generation.steps); + + const dispatch = useAppDispatch(); + + const { t } = useTranslation(); + + return ( + dispatch(setHorizontalSymmetrySteps(v))} + min={0} + max={steps} + step={1} + withInput + withSliderMarks + withReset + handleReset={() => dispatch(setHorizontalSymmetrySteps(0))} + /> + ); +} diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/SymmetryToggle.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryToggle.tsx similarity index 91% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/SymmetryToggle.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryToggle.tsx index c155336c1e..7cc17c045e 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Output/SymmetryToggle.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryToggle.tsx @@ -3,7 +3,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAISwitch from 'common/components/IAISwitch'; import { setShouldUseSymmetry } from 'features/parameters/store/generationSlice'; -export default function SymmetryToggle() { +export default function ParamSymmetryToggle() { const shouldUseSymmetry = useAppSelector( (state: RootState) => state.generation.shouldUseSymmetry ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryVertical.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryVertical.tsx new file mode 100644 index 0000000000..c8ddb46a3a --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryVertical.tsx @@ -0,0 +1,32 @@ +import { RootState } from 'app/store/store'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import IAISlider from 'common/components/IAISlider'; +import { setVerticalSymmetrySteps } from 'features/parameters/store/generationSlice'; +import { useTranslation } from 'react-i18next'; + +export default function ParamSymmetryVertical() { + const verticalSymmetrySteps = useAppSelector( + (state: RootState) => state.generation.verticalSymmetrySteps + ); + + const steps = useAppSelector((state: RootState) => state.generation.steps); + + const dispatch = useAppDispatch(); + + const { t } = useTranslation(); + + return ( + dispatch(setVerticalSymmetrySteps(v))} + min={0} + max={steps} + step={1} + withInput + withSliderMarks + withReset + handleReset={() => dispatch(setVerticalSymmetrySteps(0))} + /> + ); +} diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/VariationAmount.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationAmount.tsx similarity index 95% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/VariationAmount.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationAmount.tsx index 21b5001d6a..9bc84a0bf4 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/VariationAmount.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationAmount.tsx @@ -4,7 +4,7 @@ import IAISlider from 'common/components/IAISlider'; import { setVariationAmount } from 'features/parameters/store/generationSlice'; import { useTranslation } from 'react-i18next'; -export default function VariationAmount() { +export default function ParamVariationAmount() { const variationAmount = useAppSelector( (state: RootState) => state.generation.variationAmount ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationCollapse.tsx new file mode 100644 index 0000000000..0e1134e9f0 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationCollapse.tsx @@ -0,0 +1,37 @@ +import ParamVariationWeights from './ParamVariationWeights'; +import ParamVariationAmount from './ParamVariationAmount'; +import { useTranslation } from 'react-i18next'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { RootState } from 'app/store/store'; +import { setShouldGenerateVariations } from 'features/parameters/store/generationSlice'; +import { Flex } from '@chakra-ui/react'; +import IAICollapse from 'common/components/IAICollapse'; +import { memo } from 'react'; + +const ParamVariationCollapse = () => { + const { t } = useTranslation(); + const shouldGenerateVariations = useAppSelector( + (state: RootState) => state.generation.shouldGenerateVariations + ); + + const dispatch = useAppDispatch(); + + const handleToggle = () => + dispatch(setShouldGenerateVariations(!shouldGenerateVariations)); + + return ( + + + + + + + ); +}; + +export default memo(ParamVariationCollapse); diff --git a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/SeedWeights.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationWeights.tsx similarity index 95% rename from invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/SeedWeights.tsx rename to invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationWeights.tsx index 7f8b096757..30876597a8 100644 --- a/invokeai/frontend/web/src/features/parameters/components/AdvancedParameters/Variations/SeedWeights.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationWeights.tsx @@ -6,7 +6,7 @@ import { setSeedWeights } from 'features/parameters/store/generationSlice'; import { ChangeEvent } from 'react'; import { useTranslation } from 'react-i18next'; -export default function SeedWeights() { +export default function ParamVariationWeights() { const seedWeights = useAppSelector( (state: RootState) => state.generation.seedWeights ); diff --git a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts index 51627ce24c..89891e96aa 100644 --- a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts @@ -20,7 +20,6 @@ export interface GenerationState { negativePrompt: string; sampler: string; seamBlur: number; - seamless: boolean; seamSize: number; seamSteps: number; seamStrength: number; @@ -29,6 +28,7 @@ export interface GenerationState { shouldFitToWidthHeight: boolean; shouldGenerateVariations: boolean; shouldRandomizeSeed: boolean; + shouldUseNoiseSettings: boolean; steps: number; threshold: number; tileSize: number; @@ -39,6 +39,9 @@ export interface GenerationState { verticalSymmetrySteps: number; isImageToImageEnabled: boolean; model: string; + shouldUseSeamless: boolean; + seamlessXAxis: boolean; + seamlessYAxis: boolean; } export const initialGenerationState: GenerationState = { @@ -53,7 +56,6 @@ export const initialGenerationState: GenerationState = { negativePrompt: '', sampler: 'k_lms', seamBlur: 16, - seamless: false, seamSize: 96, seamSteps: 30, seamStrength: 0.7, @@ -62,6 +64,7 @@ export const initialGenerationState: GenerationState = { shouldFitToWidthHeight: true, shouldGenerateVariations: false, shouldRandomizeSeed: true, + shouldUseNoiseSettings: false, steps: 50, threshold: 0, tileSize: 32, @@ -72,6 +75,9 @@ export const initialGenerationState: GenerationState = { verticalSymmetrySteps: 0, isImageToImageEnabled: false, model: '', + shouldUseSeamless: false, + seamlessXAxis: true, + seamlessYAxis: true, }; const initialState: GenerationState = initialGenerationState; @@ -146,7 +152,13 @@ export const generationSlice = createSlice({ state.maskPath = action.payload; }, setSeamless: (state, action: PayloadAction) => { - state.seamless = action.payload; + state.shouldUseSeamless = action.payload; + }, + setSeamlessXAxis: (state, action: PayloadAction) => { + state.seamlessXAxis = action.payload; + }, + setSeamlessYAxis: (state, action: PayloadAction) => { + state.seamlessYAxis = action.payload; }, setShouldFitToWidthHeight: (state, action: PayloadAction) => { state.shouldFitToWidthHeight = action.payload; @@ -348,6 +360,9 @@ export const generationSlice = createSlice({ setVerticalSymmetrySteps: (state, action: PayloadAction) => { state.verticalSymmetrySteps = action.payload; }, + setShouldUseNoiseSettings: (state, action: PayloadAction) => { + state.shouldUseNoiseSettings = action.payload; + }, initialImageChanged: (state, action: PayloadAction) => { state.initialImage = action.payload; state.isImageToImageEnabled = true; @@ -382,7 +397,6 @@ export const { setNegativePrompt, setSampler, setSeamBlur, - setSeamless, setSeamSize, setSeamSteps, setSeamStrength, @@ -402,6 +416,10 @@ export const { initialImageChanged, isImageToImageEnabledChanged, modelSelected, + setShouldUseNoiseSettings, + setSeamless, + setSeamlessXAxis, + setSeamlessYAxis, } = generationSlice.actions; export default generationSlice.reducer; diff --git a/invokeai/frontend/web/src/features/parameters/store/hiresSlice.ts b/invokeai/frontend/web/src/features/parameters/store/hiresSlice.ts new file mode 100644 index 0000000000..15098afed5 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/store/hiresSlice.ts @@ -0,0 +1,98 @@ +import type { PayloadAction } from '@reduxjs/toolkit'; +import { createSlice } from '@reduxjs/toolkit'; +import { FACETOOL_TYPES } from 'app/constants'; + +export interface HiresState { + codeformerFidelity: number; + facetoolStrength: number; + facetoolType: FacetoolType; + hiresFix: boolean; + hiresStrength: number; + shouldLoopback: boolean; + shouldRunESRGAN: boolean; + shouldRunFacetool: boolean; + upscalingLevel: UpscalingLevel; + upscalingDenoising: number; + upscalingStrength: number; +} + +export const initialHiresState: HiresState = { + codeformerFidelity: 0.75, + facetoolStrength: 0.75, + facetoolType: 'gfpgan', + hiresFix: false, + hiresStrength: 0.75, + hiresSteps: 30, + hiresWidth: 512, + hiresHeight: 512, + hiresModel: '', + shouldLoopback: false, + shouldRunESRGAN: false, + shouldRunFacetool: false, + upscalingLevel: 4, + upscalingDenoising: 0.75, + upscalingStrength: 0.75, +}; + +export const postprocessingSlice = createSlice({ + name: 'postprocessing', + initialState: initialPostprocessingState, + reducers: { + setFacetoolStrength: (state, action: PayloadAction) => { + state.facetoolStrength = action.payload; + }, + setCodeformerFidelity: (state, action: PayloadAction) => { + state.codeformerFidelity = action.payload; + }, + setUpscalingLevel: (state, action: PayloadAction) => { + state.upscalingLevel = action.payload; + }, + setUpscalingDenoising: (state, action: PayloadAction) => { + state.upscalingDenoising = action.payload; + }, + setUpscalingStrength: (state, action: PayloadAction) => { + state.upscalingStrength = action.payload; + }, + setHiresFix: (state, action: PayloadAction) => { + state.hiresFix = action.payload; + }, + setHiresStrength: (state, action: PayloadAction) => { + state.hiresStrength = action.payload; + }, + resetPostprocessingState: (state) => { + return { + ...state, + ...initialPostprocessingState, + }; + }, + setShouldRunFacetool: (state, action: PayloadAction) => { + state.shouldRunFacetool = action.payload; + }, + setFacetoolType: (state, action: PayloadAction) => { + state.facetoolType = action.payload; + }, + setShouldRunESRGAN: (state, action: PayloadAction) => { + state.shouldRunESRGAN = action.payload; + }, + setShouldLoopback: (state, action: PayloadAction) => { + state.shouldLoopback = action.payload; + }, + }, +}); + +export const { + resetPostprocessingState, + setCodeformerFidelity, + setFacetoolStrength, + setFacetoolType, + setHiresFix, + setHiresStrength, + setShouldLoopback, + setShouldRunESRGAN, + setShouldRunFacetool, + setUpscalingLevel, + setUpscalingDenoising, + setUpscalingStrength, +} = postprocessingSlice.actions; + +export default postprocessingSlice.reducer; diff --git a/invokeai/frontend/web/src/features/ui/components/CreateParametersDrawer.tsx b/invokeai/frontend/web/src/features/ui/components/CreateParametersDrawer.tsx index a033ae3a05..0518d792cb 100644 --- a/invokeai/frontend/web/src/features/ui/components/CreateParametersDrawer.tsx +++ b/invokeai/frontend/web/src/features/ui/components/CreateParametersDrawer.tsx @@ -1,6 +1,6 @@ import { isEqual } from 'lodash-es'; import ResizableDrawer from './common/ResizableDrawer/ResizableDrawer'; -import CreateBaseSettings from './tabs/Create/CreateBaseSettings'; +import TextTabParameters from './tabs/text/TextTabParameters'; import { createSelector } from '@reduxjs/toolkit'; import { activeTabNameSelector, uiSelector } from '../store/uiSelectors'; import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors'; @@ -14,10 +14,10 @@ import { Flex } from '@chakra-ui/react'; import InvokeAILogoComponent from 'features/system/components/InvokeAILogoComponent'; import PinParametersPanelButton from './PinParametersPanelButton'; import { Panel, PanelGroup } from 'react-resizable-panels'; -import CreateSidePanelPinned from './tabs/Create/CreateSidePanelPinned'; -import CreateTextParameters from './tabs/Create/CreateBaseSettings'; +import CreateSidePanelPinned from './tabs/text/TextTabSettingsPinned'; +import CreateTextParameters from './tabs/text/TextTabParameters'; import ResizeHandle from './tabs/ResizeHandle'; -import CreateImageSettings from './tabs/Create/CreateImageSettings'; +import CreateImageSettings from './tabs/image/ImageTabSettings'; const selector = createSelector( [uiSelector, activeTabNameSelector, lightboxSelector], diff --git a/invokeai/frontend/web/src/features/ui/components/FloatingParametersPanelButtons.tsx b/invokeai/frontend/web/src/features/ui/components/FloatingParametersPanelButtons.tsx index 90d199076d..8ceb8ee20a 100644 --- a/invokeai/frontend/web/src/features/ui/components/FloatingParametersPanelButtons.tsx +++ b/invokeai/frontend/web/src/features/ui/components/FloatingParametersPanelButtons.tsx @@ -40,7 +40,7 @@ export const floatingParametersPanelButtonSelector = createSelector( const shouldShowParametersPanelButton = !canvasBetaLayoutCheck && !shouldShowParametersPanel && - ['generate', 'unifiedCanvas'].includes(activeTabName); + ['text', 'image', 'unifiedCanvas'].includes(activeTabName); return { shouldPinParametersPanel, diff --git a/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx b/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx index 509272a2e4..3cda3111b7 100644 --- a/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx +++ b/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx @@ -26,31 +26,34 @@ import { } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; import { MdDeviceHub, MdGridOn } from 'react-icons/md'; +import { GoTextSize } from 'react-icons/go'; import { activeTabIndexSelector } from '../store/uiSelectors'; import UnifiedCanvasWorkarea from 'features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasWorkarea'; import { useTranslation } from 'react-i18next'; import { ResourceKey } from 'i18next'; import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale'; import NodeEditor from 'features/nodes/components/NodeEditor'; -import GenerateWorkspace from './tabs/Create/GenerateWorkspace'; +import GenerateWorkspace from './tabs/text/GenerateWorkspace'; import { createSelector } from '@reduxjs/toolkit'; import { BsLightningChargeFill } from 'react-icons/bs'; import { configSelector } from 'features/system/store/configSelectors'; import { isEqual } from 'lodash-es'; import AnimatedImageToImagePanel from 'features/parameters/components/AnimatedImageToImagePanel'; import Scrollable from './common/Scrollable'; -import CreateBaseSettings from './tabs/Create/CreateBaseSettings'; +import TextTabParameters from './tabs/text/TextTabParameters'; import PinParametersPanelButton from './PinParametersPanelButton'; import ParametersSlide from './common/ParametersSlide'; import ImageGalleryPanel from 'features/gallery/components/ImageGalleryPanel'; import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels'; import ImageGalleryContent from 'features/gallery/components/ImageGalleryContent'; -import CreateTabContent from './tabs/Create/CreateContent'; +import TextTabMain from './tabs/text/TextTabMain'; import ParametersPanel from './ParametersPanel'; import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; -import CreateTab from './tabs/Create/CreateTab'; +import TextTab from './tabs/text/TextTab'; import UnifiedCanvasTab from './tabs/UnifiedCanvas/UnifiedCanvasTab'; import NodesTab from './tabs/Nodes/NodesTab'; +import { FaImage } from 'react-icons/fa'; +import ResizeHandle from './tabs/ResizeHandle'; export interface InvokeTabInfo { id: InvokeTabName; @@ -60,9 +63,14 @@ export interface InvokeTabInfo { const tabs: InvokeTabInfo[] = [ { - id: 'generate', - icon: , - content: , + id: 'text', + icon: , + content: , + }, + { + id: 'image', + icon: , + content: , }, { id: 'unifiedCanvas', @@ -107,14 +115,18 @@ const InvokeTabs = () => { const dispatch = useAppDispatch(); useHotkeys('1', () => { - dispatch(setActiveTab('generate')); + dispatch(setActiveTab('text')); }); useHotkeys('2', () => { - dispatch(setActiveTab('unifiedCanvas')); + dispatch(setActiveTab('image')); }); useHotkeys('3', () => { + dispatch(setActiveTab('unifiedCanvas')); + }); + + useHotkeys('4', () => { dispatch(setActiveTab('nodes')); }); @@ -183,23 +195,27 @@ const InvokeTabs = () => { > {tabs} - {tabPanels} + + + + {tabPanels} + + + {shouldPinGallery && shouldShowGallery && ( + <> + + + + + + )} + ); }; export default memo(InvokeTabs); - -// -// -// -// -// -// -// -// -// -// -// -// -// ; diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateBaseSettings.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateBaseSettings.tsx deleted file mode 100644 index 1208f867b2..0000000000 --- a/invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateBaseSettings.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import { - AspectRatio, - Box, - Flex, - Select, - Slider, - SliderFilledTrack, - SliderThumb, - SliderTrack, - Text, -} from '@chakra-ui/react'; -import { Feature } from 'app/features'; -import IAISlider from 'common/components/IAISlider'; -import IAISwitch from 'common/components/IAISwitch'; -import ImageToImageSettings from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageSettings'; -import ImageToImageToggle from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageToggle'; -import OutputSettings from 'features/parameters/components/AdvancedParameters/Output/OutputSettings'; -import SymmetrySettings from 'features/parameters/components/AdvancedParameters/Output/SymmetrySettings'; -import SymmetryToggle from 'features/parameters/components/AdvancedParameters/Output/SymmetryToggle'; -import RandomizeSeed from 'features/parameters/components/AdvancedParameters/Seed/RandomizeSeed'; -import SeedSettings from 'features/parameters/components/AdvancedParameters/Seed/SeedSettings'; -import GenerateVariationsToggle from 'features/parameters/components/AdvancedParameters/Variations/GenerateVariations'; -import VariationsSettings from 'features/parameters/components/AdvancedParameters/Variations/VariationsSettings'; -import DimensionsSettings from 'features/parameters/components/ImageDimensions/DimensionsSettings'; -import MainSettings from 'features/parameters/components/MainParameters/MainSettings'; -import ParametersAccordion, { - ParametersAccordionItems, -} from 'features/parameters/components/ParametersAccordion'; -import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons'; -import NegativePromptInput from 'features/parameters/components/PromptInput/NegativePromptInput'; -import PromptInput from 'features/parameters/components/PromptInput/PromptInput'; -import { findIndex } from 'lodash-es'; -import { - OverlayScrollbarsComponent, - useOverlayScrollbars, -} from 'overlayscrollbars-react'; -import { memo, useMemo, useState, useRef, useEffect } from 'react'; -import { useTranslation } from 'react-i18next'; -import { PARAMETERS_PANEL_WIDTH } from 'theme/util/constants'; -import OverlayScrollable from '../../common/OverlayScrollable'; -import AnimatedImageToImagePanel from 'features/parameters/components/AnimatedImageToImagePanel'; - -const CreateBaseSettings = () => { - const { t } = useTranslation(); - - const generateAccordionItems: ParametersAccordionItems = useMemo( - () => ({ - // general: { - // name: 'general', - // header: `${t('parameters.general')}`, - // feature: undefined, - // content: , - // }, - seed: { - name: 'seed', - header: `${t('parameters.seed')}`, - feature: Feature.SEED, - content: , - additionalHeaderComponents: , - }, - // imageToImage: { - // name: 'imageToImage', - // header: `${t('parameters.imageToImage')}`, - // feature: undefined, - // content: , - // additionalHeaderComponents: , - // }, - variations: { - name: 'variations', - header: `${t('parameters.variations')}`, - feature: Feature.VARIATIONS, - content: , - additionalHeaderComponents: , - }, - symmetry: { - name: 'symmetry', - header: `${t('parameters.symmetry')}`, - content: , - additionalHeaderComponents: , - }, - other: { - name: 'other', - header: `${t('parameters.otherOptions')}`, - feature: Feature.OTHER, - content: , - }, - }), - [t] - ); - - return ( - - - - - - - - - - - - - ); -}; - -export default memo(CreateBaseSettings); diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/Create/GenerateWorkspace.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/Create/GenerateWorkspace.tsx deleted file mode 100644 index a49836e027..0000000000 --- a/invokeai/frontend/web/src/features/ui/components/tabs/Create/GenerateWorkspace.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { Box, Flex } from '@chakra-ui/react'; -import { useAppSelector } from 'app/store/storeHooks'; -import { memo } from 'react'; -import CreateTabContent from './CreateContent'; -import CreateBaseSettings from './CreateBaseSettings'; -import PinParametersPanelButton from '../../PinParametersPanelButton'; -import { RootState } from 'app/store/store'; -import Scrollable from '../../common/Scrollable'; -import ParametersSlide from '../../common/ParametersSlide'; -import AnimatedImageToImagePanel from 'features/parameters/components/AnimatedImageToImagePanel'; - -const GenerateWorkspace = () => { - const shouldPinParametersPanel = useAppSelector( - (state: RootState) => state.ui.shouldPinParametersPanel - ); - - return ; - - return ( - - {shouldPinParametersPanel ? ( - - - - - - - - - - ) : ( - - - - )} - - - ); -}; - -export default memo(GenerateWorkspace); diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ResizeHandle.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ResizeHandle.tsx index e75a4fa88a..c62f82600b 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/ResizeHandle.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ResizeHandle.tsx @@ -2,13 +2,40 @@ import { Box, Flex } from '@chakra-ui/react'; import { memo } from 'react'; import { PanelResizeHandle } from 'react-resizable-panels'; -const ResizeHandle = () => { +type ResizeHandleProps = { + direction?: 'horizontal' | 'vertical'; +}; + +const ResizeHandle = (props: ResizeHandleProps) => { + const { direction = 'horizontal' } = props; + + if (direction === 'horizontal') { + return ( + + + + + + ); + } return ( - + ); diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasParameters.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasParameters.tsx index 5e64f72cc4..3c4ccb10b6 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasParameters.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasParameters.tsx @@ -4,20 +4,23 @@ import BoundingBoxSettings from 'features/parameters/components/AdvancedParamete import InfillAndScalingSettings from 'features/parameters/components/AdvancedParameters/Canvas/InfillAndScalingSettings'; import SeamCorrectionSettings from 'features/parameters/components/AdvancedParameters/Canvas/SeamCorrection/SeamCorrectionSettings'; import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength'; -import SymmetrySettings from 'features/parameters/components/AdvancedParameters/Output/SymmetrySettings'; -import SymmetryToggle from 'features/parameters/components/AdvancedParameters/Output/SymmetryToggle'; -import SeedSettings from 'features/parameters/components/AdvancedParameters/Seed/SeedSettings'; -import GenerateVariationsToggle from 'features/parameters/components/AdvancedParameters/Variations/GenerateVariations'; -import VariationsSettings from 'features/parameters/components/AdvancedParameters/Variations/VariationsSettings'; import MainSettings from 'features/parameters/components/MainParameters/MainSettings'; import ParametersAccordion, { ParametersAccordionItems, } from 'features/parameters/components/ParametersAccordion'; import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons'; -import NegativePromptInput from 'features/parameters/components/PromptInput/NegativePromptInput'; -import PromptInput from 'features/parameters/components/PromptInput/PromptInput'; import { useTranslation } from 'react-i18next'; import OverlayScrollable from '../../common/OverlayScrollable'; +// import ParamSeedSettings from 'features/parameters/components/Parameters/Seed/ParamSeedSettings'; +// import ParamVariationSettings from 'features/parameters/components/Parameters/Variations/ParamVariationSettings'; +// import ParamSymmetrySettings from 'features/parameters/components/Parameters/Symmetry/ParamSymmetrySettings'; +// import ParamVariationToggle from 'features/parameters/components/Parameters/Variations/ParamVariationToggle'; +// import ParamSymmetryToggle from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryToggle'; +import ParamPositiveConditioning from 'features/parameters/components/Parameters/ParamPositiveConditioning'; +import ParamNegativeConditioning from 'features/parameters/components/Parameters/ParamNegativeConditioning'; +import ParamSeedCollapse from 'features/parameters/components/Parameters/Seed/ParamSeedCollapse'; +import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse'; +import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse'; export default function UnifiedCanvasParameters() { const { t } = useTranslation(); @@ -35,12 +38,12 @@ export default function UnifiedCanvasParameters() { feature: undefined, content: , }, - seed: { - name: 'seed', - header: `${t('parameters.seed')}`, - feature: Feature.SEED, - content: , - }, + // seed: { + // name: 'seed', + // header: `${t('parameters.seed')}`, + // feature: Feature.SEED, + // content: , + // }, boundingBox: { name: 'boundingBox', header: `${t('parameters.boundingBoxHeader')}`, @@ -59,19 +62,19 @@ export default function UnifiedCanvasParameters() { feature: Feature.INFILL_AND_SCALING, content: , }, - variations: { - name: 'variations', - header: `${t('parameters.variations')}`, - feature: Feature.VARIATIONS, - content: , - additionalHeaderComponents: , - }, - symmetry: { - name: 'symmetry', - header: `${t('parameters.symmetry')}`, - content: , - additionalHeaderComponents: , - }, + // variations: { + // name: 'variations', + // header: `${t('parameters.variations')}`, + // feature: Feature.VARIATIONS, + // content: , + // additionalHeaderComponents: , + // }, + // symmetry: { + // name: 'symmetry', + // header: `${t('parameters.symmetry')}`, + // content: , + // additionalHeaderComponents: , + // }, }; return ( @@ -85,9 +88,12 @@ export default function UnifiedCanvasParameters() { position: 'absolute', }} > - - + + + + + diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateTab.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/image/ImageTab.tsx similarity index 53% rename from invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateTab.tsx rename to invokeai/frontend/web/src/features/ui/components/tabs/image/ImageTab.tsx index 9bd11d828b..b069ff31db 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateTab.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/image/ImageTab.tsx @@ -1,20 +1,12 @@ import { Portal, TabPanel } from '@chakra-ui/react'; import { memo } from 'react'; -import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels'; -import CreateBaseSettings from './CreateBaseSettings'; +import { Panel, PanelGroup } from 'react-resizable-panels'; import PinParametersPanelButton from '../../PinParametersPanelButton'; -import ImageGalleryContent from 'features/gallery/components/ImageGalleryContent'; import { createSelector } from '@reduxjs/toolkit'; import { uiSelector } from 'features/ui/store/uiSelectors'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale'; -import CreateTabContent from './CreateContent'; import ResizeHandle from '../ResizeHandle'; -import AnimatedImageToImagePanel from 'features/parameters/components/AnimatedImageToImagePanel'; -import ImageToImageSettings from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageSettings'; -import CreateSidePanelPinned from './CreateSidePanelPinned'; -import CreateTextParameters from './CreateBaseSettings'; -import CreateImageSettings from './CreateImageSettings'; const selector = createSelector(uiSelector, (ui) => { const { @@ -34,7 +26,7 @@ const selector = createSelector(uiSelector, (ui) => { }; }); -const CreateTab = () => { +const TextTab = () => { const dispatch = useAppDispatch(); const { shouldPinGallery, @@ -46,61 +38,39 @@ const CreateTab = () => { return ( {shouldPinParametersPanel && shouldShowParametersPanel && ( <> - + {/* */} - {shouldShowImageParameters && ( - <> - - - - - - )} )} { dispatch(requestCanvasRescale()); }} > - + {/* */} - {shouldPinGallery && shouldShowGallery && ( - <> - - - - - - )} ); }; -export default memo(CreateTab); +export default memo(TextTab); diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateImageSettings.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/image/ImageTabSettings.tsx similarity index 100% rename from invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateImageSettings.tsx rename to invokeai/frontend/web/src/features/ui/components/tabs/image/ImageTabSettings.tsx diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/text/TextTab.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/text/TextTab.tsx new file mode 100644 index 0000000000..c26700a39d --- /dev/null +++ b/invokeai/frontend/web/src/features/ui/components/tabs/text/TextTab.tsx @@ -0,0 +1,78 @@ +import { Portal, TabPanel } from '@chakra-ui/react'; +import { memo } from 'react'; +import { Panel, PanelGroup } from 'react-resizable-panels'; +import PinParametersPanelButton from '../../PinParametersPanelButton'; +import { createSelector } from '@reduxjs/toolkit'; +import { uiSelector } from 'features/ui/store/uiSelectors'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale'; +import TextTabMain from './TextTabMain'; +import ResizeHandle from '../ResizeHandle'; +import TextTabSettings from './TextTabParameters'; + +const selector = createSelector(uiSelector, (ui) => { + const { + shouldPinGallery, + shouldShowGallery, + shouldPinParametersPanel, + shouldShowParametersPanel, + shouldShowImageParameters, + } = ui; + + return { + shouldPinGallery, + shouldShowGallery, + shouldPinParametersPanel, + shouldShowParametersPanel, + shouldShowImageParameters, + }; +}); + +const TextTab = () => { + const dispatch = useAppDispatch(); + const { + shouldPinGallery, + shouldShowGallery, + shouldPinParametersPanel, + shouldShowParametersPanel, + shouldShowImageParameters, + } = useAppSelector(selector); + + return ( + + {shouldPinParametersPanel && shouldShowParametersPanel && ( + <> + + + + + + + )} + { + dispatch(requestCanvasRescale()); + }} + > + + + + ); +}; + +export default memo(TextTab); diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateContent.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/text/TextTabMain.tsx similarity index 89% rename from invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateContent.tsx rename to invokeai/frontend/web/src/features/ui/components/tabs/text/TextTabMain.tsx index bad7475c2e..36c5f9bd94 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateContent.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/text/TextTabMain.tsx @@ -2,7 +2,7 @@ import { Box, Flex } from '@chakra-ui/react'; import CurrentImageDisplay from 'features/gallery/components/CurrentImageDisplay'; import ProgressImagePreview from 'features/parameters/components/ProgressImagePreview'; -const CreateTabContent = () => { +const TextTabMain = () => { return ( { ); }; -export default CreateTabContent; +export default TextTabMain; diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/text/TextTabParameters.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/text/TextTabParameters.tsx new file mode 100644 index 0000000000..eaf3362539 --- /dev/null +++ b/invokeai/frontend/web/src/features/ui/components/tabs/text/TextTabParameters.tsx @@ -0,0 +1,108 @@ +import { Box, Flex } from '@chakra-ui/react'; +import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons'; +import { memo } from 'react'; +import OverlayScrollable from '../../common/OverlayScrollable'; +import ParamPositiveConditioning from 'features/parameters/components/Parameters/ParamPositiveConditioning'; +import ParamNegativeConditioning from 'features/parameters/components/Parameters/ParamNegativeConditioning'; +import { createSelector } from '@reduxjs/toolkit'; +import { uiSelector } from 'features/ui/store/uiSelectors'; +import { useAppSelector } from 'app/store/storeHooks'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import ParamIterations from 'features/parameters/components/Parameters/ParamIterations'; +import ParamSteps from 'features/parameters/components/Parameters/ParamSteps'; +import ParamCFGScale from 'features/parameters/components/Parameters/ParamCFGScale'; +import ParamWidth from 'features/parameters/components/Parameters/ParamWidth'; +import ParamHeight from 'features/parameters/components/Parameters/ParamHeight'; +import ParamScheduler from 'features/parameters/components/Parameters/ParamScheduler'; +import ModelSelect from 'features/system/components/ModelSelect'; +import ParamSeedCollapse from 'features/parameters/components/Parameters/Seed/ParamSeedCollapse'; +import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse'; +import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse'; +import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse'; +import ParamHiresCollapse from 'features/parameters/components/Parameters/Hires/ParamHiresCollapse'; +import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse'; + +const selector = createSelector( + uiSelector, + (ui) => { + const { shouldUseSliders } = ui; + + return { shouldUseSliders }; + }, + defaultSelectorOptions +); + +const TextTabParameters = () => { + const { shouldUseSliders } = useAppSelector(selector); + + return ( + + + + + + + {shouldUseSliders ? ( + + + + + + + + + + + + + + + + ) : ( + + + + + + + + + + + + + + + + + + )} + + + + + + + + + + ); +}; + +export default memo(TextTabParameters); diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateSidePanelPinned.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/text/TextTabSettingsPinned.tsx similarity index 93% rename from invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateSidePanelPinned.tsx rename to invokeai/frontend/web/src/features/ui/components/tabs/text/TextTabSettingsPinned.tsx index b17237d46e..9d58eed899 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/Create/CreateSidePanelPinned.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/text/TextTabSettingsPinned.tsx @@ -3,12 +3,12 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { uiSelector } from 'features/ui/store/uiSelectors'; import { memo } from 'react'; import { Panel } from 'react-resizable-panels'; -import CreateTextParameters from './CreateBaseSettings'; +import CreateTextParameters from './TextTabParameters'; import PinParametersPanelButton from '../../PinParametersPanelButton'; import ResizeHandle from '../ResizeHandle'; import ImageToImageSettings from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageSettings'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; -import CreateImageSettings from './CreateImageSettings'; +import CreateImageSettings from '../image/ImageTabSettings'; const selector = createSelector( uiSelector, diff --git a/invokeai/frontend/web/src/features/ui/store/tabMap.ts b/invokeai/frontend/web/src/features/ui/store/tabMap.ts index fe6e2d033a..30bfb459a0 100644 --- a/invokeai/frontend/web/src/features/ui/store/tabMap.ts +++ b/invokeai/frontend/web/src/features/ui/store/tabMap.ts @@ -1,7 +1,7 @@ export const tabMap = [ - // 'txt2img', - // 'img2img', - 'generate', + 'text', + 'image', + // 'generate', 'unifiedCanvas', 'nodes', // 'postprocessing', diff --git a/invokeai/frontend/web/src/features/ui/store/uiSlice.ts b/invokeai/frontend/web/src/features/ui/store/uiSlice.ts index c4e2ad367c..b585c5300b 100644 --- a/invokeai/frontend/web/src/features/ui/store/uiSlice.ts +++ b/invokeai/frontend/web/src/features/ui/store/uiSlice.ts @@ -18,9 +18,9 @@ export const initialUIState: UIState = { shouldPinGallery: true, shouldShowGallery: true, shouldHidePreview: false, - openLinearAccordionItems: [], - openGenerateAccordionItems: [], - openUnifiedCanvasAccordionItems: [], + textTabAccordionState: [], + imageTabAccordionState: [], + canvasTabAccordionState: [], floatingProgressImageRect: { x: 0, y: 0, width: 0, height: 0 }, shouldShowProgressImages: false, shouldAutoShowProgressImages: false, @@ -105,12 +105,16 @@ export const uiSlice = createSlice({ } }, openAccordionItemsChanged: (state, action: PayloadAction) => { - if (tabMap[state.activeTab] === 'generate') { - state.openGenerateAccordionItems = action.payload; + if (tabMap[state.activeTab] === 'text') { + state.textTabAccordionState = action.payload; + } + + if (tabMap[state.activeTab] === 'image') { + state.imageTabAccordionState = action.payload; } if (tabMap[state.activeTab] === 'unifiedCanvas') { - state.openUnifiedCanvasAccordionItems = action.payload; + state.canvasTabAccordionState = action.payload; } }, floatingProgressImageMoved: (state, action: PayloadAction) => { diff --git a/invokeai/frontend/web/src/features/ui/store/uiTypes.ts b/invokeai/frontend/web/src/features/ui/store/uiTypes.ts index 3e2a3a1616..59140cdfde 100644 --- a/invokeai/frontend/web/src/features/ui/store/uiTypes.ts +++ b/invokeai/frontend/web/src/features/ui/store/uiTypes.ts @@ -26,9 +26,9 @@ export interface UIState { shouldHidePreview: boolean; shouldPinGallery: boolean; shouldShowGallery: boolean; - openLinearAccordionItems: number[]; - openGenerateAccordionItems: number[]; - openUnifiedCanvasAccordionItems: number[]; + textTabAccordionState: number[]; + imageTabAccordionState: number[]; + canvasTabAccordionState: number[]; floatingProgressImageRect: Rect; shouldShowProgressImages: boolean; shouldAutoShowProgressImages: boolean;