mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
(wip) add informational popover base component and sample (#4522)
## What type of PR is this? (check all applicable) - [ ] Refactor - [x] Feature - [ ] Bug Fix - [ ] Optimization - [ ] Documentation Update - [ ] Community Node Submission ## Have you discussed this change with the InvokeAI team? - [x] Yes - [ ] No, because: ## Have you updated all relevant documentation? - [ ] Yes - [ ] No ## Description Adds a new common component `IAIInformationPopover` that composes JSX to be rendered within a popover as a tooltip. We were not able to use the `Tooltip` component provided by chakra because you cannot interact with elements within those (at least not that I could get working). This just a sample over positive prompt. We need content from @hipsterusername and @Millu before we can roll this out. ## Related Tickets & Documents <!-- For pull requests that relate or close an issue, please include them below. For example having the text: "closes #1234" would connect the current pull request to issue 1234. And when we merge the pull request, Github will automatically close the issue. --> - Related Issue # - Closes # ## QA Instructions, Screenshots, Recordings <!-- Please provide steps on how to test changes, any hardware or software specifications as well as any other pertinent information. --> ## Added/updated tests? - [ ] Yes - [ ] No : _please replace this line with details on why tests have not been included_ ## [optional] Are there any post deployment tasks we need to perform?
This commit is contained in:
commit
8b8d589033
@ -1154,6 +1154,136 @@
|
|||||||
"variations": "Try a variation with a value between 0.1 and 1.0 to change the result for a given seed. Interesting variations of the seed are between 0.1 and 0.3."
|
"variations": "Try a variation with a value between 0.1 and 1.0 to change the result for a given seed. Interesting variations of the seed are between 0.1 and 0.3."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"popovers": {
|
||||||
|
"clipSkip": {
|
||||||
|
"heading": "CLIP Skip",
|
||||||
|
"paragraph": "Choose how many layers of the CLIP model to skip. Certain models are better suited to be used with CLIP Skip."
|
||||||
|
},
|
||||||
|
"compositingBlur": {
|
||||||
|
"heading": "Blur",
|
||||||
|
"paragraph": "The blur radius of the mask."
|
||||||
|
},
|
||||||
|
"compositingBlurMethod": {
|
||||||
|
"heading": "Blur Method",
|
||||||
|
"paragraph": "The method of blur applied to the masked area."
|
||||||
|
},
|
||||||
|
"compositingCoherencePass": {
|
||||||
|
"heading": "Coherence Pass",
|
||||||
|
"paragraph": "Composite the Inpainted/Outpainted images."
|
||||||
|
},
|
||||||
|
"compositingCoherenceMode": {
|
||||||
|
"heading": "Mode",
|
||||||
|
"paragraph": "The mode of the Coherence Pass."
|
||||||
|
},
|
||||||
|
"compositingCoherenceSteps": {
|
||||||
|
"heading": "Steps",
|
||||||
|
"paragraph": "Number of steps in the Coherence Pass. Similar to Denoising Steps."
|
||||||
|
},
|
||||||
|
"compositingStrength": {
|
||||||
|
"heading": "Strength",
|
||||||
|
"paragraph": "Amount of noise added for the Coherence Pass. Similar to Denoising Strength."
|
||||||
|
},
|
||||||
|
"compositingMaskAdjustments": {
|
||||||
|
"heading": "Mask Adjustments",
|
||||||
|
"paragraph": "Adjust the mask."
|
||||||
|
},
|
||||||
|
"controlNetBeginEnd": {
|
||||||
|
"heading": "Begin / End Step Percentage",
|
||||||
|
"paragraph": "Which parts of the denoising process will have the ControlNet applied. ControlNets applied at the start of the process guide composition, and ControlNets applied at the end guide details."
|
||||||
|
},
|
||||||
|
"controlNetControlMode": {
|
||||||
|
"heading": "Control Mode",
|
||||||
|
"paragraph": "Lends more weight to either the prompt or ControlNet."
|
||||||
|
},
|
||||||
|
"controlNetResizeMode": {
|
||||||
|
"heading": "Resize Mode",
|
||||||
|
"paragraph": "How the ControlNet image will be fit to the image generation Ratio"
|
||||||
|
},
|
||||||
|
"controlNetToggle": {
|
||||||
|
"heading": "Enable ControlNet",
|
||||||
|
"paragraph": "ControlNets provide guidance to the generation process, helping create images with controlled composition, structure, or style, depending on the model selected."
|
||||||
|
},
|
||||||
|
"controlNetWeight": {
|
||||||
|
"heading": "Weight",
|
||||||
|
"paragraph": "How strongly the ControlNet will impact the generated image."
|
||||||
|
},
|
||||||
|
"dynamicPromptsToggle": {
|
||||||
|
"heading": "Enable Dynamic Prompts",
|
||||||
|
"paragraph": "Dynamic prompts allow multiple options within a prompt. Dynamic prompts can be used by: {option1|option2|option3}. Combinations of prompts will be randomly generated until the “Images” number has been reached."
|
||||||
|
},
|
||||||
|
"dynamicPromptsCombinatorial": {
|
||||||
|
"heading": "Combinatorial Generation",
|
||||||
|
"paragraph": "Generate an image for every possible combination of Dynamic Prompt until the Max Prompts is reached."
|
||||||
|
},
|
||||||
|
"infillMethod": {
|
||||||
|
"heading": "Infill Method",
|
||||||
|
"paragraph": "Method to infill the selected area."
|
||||||
|
},
|
||||||
|
"lora": {
|
||||||
|
"heading": "LoRA",
|
||||||
|
"paragraph": "Weight of the LoRA. Higher weight will lead to larger impacts on the final image."
|
||||||
|
},
|
||||||
|
"noiseEnable": {
|
||||||
|
"heading": "Enable Noise Settings",
|
||||||
|
"paragraph": "Advanced control over noise generation."
|
||||||
|
},
|
||||||
|
"noiseUseCPU": {
|
||||||
|
"heading": "Use CPU Noise",
|
||||||
|
"paragraph": "Uses the CPU to generate random noise."
|
||||||
|
},
|
||||||
|
"paramCFGScale": {
|
||||||
|
"heading": "CFG Scale",
|
||||||
|
"paragraph": "Controls how much your prompt influences the generation process."
|
||||||
|
},
|
||||||
|
"paramDenoisingStrength": {
|
||||||
|
"heading": "Denoising Strength",
|
||||||
|
"paragraph": "How much noise is added to the input image. 0 will result in an identical image, while 1 will result in a completely new image."
|
||||||
|
},
|
||||||
|
"paramImages": {
|
||||||
|
"heading": "Images",
|
||||||
|
"paragraph": "Number of images that will be generated."
|
||||||
|
},
|
||||||
|
"paramModel": {
|
||||||
|
"heading": "Model",
|
||||||
|
"paragraph": "Model used for the denoising steps. Different models are trained to specialize in producing different aesthetic results and content."
|
||||||
|
},
|
||||||
|
"paramNegativeConditioning": {
|
||||||
|
"heading": "Negative Prompts",
|
||||||
|
"paragraph": "This is where you enter your negative prompts."
|
||||||
|
},
|
||||||
|
"paramPositiveConditioning": {
|
||||||
|
"heading": "Positive Prompts",
|
||||||
|
"paragraph": "This is where you enter your positive prompts."
|
||||||
|
},
|
||||||
|
"paramRatio": {
|
||||||
|
"heading": "Ratio",
|
||||||
|
"paragraph": "The ratio of the dimensions of the image generated. An image size (in number of pixels) equivalent to 512x512 is recommended for SD1.5 models and a size equivalent to 1024x1024 is recommended for SDXL models."
|
||||||
|
},
|
||||||
|
"paramScheduler": {
|
||||||
|
"heading": "Scheduler",
|
||||||
|
"paragraph": "Scheduler defines how to iteratively add noise to an image or how to update a sample based on a model's output."
|
||||||
|
},
|
||||||
|
"paramSeed": {
|
||||||
|
"heading": "Seed",
|
||||||
|
"paragraph": "Controls the starting noise used for generation. Disable “Random Seed” to produce identical results with the same generation settings."
|
||||||
|
},
|
||||||
|
"paramSteps": {
|
||||||
|
"heading": "Steps",
|
||||||
|
"paragraph": "Number of steps that will be performed in each generation. Higher step counts will typically create better images but will require more generation time."
|
||||||
|
},
|
||||||
|
"paramVAE": {
|
||||||
|
"heading": "VAE",
|
||||||
|
"paragraph": "Model used for translating AI output into the final image."
|
||||||
|
},
|
||||||
|
"paramVAEPrecision": {
|
||||||
|
"heading": "VAE Precision",
|
||||||
|
"paragraph": "The precision used during VAE encoding and decoding. Fp16/Half precision is more efficient, at the expense of minor image variations."
|
||||||
|
},
|
||||||
|
"scaleBeforeProcessing": {
|
||||||
|
"heading": "Scale Before Processing",
|
||||||
|
"paragraph": "Scales the selected area to the size best suited for the model before the image generation process."
|
||||||
|
}
|
||||||
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"hideProgressImages": "Hide Progress Images",
|
"hideProgressImages": "Hide Progress Images",
|
||||||
"lockRatio": "Lock Ratio",
|
"lockRatio": "Lock Ratio",
|
||||||
|
@ -0,0 +1,112 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Popover,
|
||||||
|
PopoverTrigger,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverArrow,
|
||||||
|
PopoverCloseButton,
|
||||||
|
PopoverHeader,
|
||||||
|
PopoverBody,
|
||||||
|
PopoverProps,
|
||||||
|
Flex,
|
||||||
|
Text,
|
||||||
|
Image,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { useAppSelector } from '../../app/store/storeHooks';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
interface Props extends PopoverProps {
|
||||||
|
details: string;
|
||||||
|
children: JSX.Element;
|
||||||
|
image?: string;
|
||||||
|
buttonLabel?: string;
|
||||||
|
buttonHref?: string;
|
||||||
|
placement?: PopoverProps['placement'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function IAIInformationalPopover({
|
||||||
|
details,
|
||||||
|
image,
|
||||||
|
buttonLabel,
|
||||||
|
buttonHref,
|
||||||
|
children,
|
||||||
|
placement,
|
||||||
|
}: Props): JSX.Element {
|
||||||
|
const shouldDisableInformationalPopovers = useAppSelector(
|
||||||
|
(state) => state.system.shouldDisableInformationalPopovers
|
||||||
|
);
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const heading = t(`popovers.${details}.heading`);
|
||||||
|
const paragraph = t(`popovers.${details}.paragraph`);
|
||||||
|
|
||||||
|
if (shouldDisableInformationalPopovers) {
|
||||||
|
return children;
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Popover
|
||||||
|
placement={placement || 'top'}
|
||||||
|
closeOnBlur={false}
|
||||||
|
trigger="hover"
|
||||||
|
variant="informational"
|
||||||
|
>
|
||||||
|
<PopoverTrigger>
|
||||||
|
<div>{children}</div>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent>
|
||||||
|
<PopoverArrow />
|
||||||
|
<PopoverCloseButton />
|
||||||
|
|
||||||
|
<PopoverBody>
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
gap: 3,
|
||||||
|
flexDirection: 'column',
|
||||||
|
width: '100%',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{image && (
|
||||||
|
<Image
|
||||||
|
sx={{
|
||||||
|
objectFit: 'contain',
|
||||||
|
maxW: '60%',
|
||||||
|
maxH: '60%',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
}}
|
||||||
|
src={image}
|
||||||
|
alt="Optional Image"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
gap: 3,
|
||||||
|
flexDirection: 'column',
|
||||||
|
width: '100%',
|
||||||
|
p: 3,
|
||||||
|
pt: heading ? 0 : 3,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{heading && <PopoverHeader>{heading}</PopoverHeader>}
|
||||||
|
<Text sx={{ px: 3 }}>{paragraph}</Text>
|
||||||
|
{buttonLabel && (
|
||||||
|
<Flex sx={{ px: 3 }} justifyContent="flex-end">
|
||||||
|
<Button
|
||||||
|
onClick={() => window.open(buttonHref)}
|
||||||
|
size="sm"
|
||||||
|
variant="invokeAIOutline"
|
||||||
|
>
|
||||||
|
{buttonLabel}
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</PopoverBody>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IAIInformationalPopover;
|
@ -10,6 +10,7 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import {
|
import {
|
||||||
ControlNetConfig,
|
ControlNetConfig,
|
||||||
controlNetBeginStepPctChanged,
|
controlNetBeginStepPctChanged,
|
||||||
@ -49,58 +50,60 @@ const ParamControlNetBeginEnd = (props: Props) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControl isDisabled={!isEnabled}>
|
<IAIInformationalPopover details="controlNetBeginEnd">
|
||||||
<FormLabel>{t('controlnet.beginEndStepPercent')}</FormLabel>
|
<FormControl isDisabled={!isEnabled}>
|
||||||
<HStack w="100%" gap={2} alignItems="center">
|
<FormLabel>{t('controlnet.beginEndStepPercent')}</FormLabel>
|
||||||
<RangeSlider
|
<HStack w="100%" gap={2} alignItems="center">
|
||||||
aria-label={['Begin Step %', 'End Step %!']}
|
<RangeSlider
|
||||||
value={[beginStepPct, endStepPct]}
|
aria-label={['Begin Step %', 'End Step %!']}
|
||||||
onChange={handleStepPctChanged}
|
value={[beginStepPct, endStepPct]}
|
||||||
min={0}
|
onChange={handleStepPctChanged}
|
||||||
max={1}
|
min={0}
|
||||||
step={0.01}
|
max={1}
|
||||||
minStepsBetweenThumbs={5}
|
step={0.01}
|
||||||
isDisabled={!isEnabled}
|
minStepsBetweenThumbs={5}
|
||||||
>
|
isDisabled={!isEnabled}
|
||||||
<RangeSliderTrack>
|
|
||||||
<RangeSliderFilledTrack />
|
|
||||||
</RangeSliderTrack>
|
|
||||||
<Tooltip label={formatPct(beginStepPct)} placement="top" hasArrow>
|
|
||||||
<RangeSliderThumb index={0} />
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip label={formatPct(endStepPct)} placement="top" hasArrow>
|
|
||||||
<RangeSliderThumb index={1} />
|
|
||||||
</Tooltip>
|
|
||||||
<RangeSliderMark
|
|
||||||
value={0}
|
|
||||||
sx={{
|
|
||||||
insetInlineStart: '0 !important',
|
|
||||||
insetInlineEnd: 'unset !important',
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
0%
|
<RangeSliderTrack>
|
||||||
</RangeSliderMark>
|
<RangeSliderFilledTrack />
|
||||||
<RangeSliderMark
|
</RangeSliderTrack>
|
||||||
value={0.5}
|
<Tooltip label={formatPct(beginStepPct)} placement="top" hasArrow>
|
||||||
sx={{
|
<RangeSliderThumb index={0} />
|
||||||
insetInlineStart: '50% !important',
|
</Tooltip>
|
||||||
transform: 'translateX(-50%)',
|
<Tooltip label={formatPct(endStepPct)} placement="top" hasArrow>
|
||||||
}}
|
<RangeSliderThumb index={1} />
|
||||||
>
|
</Tooltip>
|
||||||
50%
|
<RangeSliderMark
|
||||||
</RangeSliderMark>
|
value={0}
|
||||||
<RangeSliderMark
|
sx={{
|
||||||
value={1}
|
insetInlineStart: '0 !important',
|
||||||
sx={{
|
insetInlineEnd: 'unset !important',
|
||||||
insetInlineStart: 'unset !important',
|
}}
|
||||||
insetInlineEnd: '0 !important',
|
>
|
||||||
}}
|
0%
|
||||||
>
|
</RangeSliderMark>
|
||||||
100%
|
<RangeSliderMark
|
||||||
</RangeSliderMark>
|
value={0.5}
|
||||||
</RangeSlider>
|
sx={{
|
||||||
</HStack>
|
insetInlineStart: '50% !important',
|
||||||
</FormControl>
|
transform: 'translateX(-50%)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
50%
|
||||||
|
</RangeSliderMark>
|
||||||
|
<RangeSliderMark
|
||||||
|
value={1}
|
||||||
|
sx={{
|
||||||
|
insetInlineStart: 'unset !important',
|
||||||
|
insetInlineEnd: '0 !important',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
100%
|
||||||
|
</RangeSliderMark>
|
||||||
|
</RangeSlider>
|
||||||
|
</HStack>
|
||||||
|
</FormControl>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
||||||
import {
|
import {
|
||||||
ControlModes,
|
ControlModes,
|
||||||
@ -34,12 +35,14 @@ export default function ParamControlNetControlMode(
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIMantineSelect
|
<IAIInformationalPopover details="controlNetControlMode">
|
||||||
disabled={!isEnabled}
|
<IAIMantineSelect
|
||||||
label={t('controlnet.controlMode')}
|
disabled={!isEnabled}
|
||||||
data={CONTROL_MODE_DATA}
|
label={t('controlnet.controlMode')}
|
||||||
value={String(controlMode)}
|
data={CONTROL_MODE_DATA}
|
||||||
onChange={handleControlModeChange}
|
value={String(controlMode)}
|
||||||
/>
|
onChange={handleControlModeChange}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { createSelector } from '@reduxjs/toolkit';
|
|||||||
import { stateSelector } from 'app/store/store';
|
import { stateSelector } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAISwitch from 'common/components/IAISwitch';
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
import { isControlNetEnabledToggled } from 'features/controlNet/store/controlNetSlice';
|
import { isControlNetEnabledToggled } from 'features/controlNet/store/controlNetSlice';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
@ -25,14 +26,16 @@ const ParamControlNetFeatureToggle = () => {
|
|||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISwitch
|
<IAIInformationalPopover details="controlNetToggle">
|
||||||
label="Enable ControlNet"
|
<IAISwitch
|
||||||
isChecked={isEnabled}
|
label="Enable ControlNet"
|
||||||
onChange={handleChange}
|
isChecked={isEnabled}
|
||||||
formControlProps={{
|
onChange={handleChange}
|
||||||
width: '100%',
|
formControlProps={{
|
||||||
}}
|
width: '100%',
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
||||||
import {
|
import {
|
||||||
ControlNetConfig,
|
ControlNetConfig,
|
||||||
@ -33,12 +34,14 @@ export default function ParamControlNetResizeMode(
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIMantineSelect
|
<IAIInformationalPopover details="controlNetResizeMode">
|
||||||
disabled={!isEnabled}
|
<IAIMantineSelect
|
||||||
label={t('controlnet.resizeMode')}
|
disabled={!isEnabled}
|
||||||
data={RESIZE_MODE_DATA}
|
label={t('controlnet.resizeMode')}
|
||||||
value={String(resizeMode)}
|
data={RESIZE_MODE_DATA}
|
||||||
onChange={handleResizeModeChange}
|
value={String(resizeMode)}
|
||||||
/>
|
onChange={handleResizeModeChange}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import {
|
import {
|
||||||
ControlNetConfig,
|
ControlNetConfig,
|
||||||
@ -23,17 +24,19 @@ const ParamControlNetWeight = (props: ParamControlNetWeightProps) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<IAIInformationalPopover details="controlNetWeight">
|
||||||
isDisabled={!isEnabled}
|
<IAISlider
|
||||||
label={t('controlnet.weight')}
|
isDisabled={!isEnabled}
|
||||||
value={weight}
|
label={t('controlnet.weight')}
|
||||||
onChange={handleWeightChanged}
|
value={weight}
|
||||||
min={0}
|
onChange={handleWeightChanged}
|
||||||
max={2}
|
min={0}
|
||||||
step={0.01}
|
max={2}
|
||||||
withSliderMarks
|
step={0.01}
|
||||||
sliderMarks={[0, 1, 2]}
|
withSliderMarks
|
||||||
/>
|
sliderMarks={[0, 1, 2]}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import IAISwitch from 'common/components/IAISwitch';
|
|||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { combinatorialToggled } from '../store/dynamicPromptsSlice';
|
import { combinatorialToggled } from '../store/dynamicPromptsSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
stateSelector,
|
stateSelector,
|
||||||
@ -27,11 +28,13 @@ const ParamDynamicPromptsCombinatorial = () => {
|
|||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISwitch
|
<IAIInformationalPopover details="dynamicPromptsCombinatorial">
|
||||||
label={t('dynamicPrompts.combinatorial')}
|
<IAISwitch
|
||||||
isChecked={combinatorial}
|
label={t('dynamicPrompts.combinatorial')}
|
||||||
onChange={handleChange}
|
isChecked={combinatorial}
|
||||||
/>
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
loraWeightChanged,
|
loraWeightChanged,
|
||||||
loraWeightReset,
|
loraWeightReset,
|
||||||
} from '../store/loraSlice';
|
} from '../store/loraSlice';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
lora: LoRA;
|
lora: LoRA;
|
||||||
@ -35,30 +36,32 @@ const ParamLora = (props: Props) => {
|
|||||||
}, [dispatch, lora.id]);
|
}, [dispatch, lora.id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex sx={{ gap: 2.5, alignItems: 'flex-end' }}>
|
<IAIInformationalPopover details="lora">
|
||||||
<IAISlider
|
<Flex sx={{ gap: 2.5, alignItems: 'flex-end' }}>
|
||||||
label={lora.model_name}
|
<IAISlider
|
||||||
value={lora.weight}
|
label={lora.model_name}
|
||||||
onChange={handleChange}
|
value={lora.weight}
|
||||||
min={-1}
|
onChange={handleChange}
|
||||||
max={2}
|
min={-1}
|
||||||
step={0.01}
|
max={2}
|
||||||
withInput
|
step={0.01}
|
||||||
withReset
|
withInput
|
||||||
handleReset={handleReset}
|
withReset
|
||||||
withSliderMarks
|
handleReset={handleReset}
|
||||||
sliderMarks={[-1, 0, 1, 2]}
|
withSliderMarks
|
||||||
sliderNumberInputProps={{ min: -50, max: 50 }}
|
sliderMarks={[-1, 0, 1, 2]}
|
||||||
/>
|
sliderNumberInputProps={{ min: -50, max: 50 }}
|
||||||
<IAIIconButton
|
/>
|
||||||
size="sm"
|
<IAIIconButton
|
||||||
onClick={handleRemoveLora}
|
size="sm"
|
||||||
tooltip="Remove LoRA"
|
onClick={handleRemoveLora}
|
||||||
aria-label="Remove LoRA"
|
tooltip="Remove LoRA"
|
||||||
icon={<FaTrash />}
|
aria-label="Remove LoRA"
|
||||||
colorScheme="error"
|
icon={<FaTrash />}
|
||||||
/>
|
colorScheme="error"
|
||||||
</Flex>
|
/>
|
||||||
|
</Flex>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { RootState } from 'app/store/store';
|
import { RootState } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setClipSkip } from 'features/parameters/store/generationSlice';
|
import { setClipSkip } from 'features/parameters/store/generationSlice';
|
||||||
import { clipSkipMap } from 'features/parameters/types/constants';
|
import { clipSkipMap } from 'features/parameters/types/constants';
|
||||||
@ -42,19 +43,21 @@ export default function ParamClipSkip() {
|
|||||||
}, [model]);
|
}, [model]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<IAIInformationalPopover details="clipSkip">
|
||||||
label={t('parameters.clipSkip')}
|
<IAISlider
|
||||||
aria-label={t('parameters.clipSkip')}
|
label={t('parameters.clipSkip')}
|
||||||
min={0}
|
aria-label={t('parameters.clipSkip')}
|
||||||
max={max}
|
min={0}
|
||||||
step={1}
|
max={max}
|
||||||
value={clipSkip}
|
step={1}
|
||||||
onChange={handleClipSkipChange}
|
value={clipSkip}
|
||||||
withSliderMarks
|
onChange={handleClipSkipChange}
|
||||||
sliderMarks={sliderMarks}
|
withSliderMarks
|
||||||
withInput
|
sliderMarks={sliderMarks}
|
||||||
withReset
|
withInput
|
||||||
handleReset={handleClipSkipReset}
|
withReset
|
||||||
/>
|
handleReset={handleClipSkipReset}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import ParamAspectRatio, {
|
|||||||
} from '../../Core/ParamAspectRatio';
|
} from '../../Core/ParamAspectRatio';
|
||||||
import ParamBoundingBoxHeight from './ParamBoundingBoxHeight';
|
import ParamBoundingBoxHeight from './ParamBoundingBoxHeight';
|
||||||
import ParamBoundingBoxWidth from './ParamBoundingBoxWidth';
|
import ParamBoundingBoxWidth from './ParamBoundingBoxWidth';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
|
|
||||||
const sizeOptsSelector = createSelector(
|
const sizeOptsSelector = createSelector(
|
||||||
[generationSelector, canvasSelector],
|
[generationSelector, canvasSelector],
|
||||||
@ -93,18 +94,20 @@ export default function ParamBoundingBoxSize() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Flex alignItems="center" gap={2}>
|
<Flex alignItems="center" gap={2}>
|
||||||
<Text
|
<IAIInformationalPopover details="paramRatio">
|
||||||
sx={{
|
<Text
|
||||||
fontSize: 'sm',
|
sx={{
|
||||||
width: 'full',
|
fontSize: 'sm',
|
||||||
color: 'base.700',
|
width: 'full',
|
||||||
_dark: {
|
color: 'base.700',
|
||||||
color: 'base.300',
|
_dark: {
|
||||||
},
|
color: 'base.300',
|
||||||
}}
|
},
|
||||||
>
|
}}
|
||||||
{t('parameters.aspectRatio')}
|
>
|
||||||
</Text>
|
{t('parameters.aspectRatio')}
|
||||||
|
</Text>
|
||||||
|
</IAIInformationalPopover>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<ParamAspectRatio />
|
<ParamAspectRatio />
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { RootState } from 'app/store/store';
|
import type { RootState } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import { IAISelectDataType } from 'common/components/IAIMantineSearchableSelect';
|
import { IAISelectDataType } from 'common/components/IAIMantineSearchableSelect';
|
||||||
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
||||||
import { setCanvasCoherenceMode } from 'features/parameters/store/generationSlice';
|
import { setCanvasCoherenceMode } from 'features/parameters/store/generationSlice';
|
||||||
@ -30,12 +31,14 @@ const ParamCanvasCoherenceMode = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIMantineSelect
|
<IAIInformationalPopover details="compositingCoherenceMode">
|
||||||
label={t('parameters.coherenceMode')}
|
<IAIMantineSelect
|
||||||
data={coherenceModeSelectData}
|
label={t('parameters.coherenceMode')}
|
||||||
value={canvasCoherenceMode}
|
data={coherenceModeSelectData}
|
||||||
onChange={handleCoherenceModeChange}
|
value={canvasCoherenceMode}
|
||||||
/>
|
onChange={handleCoherenceModeChange}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { RootState } from 'app/store/store';
|
import type { RootState } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setCanvasCoherenceSteps } from 'features/parameters/store/generationSlice';
|
import { setCanvasCoherenceSteps } from 'features/parameters/store/generationSlice';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
@ -13,23 +14,25 @@ const ParamCanvasCoherenceSteps = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<IAIInformationalPopover details="compositingCoherenceSteps">
|
||||||
label={t('parameters.coherenceSteps')}
|
<IAISlider
|
||||||
min={1}
|
label={t('parameters.coherenceSteps')}
|
||||||
max={100}
|
min={1}
|
||||||
step={1}
|
max={100}
|
||||||
sliderNumberInputProps={{ max: 999 }}
|
step={1}
|
||||||
value={canvasCoherenceSteps}
|
sliderNumberInputProps={{ max: 999 }}
|
||||||
onChange={(v) => {
|
value={canvasCoherenceSteps}
|
||||||
dispatch(setCanvasCoherenceSteps(v));
|
onChange={(v) => {
|
||||||
}}
|
dispatch(setCanvasCoherenceSteps(v));
|
||||||
withInput
|
}}
|
||||||
withSliderMarks
|
withInput
|
||||||
withReset
|
withSliderMarks
|
||||||
handleReset={() => {
|
withReset
|
||||||
dispatch(setCanvasCoherenceSteps(20));
|
handleReset={() => {
|
||||||
}}
|
dispatch(setCanvasCoherenceSteps(20));
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { RootState } from 'app/store/store';
|
import type { RootState } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setCanvasCoherenceStrength } from 'features/parameters/store/generationSlice';
|
import { setCanvasCoherenceStrength } from 'features/parameters/store/generationSlice';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
@ -13,23 +14,25 @@ const ParamCanvasCoherenceStrength = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<IAIInformationalPopover details="compositingStrength">
|
||||||
label={t('parameters.coherenceStrength')}
|
<IAISlider
|
||||||
min={0}
|
label={t('parameters.coherenceStrength')}
|
||||||
max={1}
|
min={0}
|
||||||
step={0.01}
|
max={1}
|
||||||
sliderNumberInputProps={{ max: 999 }}
|
step={0.01}
|
||||||
value={canvasCoherenceStrength}
|
sliderNumberInputProps={{ max: 999 }}
|
||||||
onChange={(v) => {
|
value={canvasCoherenceStrength}
|
||||||
dispatch(setCanvasCoherenceStrength(v));
|
onChange={(v) => {
|
||||||
}}
|
dispatch(setCanvasCoherenceStrength(v));
|
||||||
withInput
|
}}
|
||||||
withSliderMarks
|
withInput
|
||||||
withReset
|
withSliderMarks
|
||||||
handleReset={() => {
|
withReset
|
||||||
dispatch(setCanvasCoherenceStrength(0.3));
|
handleReset={() => {
|
||||||
}}
|
dispatch(setCanvasCoherenceStrength(0.3));
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { RootState } from 'app/store/store';
|
import type { RootState } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setMaskBlur } from 'features/parameters/store/generationSlice';
|
import { setMaskBlur } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -12,21 +13,23 @@ export default function ParamMaskBlur() {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<IAIInformationalPopover details="compositingBlur">
|
||||||
label={t('parameters.maskBlur')}
|
<IAISlider
|
||||||
min={0}
|
label={t('parameters.maskBlur')}
|
||||||
max={64}
|
min={0}
|
||||||
sliderNumberInputProps={{ max: 512 }}
|
max={64}
|
||||||
value={maskBlur}
|
sliderNumberInputProps={{ max: 512 }}
|
||||||
onChange={(v) => {
|
value={maskBlur}
|
||||||
dispatch(setMaskBlur(v));
|
onChange={(v) => {
|
||||||
}}
|
dispatch(setMaskBlur(v));
|
||||||
withInput
|
}}
|
||||||
withSliderMarks
|
withInput
|
||||||
withReset
|
withSliderMarks
|
||||||
handleReset={() => {
|
withReset
|
||||||
dispatch(setMaskBlur(16));
|
handleReset={() => {
|
||||||
}}
|
dispatch(setMaskBlur(16));
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { SelectItem } from '@mantine/core';
|
|||||||
import { RootState } from 'app/store/store';
|
import { RootState } from 'app/store/store';
|
||||||
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
||||||
import { setMaskBlurMethod } from 'features/parameters/store/generationSlice';
|
import { setMaskBlurMethod } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -28,11 +29,13 @@ export default function ParamMaskBlurMethod() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIMantineSelect
|
<IAIInformationalPopover details="compositingBlurMethod">
|
||||||
value={maskBlurMethod}
|
<IAIMantineSelect
|
||||||
onChange={handleMaskBlurMethodChange}
|
value={maskBlurMethod}
|
||||||
label={t('parameters.maskBlurMethod')}
|
onChange={handleMaskBlurMethodChange}
|
||||||
data={maskBlurMethods}
|
label={t('parameters.maskBlurMethod')}
|
||||||
/>
|
data={maskBlurMethods}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,19 @@ const ParamCompositingSettingsCollapse = () => {
|
|||||||
return (
|
return (
|
||||||
<IAICollapse label={t('parameters.compositingSettingsHeader')}>
|
<IAICollapse label={t('parameters.compositingSettingsHeader')}>
|
||||||
<Flex sx={{ flexDirection: 'column', gap: 2 }}>
|
<Flex sx={{ flexDirection: 'column', gap: 2 }}>
|
||||||
<SubParametersWrapper label={t('parameters.coherencePassHeader')}>
|
<SubParametersWrapper
|
||||||
|
label={t('parameters.coherencePassHeader')}
|
||||||
|
headerInfoPopover="compositingCoherencePass"
|
||||||
|
>
|
||||||
<ParamCanvasCoherenceMode />
|
<ParamCanvasCoherenceMode />
|
||||||
<ParamCanvasCoherenceSteps />
|
<ParamCanvasCoherenceSteps />
|
||||||
<ParamCanvasCoherenceStrength />
|
<ParamCanvasCoherenceStrength />
|
||||||
</SubParametersWrapper>
|
</SubParametersWrapper>
|
||||||
<Divider />
|
<Divider />
|
||||||
<SubParametersWrapper label={t('parameters.maskAdjustmentsHeader')}>
|
<SubParametersWrapper
|
||||||
|
label={t('parameters.maskAdjustmentsHeader')}
|
||||||
|
headerInfoPopover="compositingMaskAdjustments"
|
||||||
|
>
|
||||||
<ParamMaskBlur />
|
<ParamMaskBlur />
|
||||||
<ParamMaskBlurMethod />
|
<ParamMaskBlurMethod />
|
||||||
</SubParametersWrapper>
|
</SubParametersWrapper>
|
||||||
|
@ -2,6 +2,7 @@ import { createSelector } from '@reduxjs/toolkit';
|
|||||||
import { stateSelector } from 'app/store/store';
|
import { stateSelector } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
||||||
import { setInfillMethod } from 'features/parameters/store/generationSlice';
|
import { setInfillMethod } from 'features/parameters/store/generationSlice';
|
||||||
|
|
||||||
@ -39,14 +40,16 @@ const ParamInfillMethod = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIMantineSelect
|
<IAIInformationalPopover details="infillMethod">
|
||||||
disabled={infill_methods?.length === 0}
|
<IAIMantineSelect
|
||||||
placeholder={isLoading ? 'Loading...' : undefined}
|
disabled={infill_methods?.length === 0}
|
||||||
label={t('parameters.infillMethod')}
|
placeholder={isLoading ? 'Loading...' : undefined}
|
||||||
value={infillMethod}
|
label={t('parameters.infillMethod')}
|
||||||
data={infill_methods ?? []}
|
value={infillMethod}
|
||||||
onChange={handleChange}
|
data={infill_methods ?? []}
|
||||||
/>
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAIMantineSearchableSelect from 'common/components/IAIMantineSearchableSelect';
|
import IAIMantineSearchableSelect from 'common/components/IAIMantineSearchableSelect';
|
||||||
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import { setBoundingBoxScaleMethod } from 'features/canvas/store/canvasSlice';
|
import { setBoundingBoxScaleMethod } from 'features/canvas/store/canvasSlice';
|
||||||
@ -35,12 +36,14 @@ const ParamScaleBeforeProcessing = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIMantineSearchableSelect
|
<IAIInformationalPopover details="scaleBeforeProcessing">
|
||||||
label={t('parameters.scaleBeforeProcessing')}
|
<IAIMantineSearchableSelect
|
||||||
data={BOUNDING_BOX_SCALES_DICT}
|
label={t('parameters.scaleBeforeProcessing')}
|
||||||
value={boundingBoxScale}
|
data={BOUNDING_BOX_SCALES_DICT}
|
||||||
onChange={handleChangeBoundingBoxScaleMethod}
|
value={boundingBoxScale}
|
||||||
/>
|
onChange={handleChangeBoundingBoxScaleMethod}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import { createSelector } from '@reduxjs/toolkit';
|
|||||||
import { stateSelector } from 'app/store/store';
|
import { stateSelector } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setCfgScale } from 'features/parameters/store/generationSlice';
|
import { setCfgScale } from 'features/parameters/store/generationSlice';
|
||||||
@ -53,31 +54,35 @@ const ParamCFGScale = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return shouldUseSliders ? (
|
return shouldUseSliders ? (
|
||||||
<IAISlider
|
<IAIInformationalPopover details="paramCFGScale">
|
||||||
label={t('parameters.cfgScale')}
|
<IAISlider
|
||||||
step={shift ? 0.1 : 0.5}
|
label={t('parameters.cfgScale')}
|
||||||
min={min}
|
step={shift ? 0.1 : 0.5}
|
||||||
max={sliderMax}
|
min={min}
|
||||||
onChange={handleChange}
|
max={sliderMax}
|
||||||
handleReset={handleReset}
|
onChange={handleChange}
|
||||||
value={cfgScale}
|
handleReset={handleReset}
|
||||||
sliderNumberInputProps={{ max: inputMax }}
|
value={cfgScale}
|
||||||
withInput
|
sliderNumberInputProps={{ max: inputMax }}
|
||||||
withReset
|
withInput
|
||||||
withSliderMarks
|
withReset
|
||||||
isInteger={false}
|
withSliderMarks
|
||||||
/>
|
isInteger={false}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
) : (
|
) : (
|
||||||
<IAINumberInput
|
<IAIInformationalPopover details="paramCFGScale">
|
||||||
label={t('parameters.cfgScale')}
|
<IAINumberInput
|
||||||
step={0.5}
|
label={t('parameters.cfgScale')}
|
||||||
min={min}
|
step={0.5}
|
||||||
max={inputMax}
|
min={min}
|
||||||
onChange={handleChange}
|
max={inputMax}
|
||||||
value={cfgScale}
|
onChange={handleChange}
|
||||||
isInteger={false}
|
value={cfgScale}
|
||||||
numberInputFieldProps={{ textAlign: 'center' }}
|
isInteger={false}
|
||||||
/>
|
numberInputFieldProps={{ textAlign: 'center' }}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import { createSelector } from '@reduxjs/toolkit';
|
|||||||
import { stateSelector } from 'app/store/store';
|
import { stateSelector } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setIterations } from 'features/parameters/store/generationSlice';
|
import { setIterations } from 'features/parameters/store/generationSlice';
|
||||||
@ -60,29 +61,33 @@ const ParamIterations = ({ asSlider }: Props) => {
|
|||||||
}, [dispatch, initial]);
|
}, [dispatch, initial]);
|
||||||
|
|
||||||
return asSlider || shouldUseSliders ? (
|
return asSlider || shouldUseSliders ? (
|
||||||
<IAISlider
|
<IAIInformationalPopover details="paramImages">
|
||||||
label={t('parameters.iterations')}
|
<IAISlider
|
||||||
step={step}
|
label={t('parameters.iterations')}
|
||||||
min={min}
|
step={step}
|
||||||
max={sliderMax}
|
min={min}
|
||||||
onChange={handleChange}
|
max={sliderMax}
|
||||||
handleReset={handleReset}
|
onChange={handleChange}
|
||||||
value={iterations}
|
handleReset={handleReset}
|
||||||
withInput
|
value={iterations}
|
||||||
withReset
|
withInput
|
||||||
withSliderMarks
|
withReset
|
||||||
sliderNumberInputProps={{ max: inputMax }}
|
withSliderMarks
|
||||||
/>
|
sliderNumberInputProps={{ max: inputMax }}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
) : (
|
) : (
|
||||||
<IAINumberInput
|
<IAIInformationalPopover details="paramImages">
|
||||||
label={t('parameters.iterations')}
|
<IAINumberInput
|
||||||
step={step}
|
label={t('parameters.iterations')}
|
||||||
min={min}
|
step={step}
|
||||||
max={inputMax}
|
min={min}
|
||||||
onChange={handleChange}
|
max={inputMax}
|
||||||
value={iterations}
|
onChange={handleChange}
|
||||||
numberInputFieldProps={{ textAlign: 'center' }}
|
value={iterations}
|
||||||
/>
|
numberInputFieldProps={{ textAlign: 'center' }}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import { ChangeEvent, KeyboardEvent, memo, useCallback, useRef } from 'react';
|
|||||||
import { flushSync } from 'react-dom';
|
import { flushSync } from 'react-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
|
|
||||||
const ParamNegativeConditioning = () => {
|
const ParamNegativeConditioning = () => {
|
||||||
const negativePrompt = useAppSelector(
|
const negativePrompt = useAppSelector(
|
||||||
@ -81,18 +82,20 @@ const ParamNegativeConditioning = () => {
|
|||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
onSelect={handleSelectEmbedding}
|
onSelect={handleSelectEmbedding}
|
||||||
>
|
>
|
||||||
<IAITextarea
|
<IAIInformationalPopover details="paramNegativeConditioning">
|
||||||
id="negativePrompt"
|
<IAITextarea
|
||||||
name="negativePrompt"
|
id="negativePrompt"
|
||||||
ref={promptRef}
|
name="negativePrompt"
|
||||||
value={negativePrompt}
|
ref={promptRef}
|
||||||
placeholder={t('parameters.negativePromptPlaceholder')}
|
value={negativePrompt}
|
||||||
onChange={handleChangePrompt}
|
placeholder={t('parameters.negativePromptPlaceholder')}
|
||||||
resize="vertical"
|
onChange={handleChangePrompt}
|
||||||
fontSize="sm"
|
resize="vertical"
|
||||||
minH={16}
|
fontSize="sm"
|
||||||
{...(isEmbeddingEnabled && { onKeyDown: handleKeyDown })}
|
minH={16}
|
||||||
/>
|
{...(isEmbeddingEnabled && { onKeyDown: handleKeyDown })}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
</ParamEmbeddingPopover>
|
</ParamEmbeddingPopover>
|
||||||
{!isOpen && isEmbeddingEnabled && (
|
{!isOpen && isEmbeddingEnabled && (
|
||||||
<Box
|
<Box
|
||||||
|
@ -12,6 +12,7 @@ import { flushSync } from 'react-dom';
|
|||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus';
|
||||||
|
import IAIInformationalPopover from '../../../../../common/components/IAIInformationalPopover';
|
||||||
|
|
||||||
const promptInputSelector = createSelector(
|
const promptInputSelector = createSelector(
|
||||||
[stateSelector],
|
[stateSelector],
|
||||||
@ -109,17 +110,19 @@ const ParamPositiveConditioning = () => {
|
|||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
onSelect={handleSelectEmbedding}
|
onSelect={handleSelectEmbedding}
|
||||||
>
|
>
|
||||||
<IAITextarea
|
<IAIInformationalPopover details="paramPositiveConditioning">
|
||||||
id="prompt"
|
<IAITextarea
|
||||||
name="prompt"
|
id="prompt"
|
||||||
ref={promptRef}
|
name="prompt"
|
||||||
value={prompt}
|
ref={promptRef}
|
||||||
placeholder={t('parameters.positivePromptPlaceholder')}
|
value={prompt}
|
||||||
onChange={handleChangePrompt}
|
placeholder={t('parameters.positivePromptPlaceholder')}
|
||||||
onKeyDown={handleKeyDown}
|
onChange={handleChangePrompt}
|
||||||
resize="vertical"
|
onKeyDown={handleKeyDown}
|
||||||
minH={32}
|
resize="vertical"
|
||||||
/>
|
minH={32}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
</ParamEmbeddingPopover>
|
</ParamEmbeddingPopover>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
{!isOpen && isEmbeddingEnabled && (
|
{!isOpen && isEmbeddingEnabled && (
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAIMantineSearchableSelect from 'common/components/IAIMantineSearchableSelect';
|
import IAIMantineSearchableSelect from 'common/components/IAIMantineSearchableSelect';
|
||||||
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||||
import { setScheduler } from 'features/parameters/store/generationSlice';
|
import { setScheduler } from 'features/parameters/store/generationSlice';
|
||||||
@ -51,12 +52,14 @@ const ParamScheduler = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIMantineSearchableSelect
|
<IAIInformationalPopover details="paramScheduler">
|
||||||
label={t('parameters.scheduler')}
|
<IAIMantineSearchableSelect
|
||||||
value={scheduler}
|
label={t('parameters.scheduler')}
|
||||||
data={data}
|
value={scheduler}
|
||||||
onChange={handleChange}
|
data={data}
|
||||||
/>
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import { activeTabNameSelector } from '../../../../ui/store/uiSelectors';
|
|||||||
import ParamAspectRatio, { mappedAspectRatios } from './ParamAspectRatio';
|
import ParamAspectRatio, { mappedAspectRatios } from './ParamAspectRatio';
|
||||||
import ParamHeight from './ParamHeight';
|
import ParamHeight from './ParamHeight';
|
||||||
import ParamWidth from './ParamWidth';
|
import ParamWidth from './ParamWidth';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
|
||||||
const sizeOptsSelector = createSelector(
|
const sizeOptsSelector = createSelector(
|
||||||
@ -83,18 +84,20 @@ export default function ParamSize() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Flex alignItems="center" gap={2}>
|
<Flex alignItems="center" gap={2}>
|
||||||
<Text
|
<IAIInformationalPopover details="paramRatio">
|
||||||
sx={{
|
<Text
|
||||||
fontSize: 'sm',
|
sx={{
|
||||||
width: 'full',
|
fontSize: 'sm',
|
||||||
color: 'base.700',
|
width: 'full',
|
||||||
_dark: {
|
color: 'base.700',
|
||||||
color: 'base.300',
|
_dark: {
|
||||||
},
|
color: 'base.300',
|
||||||
}}
|
},
|
||||||
>
|
}}
|
||||||
{t('parameters.aspectRatio')}
|
>
|
||||||
</Text>
|
{t('parameters.aspectRatio')}
|
||||||
|
</Text>
|
||||||
|
</IAIInformationalPopover>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<ParamAspectRatio />
|
<ParamAspectRatio />
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
|
@ -2,6 +2,7 @@ import { createSelector } from '@reduxjs/toolkit';
|
|||||||
import { stateSelector } from 'app/store/store';
|
import { stateSelector } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
|
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
@ -56,30 +57,34 @@ const ParamSteps = () => {
|
|||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
return shouldUseSliders ? (
|
return shouldUseSliders ? (
|
||||||
<IAISlider
|
<IAIInformationalPopover details="paramSteps">
|
||||||
label={t('parameters.steps')}
|
<IAISlider
|
||||||
min={min}
|
label={t('parameters.steps')}
|
||||||
max={sliderMax}
|
min={min}
|
||||||
step={step}
|
max={sliderMax}
|
||||||
onChange={handleChange}
|
step={step}
|
||||||
handleReset={handleReset}
|
onChange={handleChange}
|
||||||
value={steps}
|
handleReset={handleReset}
|
||||||
withInput
|
value={steps}
|
||||||
withReset
|
withInput
|
||||||
withSliderMarks
|
withReset
|
||||||
sliderNumberInputProps={{ max: inputMax }}
|
withSliderMarks
|
||||||
/>
|
sliderNumberInputProps={{ max: inputMax }}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
) : (
|
) : (
|
||||||
<IAINumberInput
|
<IAIInformationalPopover details="paramSteps">
|
||||||
label={t('parameters.steps')}
|
<IAINumberInput
|
||||||
min={min}
|
label={t('parameters.steps')}
|
||||||
max={inputMax}
|
min={min}
|
||||||
step={step}
|
max={inputMax}
|
||||||
onChange={handleChange}
|
step={step}
|
||||||
value={steps}
|
onChange={handleChange}
|
||||||
numberInputFieldProps={{ textAlign: 'center' }}
|
value={steps}
|
||||||
onBlur={handleBlur}
|
numberInputFieldProps={{ textAlign: 'center' }}
|
||||||
/>
|
onBlur={handleBlur}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import { setImg2imgStrength } from 'features/parameters/store/generationSlice';
|
|||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import SubParametersWrapper from '../SubParametersWrapper';
|
import SubParametersWrapper from '../SubParametersWrapper';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[stateSelector],
|
[stateSelector],
|
||||||
@ -46,20 +47,22 @@ const ImageToImageStrength = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SubParametersWrapper>
|
<SubParametersWrapper>
|
||||||
<IAISlider
|
<IAIInformationalPopover details="paramDenoisingStrength">
|
||||||
label={`${t('parameters.denoisingStrength')}`}
|
<IAISlider
|
||||||
step={step}
|
label={`${t('parameters.denoisingStrength')}`}
|
||||||
min={min}
|
step={step}
|
||||||
max={sliderMax}
|
min={min}
|
||||||
onChange={handleChange}
|
max={sliderMax}
|
||||||
handleReset={handleReset}
|
onChange={handleChange}
|
||||||
value={img2imgStrength}
|
handleReset={handleReset}
|
||||||
isInteger={false}
|
value={img2imgStrength}
|
||||||
withInput
|
isInteger={false}
|
||||||
withSliderMarks
|
withInput
|
||||||
withReset
|
withSliderMarks
|
||||||
sliderNumberInputProps={{ max: inputMax }}
|
withReset
|
||||||
/>
|
sliderNumberInputProps={{ max: inputMax }}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
</SubParametersWrapper>
|
</SubParametersWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@ import {
|
|||||||
useGetOnnxModelsQuery,
|
useGetOnnxModelsQuery,
|
||||||
} from 'services/api/endpoints/models';
|
} from 'services/api/endpoints/models';
|
||||||
import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
stateSelector,
|
stateSelector,
|
||||||
@ -118,24 +119,28 @@ const ParamMainModelSelect = () => {
|
|||||||
data={[]}
|
data={[]}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Flex w="100%" alignItems="center" gap={3}>
|
<IAIInformationalPopover details="paramModel" placement="bottom">
|
||||||
<IAIMantineSearchableSelect
|
<Flex w="100%" alignItems="center" gap={3}>
|
||||||
tooltip={selectedModel?.description}
|
<IAIMantineSearchableSelect
|
||||||
label={t('modelManager.model')}
|
tooltip={selectedModel?.description}
|
||||||
value={selectedModel?.id}
|
label={t('modelManager.model')}
|
||||||
placeholder={data.length > 0 ? 'Select a model' : 'No models available'}
|
value={selectedModel?.id}
|
||||||
data={data}
|
placeholder={
|
||||||
error={data.length === 0}
|
data.length > 0 ? 'Select a model' : 'No models available'
|
||||||
disabled={data.length === 0}
|
}
|
||||||
onChange={handleChangeModel}
|
data={data}
|
||||||
w="100%"
|
error={data.length === 0}
|
||||||
/>
|
disabled={data.length === 0}
|
||||||
{isSyncModelEnabled && (
|
onChange={handleChangeModel}
|
||||||
<Box mt={7}>
|
w="100%"
|
||||||
<SyncModelsButton iconMode />
|
/>
|
||||||
</Box>
|
{isSyncModelEnabled && (
|
||||||
)}
|
<Box mt={7}>
|
||||||
</Flex>
|
<SyncModelsButton iconMode />
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAISwitch from 'common/components/IAISwitch';
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
import { shouldUseCpuNoiseChanged } from 'features/parameters/store/generationSlice';
|
import { shouldUseCpuNoiseChanged } from 'features/parameters/store/generationSlice';
|
||||||
import { ChangeEvent, useCallback } from 'react';
|
import { ChangeEvent, useCallback } from 'react';
|
||||||
@ -19,10 +20,12 @@ export const ParamCpuNoiseToggle = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISwitch
|
<IAIInformationalPopover details="noiseUseCPU">
|
||||||
label={t('parameters.useCpuNoise')}
|
<IAISwitch
|
||||||
isChecked={shouldUseCpuNoise}
|
label={t('parameters.useCpuNoise')}
|
||||||
onChange={handleChange}
|
isChecked={shouldUseCpuNoise}
|
||||||
/>
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,14 +3,17 @@ import { memo } from 'react';
|
|||||||
import ParamSeed from './ParamSeed';
|
import ParamSeed from './ParamSeed';
|
||||||
import ParamSeedShuffle from './ParamSeedShuffle';
|
import ParamSeedShuffle from './ParamSeedShuffle';
|
||||||
import ParamSeedRandomize from './ParamSeedRandomize';
|
import ParamSeedRandomize from './ParamSeedRandomize';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
|
|
||||||
const ParamSeedFull = () => {
|
const ParamSeedFull = () => {
|
||||||
return (
|
return (
|
||||||
<Flex sx={{ gap: 3, alignItems: 'flex-end' }}>
|
<IAIInformationalPopover details="paramSeed">
|
||||||
<ParamSeed />
|
<Flex sx={{ gap: 3, alignItems: 'flex-end' }}>
|
||||||
<ParamSeedShuffle />
|
<ParamSeed />
|
||||||
<ParamSeedRandomize />
|
<ParamSeedShuffle />
|
||||||
</Flex>
|
<ParamSeedRandomize />
|
||||||
|
</Flex>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { Flex, Text } from '@chakra-ui/react';
|
import { Flex, Text } from '@chakra-ui/react';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import { ReactNode, memo } from 'react';
|
import { ReactNode, memo } from 'react';
|
||||||
|
|
||||||
type SubParameterWrapperProps = {
|
type SubParameterWrapperProps = {
|
||||||
children: ReactNode | ReactNode[];
|
children: ReactNode | ReactNode[];
|
||||||
label?: string;
|
label?: string;
|
||||||
|
headerInfoPopover?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SubParametersWrapper = (props: SubParameterWrapperProps) => (
|
const SubParametersWrapper = (props: SubParameterWrapperProps) => (
|
||||||
@ -21,7 +23,18 @@ const SubParametersWrapper = (props: SubParameterWrapperProps) => (
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{props.label && (
|
{props.headerInfoPopover && props.label && (
|
||||||
|
<IAIInformationalPopover details={props.headerInfoPopover}>
|
||||||
|
<Text
|
||||||
|
fontSize="sm"
|
||||||
|
fontWeight="bold"
|
||||||
|
sx={{ color: 'base.600', _dark: { color: 'base.300' } }}
|
||||||
|
>
|
||||||
|
{props.label}
|
||||||
|
</Text>
|
||||||
|
</IAIInformationalPopover>
|
||||||
|
)}
|
||||||
|
{!props.headerInfoPopover && props.label && (
|
||||||
<Text
|
<Text
|
||||||
fontSize="sm"
|
fontSize="sm"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
|
@ -15,6 +15,7 @@ import IAIMantineSelectItemWithTooltip from 'common/components/IAIMantineSelectI
|
|||||||
import { vaeSelected } from 'features/parameters/store/generationSlice';
|
import { vaeSelected } from 'features/parameters/store/generationSlice';
|
||||||
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
|
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
|
||||||
import { modelIdToVAEModelParam } from 'features/parameters/util/modelIdToVAEModelParam';
|
import { modelIdToVAEModelParam } from 'features/parameters/util/modelIdToVAEModelParam';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
stateSelector,
|
stateSelector,
|
||||||
@ -93,17 +94,19 @@ const ParamVAEModelSelect = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIMantineSearchableSelect
|
<IAIInformationalPopover details="paramVAE">
|
||||||
itemComponent={IAIMantineSelectItemWithTooltip}
|
<IAIMantineSearchableSelect
|
||||||
tooltip={selectedVaeModel?.description}
|
itemComponent={IAIMantineSelectItemWithTooltip}
|
||||||
label={t('modelManager.vae')}
|
tooltip={selectedVaeModel?.description}
|
||||||
value={selectedVaeModel?.id ?? 'default'}
|
label={t('modelManager.vae')}
|
||||||
placeholder="Default"
|
value={selectedVaeModel?.id ?? 'default'}
|
||||||
data={data}
|
placeholder="Default"
|
||||||
onChange={handleChangeModel}
|
data={data}
|
||||||
disabled={data.length === 0}
|
onChange={handleChangeModel}
|
||||||
clearable
|
disabled={data.length === 0}
|
||||||
/>
|
clearable
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import { createSelector } from '@reduxjs/toolkit';
|
|||||||
import { stateSelector } from 'app/store/store';
|
import { stateSelector } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
||||||
import { vaePrecisionChanged } from 'features/parameters/store/generationSlice';
|
import { vaePrecisionChanged } from 'features/parameters/store/generationSlice';
|
||||||
import { PrecisionParam } from 'features/parameters/types/parameterSchemas';
|
import { PrecisionParam } from 'features/parameters/types/parameterSchemas';
|
||||||
@ -34,12 +35,14 @@ const ParamVAEModelSelect = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIMantineSelect
|
<IAIInformationalPopover details="paramVAEPrecision">
|
||||||
label="VAE Precision"
|
<IAIMantineSelect
|
||||||
value={vaePrecision}
|
label="VAE Precision"
|
||||||
data={DATA}
|
value={vaePrecision}
|
||||||
onChange={handleChange}
|
data={DATA}
|
||||||
/>
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import SubParametersWrapper from 'features/parameters/components/Parameters/SubP
|
|||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { setSDXLImg2ImgDenoisingStrength } from '../store/sdxlSlice';
|
import { setSDXLImg2ImgDenoisingStrength } from '../store/sdxlSlice';
|
||||||
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[stateSelector],
|
[stateSelector],
|
||||||
@ -36,19 +37,21 @@ const ParamSDXLImg2ImgDenoisingStrength = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SubParametersWrapper>
|
<SubParametersWrapper>
|
||||||
<IAISlider
|
<IAIInformationalPopover details="paramDenoisingStrength">
|
||||||
label={t('sdxl.denoisingStrength')}
|
<IAISlider
|
||||||
step={0.01}
|
label={t('sdxl.denoisingStrength')}
|
||||||
min={0}
|
step={0.01}
|
||||||
max={1}
|
min={0}
|
||||||
onChange={handleChange}
|
max={1}
|
||||||
handleReset={handleReset}
|
onChange={handleChange}
|
||||||
value={sdxlImg2ImgDenoisingStrength}
|
handleReset={handleReset}
|
||||||
isInteger={false}
|
value={sdxlImg2ImgDenoisingStrength}
|
||||||
withInput
|
isInteger={false}
|
||||||
withSliderMarks
|
withInput
|
||||||
withReset
|
withSliderMarks
|
||||||
/>
|
withReset
|
||||||
|
/>
|
||||||
|
</IAIInformationalPopover>
|
||||||
</SubParametersWrapper>
|
</SubParametersWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -23,6 +23,7 @@ import {
|
|||||||
consoleLogLevelChanged,
|
consoleLogLevelChanged,
|
||||||
setEnableImageDebugging,
|
setEnableImageDebugging,
|
||||||
setShouldConfirmOnDelete,
|
setShouldConfirmOnDelete,
|
||||||
|
setShouldDisableInformationalPopovers,
|
||||||
shouldAntialiasProgressImageChanged,
|
shouldAntialiasProgressImageChanged,
|
||||||
shouldLogToConsoleChanged,
|
shouldLogToConsoleChanged,
|
||||||
shouldUseNSFWCheckerChanged,
|
shouldUseNSFWCheckerChanged,
|
||||||
@ -66,6 +67,7 @@ const selector = createSelector(
|
|||||||
shouldAntialiasProgressImage,
|
shouldAntialiasProgressImage,
|
||||||
shouldUseNSFWChecker,
|
shouldUseNSFWChecker,
|
||||||
shouldUseWatermarker,
|
shouldUseWatermarker,
|
||||||
|
shouldDisableInformationalPopovers,
|
||||||
} = system;
|
} = system;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -85,6 +87,7 @@ const selector = createSelector(
|
|||||||
shouldUseNSFWChecker,
|
shouldUseNSFWChecker,
|
||||||
shouldUseWatermarker,
|
shouldUseWatermarker,
|
||||||
shouldAutoChangeDimensions,
|
shouldAutoChangeDimensions,
|
||||||
|
shouldDisableInformationalPopovers,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -158,6 +161,7 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
|||||||
shouldUseNSFWChecker,
|
shouldUseNSFWChecker,
|
||||||
shouldUseWatermarker,
|
shouldUseWatermarker,
|
||||||
shouldAutoChangeDimensions,
|
shouldAutoChangeDimensions,
|
||||||
|
shouldDisableInformationalPopovers,
|
||||||
} = useAppSelector(selector);
|
} = useAppSelector(selector);
|
||||||
|
|
||||||
const handleClickResetWebUI = useCallback(() => {
|
const handleClickResetWebUI = useCallback(() => {
|
||||||
@ -307,6 +311,15 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
|||||||
onChange={handleLanguageChanged}
|
onChange={handleLanguageChanged}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<SettingSwitch
|
||||||
|
label="Disable informational popovers"
|
||||||
|
isChecked={shouldDisableInformationalPopovers}
|
||||||
|
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||||
|
dispatch(
|
||||||
|
setShouldDisableInformationalPopovers(e.target.checked)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
</StyledFlex>
|
</StyledFlex>
|
||||||
|
|
||||||
{shouldShowDeveloperSettings && (
|
{shouldShowDeveloperSettings && (
|
||||||
|
@ -35,6 +35,7 @@ export const initialSystemState: SystemState = {
|
|||||||
language: 'en',
|
language: 'en',
|
||||||
shouldUseNSFWChecker: false,
|
shouldUseNSFWChecker: false,
|
||||||
shouldUseWatermarker: false,
|
shouldUseWatermarker: false,
|
||||||
|
shouldDisableInformationalPopovers: false,
|
||||||
status: 'DISCONNECTED',
|
status: 'DISCONNECTED',
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,6 +76,12 @@ export const systemSlice = createSlice({
|
|||||||
shouldUseWatermarkerChanged(state, action: PayloadAction<boolean>) {
|
shouldUseWatermarkerChanged(state, action: PayloadAction<boolean>) {
|
||||||
state.shouldUseWatermarker = action.payload;
|
state.shouldUseWatermarker = action.payload;
|
||||||
},
|
},
|
||||||
|
setShouldDisableInformationalPopovers(
|
||||||
|
state,
|
||||||
|
action: PayloadAction<boolean>
|
||||||
|
) {
|
||||||
|
state.shouldDisableInformationalPopovers = action.payload;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
extraReducers(builder) {
|
extraReducers(builder) {
|
||||||
/**
|
/**
|
||||||
@ -234,6 +241,7 @@ export const {
|
|||||||
languageChanged,
|
languageChanged,
|
||||||
shouldUseNSFWCheckerChanged,
|
shouldUseNSFWCheckerChanged,
|
||||||
shouldUseWatermarkerChanged,
|
shouldUseWatermarkerChanged,
|
||||||
|
setShouldDisableInformationalPopovers,
|
||||||
} = systemSlice.actions;
|
} = systemSlice.actions;
|
||||||
|
|
||||||
export default systemSlice.reducer;
|
export default systemSlice.reducer;
|
||||||
|
@ -33,6 +33,7 @@ export interface SystemState {
|
|||||||
shouldUseNSFWChecker: boolean;
|
shouldUseNSFWChecker: boolean;
|
||||||
shouldUseWatermarker: boolean;
|
shouldUseWatermarker: boolean;
|
||||||
status: SystemStatus;
|
status: SystemStatus;
|
||||||
|
shouldDisableInformationalPopovers: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LANGUAGES = {
|
export const LANGUAGES = {
|
||||||
|
@ -80,6 +80,13 @@ const invokeAIOutline = defineStyle((props) => {
|
|||||||
return {
|
return {
|
||||||
border: '1px solid',
|
border: '1px solid',
|
||||||
borderColor: c === 'gray' ? borderColor : 'currentColor',
|
borderColor: c === 'gray' ? borderColor : 'currentColor',
|
||||||
|
_hover: {
|
||||||
|
bg: mode(`${c}.500`, `${c}.500`)(props),
|
||||||
|
color: mode('white', `base.50`)(props),
|
||||||
|
svg: {
|
||||||
|
fill: mode('white', `base.50`)(props),
|
||||||
|
},
|
||||||
|
},
|
||||||
'.chakra-button__group[data-attached][data-orientation=horizontal] > &:not(:last-of-type)':
|
'.chakra-button__group[data-attached][data-orientation=horizontal] > &:not(:last-of-type)':
|
||||||
{
|
{
|
||||||
marginEnd: '-1px',
|
marginEnd: '-1px',
|
||||||
|
@ -29,13 +29,34 @@ const invokeAIContent = defineStyle((props) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const informationalContent = defineStyle((props) => {
|
||||||
|
return {
|
||||||
|
[$arrowBg.variable]: mode('colors.base.100', 'colors.base.600')(props),
|
||||||
|
[$popperBg.variable]: mode('colors.base.100', 'colors.base.600')(props),
|
||||||
|
[$arrowShadowColor.variable]: mode(
|
||||||
|
'colors.base.400',
|
||||||
|
'colors.base.400'
|
||||||
|
)(props),
|
||||||
|
p: 0,
|
||||||
|
bg: mode('base.100', 'base.600')(props),
|
||||||
|
border: 'none',
|
||||||
|
shadow: 'dark-lg',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const invokeAI = definePartsStyle((props) => ({
|
const invokeAI = definePartsStyle((props) => ({
|
||||||
content: invokeAIContent(props),
|
content: invokeAIContent(props),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const informational = definePartsStyle((props) => ({
|
||||||
|
content: informationalContent(props),
|
||||||
|
body: { padding: 0 },
|
||||||
|
}));
|
||||||
|
|
||||||
export const popoverTheme = defineMultiStyleConfig({
|
export const popoverTheme = defineMultiStyleConfig({
|
||||||
variants: {
|
variants: {
|
||||||
invokeAI,
|
invokeAI,
|
||||||
|
informational,
|
||||||
},
|
},
|
||||||
defaultProps: {
|
defaultProps: {
|
||||||
variant: 'invokeAI',
|
variant: 'invokeAI',
|
||||||
|
Loading…
Reference in New Issue
Block a user