mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
feat(ui): remove SDXL style prompt from linear UI
This feature added a lot of unexpected complexity in graph building / metadata recall and is unintuitive user experience. 99% of the time, the style prompt should be exactly the main prompt. You can still use style prompts in workflows, but in an effort to reduce complexity in the linear UI, we are removing this rarely-used feature.
This commit is contained in:
@@ -181,15 +181,6 @@ const slice = createSlice({
|
||||
negativePromptChanged: (state, action: PayloadAction<ParameterNegativePrompt>) => {
|
||||
state.negativePrompt = action.payload;
|
||||
},
|
||||
positivePrompt2Changed: (state, action: PayloadAction<string>) => {
|
||||
state.positivePrompt2 = action.payload;
|
||||
},
|
||||
negativePrompt2Changed: (state, action: PayloadAction<string>) => {
|
||||
state.negativePrompt2 = action.payload;
|
||||
},
|
||||
shouldConcatPromptsChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldConcatPrompts = action.payload;
|
||||
},
|
||||
refinerModelChanged: (state, action: PayloadAction<ParameterSDXLRefinerModel | null>) => {
|
||||
const result = zParamsState.shape.refinerModel.safeParse(action.payload);
|
||||
if (!result.success) {
|
||||
@@ -425,9 +416,6 @@ export const {
|
||||
shouldUseCpuNoiseChanged,
|
||||
positivePromptChanged,
|
||||
negativePromptChanged,
|
||||
positivePrompt2Changed,
|
||||
negativePrompt2Changed,
|
||||
shouldConcatPromptsChanged,
|
||||
refinerModelChanged,
|
||||
setRefinerSteps,
|
||||
setRefinerCFGScale,
|
||||
@@ -518,9 +506,6 @@ export const selectModelSupportsNegativePrompt = createSelector(
|
||||
[selectIsFLUX, selectIsChatGPT4o, selectIsFluxKontext],
|
||||
(isFLUX, isChatGPT4o, isFluxKontext) => !isFLUX && !isChatGPT4o && !isFluxKontext
|
||||
);
|
||||
export const selectPositivePrompt2 = createParamsSelector((params) => params.positivePrompt2);
|
||||
export const selectNegativePrompt2 = createParamsSelector((params) => params.negativePrompt2);
|
||||
export const selectShouldConcatPrompts = createParamsSelector((params) => params.shouldConcatPrompts);
|
||||
export const selectScheduler = createParamsSelector((params) => params.scheduler);
|
||||
export const selectSeamlessXAxis = createParamsSelector((params) => params.seamlessXAxis);
|
||||
export const selectSeamlessYAxis = createParamsSelector((params) => params.seamlessYAxis);
|
||||
|
||||
@@ -14,9 +14,7 @@ import {
|
||||
zParameterMaskBlurMethod,
|
||||
zParameterModel,
|
||||
zParameterNegativePrompt,
|
||||
zParameterNegativeStylePromptSDXL,
|
||||
zParameterPositivePrompt,
|
||||
zParameterPositiveStylePromptSDXL,
|
||||
zParameterPrecision,
|
||||
zParameterScheduler,
|
||||
zParameterSDXLRefinerModel,
|
||||
@@ -534,9 +532,6 @@ export const zParamsState = z.object({
|
||||
shouldUseCpuNoise: z.boolean(),
|
||||
positivePrompt: zParameterPositivePrompt,
|
||||
negativePrompt: zParameterNegativePrompt,
|
||||
positivePrompt2: zParameterPositiveStylePromptSDXL,
|
||||
negativePrompt2: zParameterNegativeStylePromptSDXL,
|
||||
shouldConcatPrompts: z.boolean(),
|
||||
refinerModel: zParameterSDXLRefinerModel.nullable(),
|
||||
refinerSteps: z.number(),
|
||||
refinerCFGScale: z.number(),
|
||||
@@ -584,9 +579,6 @@ export const getInitialParamsState = (): ParamsState => ({
|
||||
shouldUseCpuNoise: true,
|
||||
positivePrompt: '',
|
||||
negativePrompt: null,
|
||||
positivePrompt2: '',
|
||||
negativePrompt2: '',
|
||||
shouldConcatPrompts: true,
|
||||
refinerModel: null,
|
||||
refinerSteps: 20,
|
||||
refinerCFGScale: 7.5,
|
||||
|
||||
@@ -33,8 +33,6 @@ const ImageMetadataActions = (props: Props) => {
|
||||
<UnrecallableMetadataDatum metadata={metadata} handler={MetadataHandlers.GenerationMode} />
|
||||
<SingleMetadataDatum metadata={metadata} handler={MetadataHandlers.PositivePrompt} />
|
||||
<SingleMetadataDatum metadata={metadata} handler={MetadataHandlers.NegativePrompt} />
|
||||
<SingleMetadataDatum metadata={metadata} handler={MetadataHandlers.PositiveStylePrompt} />
|
||||
<SingleMetadataDatum metadata={metadata} handler={MetadataHandlers.NegativeStylePrompt} />
|
||||
<SingleMetadataDatum metadata={metadata} handler={MetadataHandlers.MainModel} />
|
||||
<SingleMetadataDatum metadata={metadata} handler={MetadataHandlers.VAEModel} />
|
||||
<SingleMetadataDatum metadata={metadata} handler={MetadataHandlers.Width} />
|
||||
|
||||
@@ -22,12 +22,7 @@ export const useRecallPrompts = (imageDTO: ImageDTO) => {
|
||||
const parse = async () => {
|
||||
try {
|
||||
const result = await MetadataUtils.hasMetadataByHandlers({
|
||||
handlers: [
|
||||
MetadataHandlers.PositivePrompt,
|
||||
MetadataHandlers.NegativePrompt,
|
||||
MetadataHandlers.PositiveStylePrompt,
|
||||
MetadataHandlers.NegativeStylePrompt,
|
||||
],
|
||||
handlers: [MetadataHandlers.PositivePrompt, MetadataHandlers.NegativePrompt],
|
||||
metadata,
|
||||
store,
|
||||
require: 'some',
|
||||
|
||||
@@ -9,9 +9,7 @@ import { bboxHeightChanged, bboxWidthChanged, canvasMetadataRecalled } from 'fea
|
||||
import { loraAllDeleted, loraRecalled } from 'features/controlLayers/store/lorasSlice';
|
||||
import {
|
||||
heightChanged,
|
||||
negativePrompt2Changed,
|
||||
negativePromptChanged,
|
||||
positivePrompt2Changed,
|
||||
positivePromptChanged,
|
||||
refinerModelChanged,
|
||||
selectBase,
|
||||
@@ -30,7 +28,6 @@ import {
|
||||
setSeamlessYAxis,
|
||||
setSeed,
|
||||
setSteps,
|
||||
shouldConcatPromptsChanged,
|
||||
vaeSelected,
|
||||
widthChanged,
|
||||
} from 'features/controlLayers/store/paramsSlice';
|
||||
@@ -49,7 +46,6 @@ import type {
|
||||
ParameterModel,
|
||||
ParameterNegativePrompt,
|
||||
ParameterPositivePrompt,
|
||||
ParameterPositiveStylePromptSDXL,
|
||||
ParameterScheduler,
|
||||
ParameterSDXLRefinerModel,
|
||||
ParameterSDXLRefinerNegativeAestheticScore,
|
||||
@@ -70,9 +66,7 @@ import {
|
||||
zParameterGuidance,
|
||||
zParameterImageDimension,
|
||||
zParameterNegativePrompt,
|
||||
zParameterNegativeStylePromptSDXL,
|
||||
zParameterPositivePrompt,
|
||||
zParameterPositiveStylePromptSDXL,
|
||||
zParameterScheduler,
|
||||
zParameterSDXLRefinerNegativeAestheticScore,
|
||||
zParameterSDXLRefinerPositiveAestheticScore,
|
||||
@@ -289,46 +283,6 @@ const NegativePrompt: SingleMetadataHandler<ParameterNegativePrompt> = {
|
||||
};
|
||||
//#endregion Negative Prompt
|
||||
|
||||
//#region SDXL Positive Style Prompt
|
||||
const PositiveStylePrompt: SingleMetadataHandler<ParameterPositiveStylePromptSDXL> = {
|
||||
[SingleMetadataKey]: true,
|
||||
type: 'PositiveStylePrompt',
|
||||
parse: (metadata, _store) => {
|
||||
const raw = getProperty(metadata, 'positive_style_prompt');
|
||||
const parsed = zParameterPositiveStylePromptSDXL.parse(raw);
|
||||
return Promise.resolve(parsed);
|
||||
},
|
||||
recall: (value, store) => {
|
||||
store.dispatch(positivePrompt2Changed(value));
|
||||
},
|
||||
i18nKey: 'sdxl.posStylePrompt',
|
||||
LabelComponent: MetadataLabel,
|
||||
ValueComponent: ({ value }: SingleMetadataValueProps<ParameterPositiveStylePromptSDXL>) => (
|
||||
<MetadataPrimitiveValue value={value} />
|
||||
),
|
||||
};
|
||||
//#endregion SDXL Positive Style Prompt
|
||||
|
||||
//#region SDXL Negative Style Prompt
|
||||
const NegativeStylePrompt: SingleMetadataHandler<ParameterPositiveStylePromptSDXL> = {
|
||||
[SingleMetadataKey]: true,
|
||||
type: 'NegativeStylePrompt',
|
||||
parse: (metadata, _store) => {
|
||||
const raw = getProperty(metadata, 'negative_style_prompt');
|
||||
const parsed = zParameterNegativeStylePromptSDXL.parse(raw);
|
||||
return Promise.resolve(parsed);
|
||||
},
|
||||
recall: (value, store) => {
|
||||
store.dispatch(negativePrompt2Changed(value));
|
||||
},
|
||||
i18nKey: 'sdxl.negStylePrompt',
|
||||
LabelComponent: MetadataLabel,
|
||||
ValueComponent: ({ value }: SingleMetadataValueProps<ParameterPositiveStylePromptSDXL>) => (
|
||||
<MetadataPrimitiveValue value={value} />
|
||||
),
|
||||
};
|
||||
//#endregion SDXL Negative Style Prompt
|
||||
|
||||
//#region CFG Scale
|
||||
const CFGScale: SingleMetadataHandler<ParameterCFGScale> = {
|
||||
[SingleMetadataKey]: true,
|
||||
@@ -927,8 +881,6 @@ export const MetadataHandlers = {
|
||||
GenerationMode,
|
||||
PositivePrompt,
|
||||
NegativePrompt,
|
||||
PositiveStylePrompt,
|
||||
NegativeStylePrompt,
|
||||
CFGScale,
|
||||
CFGRescaleMultiplier,
|
||||
Guidance,
|
||||
@@ -1052,26 +1004,6 @@ const recallByHandlers = async (arg: {
|
||||
}
|
||||
}
|
||||
|
||||
// We may need to update the prompt concat flag based on the recalled prompts
|
||||
const positivePrompt = recalled.get(MetadataHandlers.PositivePrompt);
|
||||
const negativePrompt = recalled.get(MetadataHandlers.NegativePrompt);
|
||||
const positiveStylePrompt = recalled.get(MetadataHandlers.PositiveStylePrompt);
|
||||
const negativeStylePrompt = recalled.get(MetadataHandlers.NegativeStylePrompt);
|
||||
|
||||
// The values will be undefined if the handler was not recalled
|
||||
if (
|
||||
positivePrompt !== undefined ||
|
||||
negativePrompt !== undefined ||
|
||||
positiveStylePrompt !== undefined ||
|
||||
negativeStylePrompt !== undefined
|
||||
) {
|
||||
const concat =
|
||||
(Boolean(positiveStylePrompt) && positiveStylePrompt === positivePrompt) ||
|
||||
(Boolean(negativeStylePrompt) && negativeStylePrompt === negativePrompt);
|
||||
|
||||
store.dispatch(shouldConcatPromptsChanged(concat));
|
||||
}
|
||||
|
||||
if (!silent) {
|
||||
if (recalled.size > 0) {
|
||||
toast({
|
||||
@@ -1094,12 +1026,7 @@ const recallByHandlers = async (arg: {
|
||||
const recallPrompts = async (metadata: unknown, store: AppStore) => {
|
||||
const recalled = await recallByHandlers({
|
||||
metadata,
|
||||
handlers: [
|
||||
MetadataHandlers.PositivePrompt,
|
||||
MetadataHandlers.NegativePrompt,
|
||||
MetadataHandlers.PositiveStylePrompt,
|
||||
MetadataHandlers.NegativeStylePrompt,
|
||||
],
|
||||
handlers: [MetadataHandlers.PositivePrompt, MetadataHandlers.NegativePrompt],
|
||||
store,
|
||||
silent: true,
|
||||
});
|
||||
|
||||
@@ -115,7 +115,7 @@ export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise
|
||||
type: 'sdxl_compel_prompt',
|
||||
id: getPrefixedId('neg_cond'),
|
||||
prompt: prompts.negative,
|
||||
style: prompts.negativeStyle,
|
||||
style: prompts.negative,
|
||||
});
|
||||
modelLoader = g.addNode({
|
||||
type: 'sdxl_model_loader',
|
||||
@@ -130,23 +130,14 @@ export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise
|
||||
g.addEdge(modelLoader, 'unet', tiledMultidiffusion, 'unet');
|
||||
|
||||
g.addEdge(positivePrompt, 'value', posCond, 'prompt');
|
||||
g.addEdge(positivePrompt, 'value', posCond, 'style');
|
||||
|
||||
addSDXLLoRAs(state, g, tiledMultidiffusion, modelLoader, null, posCond, negCond);
|
||||
|
||||
g.upsertMetadata({
|
||||
negative_prompt: prompts.negative,
|
||||
negative_style_prompt: prompts.negativeStyle,
|
||||
});
|
||||
|
||||
g.addEdgeToMetadata(positivePrompt, 'value', 'positive_prompt');
|
||||
|
||||
if (prompts.useMainPromptsForStyle) {
|
||||
g.addEdge(positivePrompt, 'value', posCond, 'style');
|
||||
g.addEdgeToMetadata(positivePrompt, 'value', 'positive_style_prompt');
|
||||
} else {
|
||||
posCond.style = prompts.positiveStyle;
|
||||
g.upsertMetadata({ positive_style_prompt: prompts.positiveStyle });
|
||||
}
|
||||
} else {
|
||||
const prompts = selectPresetModifiedPrompts(state);
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ export const buildSDXLGraph = async (arg: GraphBuilderArg): Promise<GraphBuilder
|
||||
type: 'sdxl_compel_prompt',
|
||||
id: getPrefixedId('neg_cond'),
|
||||
prompt: prompts.negative,
|
||||
style: prompts.useMainPromptsForStyle ? prompts.negative : prompts.negativeStyle,
|
||||
style: prompts.negative,
|
||||
});
|
||||
const negCondCollect = g.addNode({
|
||||
type: 'collect',
|
||||
@@ -123,6 +123,8 @@ export const buildSDXLGraph = async (arg: GraphBuilderArg): Promise<GraphBuilder
|
||||
g.addEdge(modelLoader, 'clip2', negCond, 'clip2');
|
||||
|
||||
g.addEdge(positivePrompt, 'value', posCond, 'prompt');
|
||||
g.addEdge(positivePrompt, 'value', posCond, 'style');
|
||||
|
||||
g.addEdge(posCond, 'conditioning', posCondCollect, 'item');
|
||||
g.addEdge(posCondCollect, 'collection', denoise, 'positive_conditioning');
|
||||
|
||||
@@ -141,19 +143,12 @@ export const buildSDXLGraph = async (arg: GraphBuilderArg): Promise<GraphBuilder
|
||||
rand_device: shouldUseCpuNoise ? 'cpu' : 'cuda',
|
||||
scheduler,
|
||||
negative_prompt: prompts.negative,
|
||||
negative_style_prompt: prompts.useMainPromptsForStyle ? prompts.negative : prompts.negativeStyle,
|
||||
vae: vae ?? undefined,
|
||||
});
|
||||
g.addEdgeToMetadata(seed, 'value', 'seed');
|
||||
g.addEdgeToMetadata(positivePrompt, 'value', 'positive_prompt');
|
||||
|
||||
if (prompts.useMainPromptsForStyle) {
|
||||
g.addEdge(positivePrompt, 'value', posCond, 'style');
|
||||
g.addEdgeToMetadata(positivePrompt, 'value', 'positive_style_prompt');
|
||||
} else {
|
||||
posCond.style = prompts.positiveStyle;
|
||||
g.upsertMetadata({ positive_style_prompt: prompts.positiveStyle });
|
||||
}
|
||||
g.addEdgeToMetadata(positivePrompt, 'value', 'positive_style_prompt');
|
||||
|
||||
const seamless = addSeamless(state, g, denoise, modelLoader, vaeLoader);
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ export const selectPresetModifiedPrompts = createSelector(
|
||||
selectListStylePresetsRequestState,
|
||||
(params, stylePresetSlice, listStylePresetsRequestState) => {
|
||||
const negativePrompt = params.negativePrompt ?? '';
|
||||
const { positivePrompt, positivePrompt2, negativePrompt2, shouldConcatPrompts } = params;
|
||||
const { positivePrompt } = params;
|
||||
const { activeStylePresetId } = stylePresetSlice;
|
||||
|
||||
if (activeStylePresetId) {
|
||||
@@ -107,9 +107,6 @@ export const selectPresetModifiedPrompts = createSelector(
|
||||
return {
|
||||
positive: presetModifiedPositivePrompt,
|
||||
negative: presetModifiedNegativePrompt,
|
||||
positiveStyle: positivePrompt2,
|
||||
negativeStyle: negativePrompt2,
|
||||
useMainPromptsForStyle: shouldConcatPrompts,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -117,9 +114,6 @@ export const selectPresetModifiedPrompts = createSelector(
|
||||
return {
|
||||
positive: positivePrompt,
|
||||
negative: negativePrompt,
|
||||
positiveStyle: positivePrompt2,
|
||||
negativeStyle: negativePrompt2,
|
||||
useMainPromptsForStyle: shouldConcatPrompts,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { usePersistedTextAreaSize } from 'common/hooks/usePersistedTextareaSize';
|
||||
import {
|
||||
positivePromptChanged,
|
||||
selectBase,
|
||||
selectModelSupportsNegativePrompt,
|
||||
selectPositivePrompt,
|
||||
} from 'features/controlLayers/store/paramsSlice';
|
||||
@@ -21,7 +20,6 @@ import { PromptExpansionOverlay } from 'features/prompt/PromptExpansion/PromptEx
|
||||
import { promptExpansionApi } from 'features/prompt/PromptExpansion/state';
|
||||
import { PromptPopover } from 'features/prompt/PromptPopover';
|
||||
import { usePrompt } from 'features/prompt/usePrompt';
|
||||
import { SDXLConcatButton } from 'features/sdxl/components/SDXLPrompts/SDXLConcatButton';
|
||||
import {
|
||||
selectStylePresetActivePresetId,
|
||||
selectStylePresetViewMode,
|
||||
@@ -42,7 +40,6 @@ const persistOptions: Parameters<typeof usePersistedTextAreaSize>[2] = {
|
||||
export const ParamPositivePrompt = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const prompt = useAppSelector(selectPositivePrompt);
|
||||
const baseModel = useAppSelector(selectBase);
|
||||
const viewMode = useAppSelector(selectStylePresetViewMode);
|
||||
const activeStylePresetId = useAppSelector(selectStylePresetActivePresetId);
|
||||
const modelSupportsNegativePrompt = useAppSelector(selectModelSupportsNegativePrompt);
|
||||
@@ -118,7 +115,6 @@ export const ParamPositivePrompt = memo(() => {
|
||||
<PromptOverlayButtonWrapper>
|
||||
<Flex flexDir="column" gap={2} justifyContent="flex-start" alignItems="center">
|
||||
<AddPromptTriggerButton isOpen={isOpen} onOpen={onOpen} />
|
||||
{baseModel === 'sdxl' && <SDXLConcatButton />}
|
||||
<ShowDynamicPromptsPreviewButton />
|
||||
{modelSupportsNegativePrompt && <NegativePromptToggleButton />}
|
||||
</Flex>
|
||||
|
||||
@@ -1,33 +1,18 @@
|
||||
import { Flex } from '@invoke-ai/ui-library';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { RefImageList } from 'features/controlLayers/components/RefImage/RefImageList';
|
||||
import {
|
||||
createParamsSelector,
|
||||
selectHasNegativePrompt,
|
||||
selectModelSupportsNegativePrompt,
|
||||
} from 'features/controlLayers/store/paramsSlice';
|
||||
import { selectHasNegativePrompt, selectModelSupportsNegativePrompt } from 'features/controlLayers/store/paramsSlice';
|
||||
import { ParamNegativePrompt } from 'features/parameters/components/Core/ParamNegativePrompt';
|
||||
import { ParamPositivePrompt } from 'features/parameters/components/Core/ParamPositivePrompt';
|
||||
import { ParamSDXLNegativeStylePrompt } from 'features/sdxl/components/SDXLPrompts/ParamSDXLNegativeStylePrompt';
|
||||
import { ParamSDXLPositiveStylePrompt } from 'features/sdxl/components/SDXLPrompts/ParamSDXLPositiveStylePrompt';
|
||||
import { memo } from 'react';
|
||||
|
||||
const selectWithStylePrompts = createParamsSelector((params) => {
|
||||
const isSDXL = params.model?.base === 'sdxl';
|
||||
const shouldConcatPrompts = params.shouldConcatPrompts;
|
||||
return isSDXL && !shouldConcatPrompts;
|
||||
});
|
||||
|
||||
export const Prompts = memo(() => {
|
||||
const withStylePrompts = useAppSelector(selectWithStylePrompts);
|
||||
const modelSupportsNegativePrompt = useAppSelector(selectModelSupportsNegativePrompt);
|
||||
const hasNegativePrompt = useAppSelector(selectHasNegativePrompt);
|
||||
return (
|
||||
<Flex flexDir="column" gap={2}>
|
||||
<ParamPositivePrompt />
|
||||
{withStylePrompts && <ParamSDXLPositiveStylePrompt />}
|
||||
{modelSupportsNegativePrompt && hasNegativePrompt && <ParamNegativePrompt />}
|
||||
{withStylePrompts && <ParamSDXLNegativeStylePrompt />}
|
||||
<RefImageList />
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -1,32 +1,17 @@
|
||||
import { Flex } from '@invoke-ai/ui-library';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import {
|
||||
createParamsSelector,
|
||||
selectHasNegativePrompt,
|
||||
selectModelSupportsNegativePrompt,
|
||||
} from 'features/controlLayers/store/paramsSlice';
|
||||
import { selectHasNegativePrompt, selectModelSupportsNegativePrompt } from 'features/controlLayers/store/paramsSlice';
|
||||
import { ParamNegativePrompt } from 'features/parameters/components/Core/ParamNegativePrompt';
|
||||
import { ParamPositivePrompt } from 'features/parameters/components/Core/ParamPositivePrompt';
|
||||
import { ParamSDXLNegativeStylePrompt } from 'features/sdxl/components/SDXLPrompts/ParamSDXLNegativeStylePrompt';
|
||||
import { ParamSDXLPositiveStylePrompt } from 'features/sdxl/components/SDXLPrompts/ParamSDXLPositiveStylePrompt';
|
||||
import { memo } from 'react';
|
||||
|
||||
const selectWithStylePrompts = createParamsSelector((params) => {
|
||||
const isSDXL = params.model?.base === 'sdxl';
|
||||
const shouldConcatPrompts = params.shouldConcatPrompts;
|
||||
return isSDXL && !shouldConcatPrompts;
|
||||
});
|
||||
|
||||
export const UpscalePrompts = memo(() => {
|
||||
const withStylePrompts = useAppSelector(selectWithStylePrompts);
|
||||
const modelSupportsNegativePrompt = useAppSelector(selectModelSupportsNegativePrompt);
|
||||
const hasNegativePrompt = useAppSelector(selectHasNegativePrompt);
|
||||
return (
|
||||
<Flex flexDir="column" gap={2}>
|
||||
<ParamPositivePrompt />
|
||||
{withStylePrompts && <ParamSDXLPositiveStylePrompt />}
|
||||
{modelSupportsNegativePrompt && hasNegativePrompt && <ParamNegativePrompt />}
|
||||
{withStylePrompts && <ParamSDXLNegativeStylePrompt />}
|
||||
</Flex>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -33,16 +33,6 @@ export const [zParameterNegativePrompt, isParameterNegativePrompt] = buildParame
|
||||
export type ParameterNegativePrompt = z.infer<typeof zParameterNegativePrompt>;
|
||||
// #endregion
|
||||
|
||||
// #region Positive style prompt (SDXL)
|
||||
export const [zParameterPositiveStylePromptSDXL, isParameterPositiveStylePromptSDXL] = buildParameter(z.string());
|
||||
export type ParameterPositiveStylePromptSDXL = z.infer<typeof zParameterPositiveStylePromptSDXL>;
|
||||
// #endregion
|
||||
|
||||
// #region Positive style prompt (SDXL)
|
||||
export const [zParameterNegativeStylePromptSDXL, isParameterNegativeStylePromptSDXL] = buildParameter(z.string());
|
||||
export type ParameterNegativeStylePromptSDXL = z.infer<typeof zParameterNegativeStylePromptSDXL>;
|
||||
// #endregion
|
||||
|
||||
// #region Steps
|
||||
export const [zParameterSteps, isParameterSteps] = buildParameter(z.number().int().min(1));
|
||||
export type ParameterSteps = z.infer<typeof zParameterSteps>;
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
import { Box, Textarea } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { usePersistedTextAreaSize } from 'common/hooks/usePersistedTextareaSize';
|
||||
import { negativePrompt2Changed, selectNegativePrompt2 } from 'features/controlLayers/store/paramsSlice';
|
||||
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
|
||||
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
||||
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
||||
import { PromptPopover } from 'features/prompt/PromptPopover';
|
||||
import { usePrompt } from 'features/prompt/usePrompt';
|
||||
import { memo, useCallback, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const persistOptions: Parameters<typeof usePersistedTextAreaSize>[2] = {
|
||||
trackWidth: false,
|
||||
trackHeight: true,
|
||||
};
|
||||
|
||||
export const ParamSDXLNegativeStylePrompt = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const prompt = useAppSelector(selectNegativePrompt2);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
usePersistedTextAreaSize('negative_style_prompt', textareaRef, persistOptions);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const handleChange = useCallback(
|
||||
(v: string) => {
|
||||
dispatch(negativePrompt2Changed(v));
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
const { onChange, isOpen, onClose, onOpen, onSelect, onKeyDown } = usePrompt({
|
||||
prompt,
|
||||
textareaRef: textareaRef,
|
||||
onChange: handleChange,
|
||||
});
|
||||
|
||||
return (
|
||||
<PromptPopover isOpen={isOpen} onClose={onClose} onSelect={onSelect} width={textareaRef.current?.clientWidth}>
|
||||
<Box pos="relative">
|
||||
<Textarea
|
||||
className="negative-style-prompt-textarea"
|
||||
name="prompt"
|
||||
ref={textareaRef}
|
||||
value={prompt}
|
||||
onChange={onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
fontSize="sm"
|
||||
variant="darkFilled"
|
||||
minH={24}
|
||||
borderTopWidth={24} // This prevents the prompt from being hidden behind the header
|
||||
paddingInlineEnd={10}
|
||||
paddingInlineStart={3}
|
||||
paddingTop={0}
|
||||
paddingBottom={3}
|
||||
/>
|
||||
<PromptOverlayButtonWrapper>
|
||||
<AddPromptTriggerButton isOpen={isOpen} onOpen={onOpen} />
|
||||
</PromptOverlayButtonWrapper>
|
||||
<PromptLabel label={t('sdxl.negStylePrompt')} />
|
||||
</Box>
|
||||
</PromptPopover>
|
||||
);
|
||||
});
|
||||
|
||||
ParamSDXLNegativeStylePrompt.displayName = 'ParamSDXLNegativeStylePrompt';
|
||||
@@ -1,65 +0,0 @@
|
||||
import { Box, Textarea } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { usePersistedTextAreaSize } from 'common/hooks/usePersistedTextareaSize';
|
||||
import { positivePrompt2Changed, selectPositivePrompt2 } from 'features/controlLayers/store/paramsSlice';
|
||||
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
|
||||
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
||||
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
||||
import { PromptPopover } from 'features/prompt/PromptPopover';
|
||||
import { usePrompt } from 'features/prompt/usePrompt';
|
||||
import { memo, useCallback, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const persistOptions: Parameters<typeof usePersistedTextAreaSize>[2] = {
|
||||
trackWidth: false,
|
||||
trackHeight: true,
|
||||
};
|
||||
|
||||
export const ParamSDXLPositiveStylePrompt = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const prompt = useAppSelector(selectPositivePrompt2);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
usePersistedTextAreaSize('positive_style_prompt', textareaRef, persistOptions);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const handleChange = useCallback(
|
||||
(v: string) => {
|
||||
dispatch(positivePrompt2Changed(v));
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
const { onChange, isOpen, onClose, onOpen, onSelect, onKeyDown } = usePrompt({
|
||||
prompt,
|
||||
textareaRef: textareaRef,
|
||||
onChange: handleChange,
|
||||
});
|
||||
|
||||
return (
|
||||
<PromptPopover isOpen={isOpen} onClose={onClose} onSelect={onSelect} width={textareaRef.current?.clientWidth}>
|
||||
<Box pos="relative">
|
||||
<Textarea
|
||||
className="positive-style-prompt-textarea"
|
||||
name="prompt"
|
||||
ref={textareaRef}
|
||||
value={prompt}
|
||||
onChange={onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
fontSize="sm"
|
||||
variant="darkFilled"
|
||||
minH={24}
|
||||
borderTopWidth={24} // This prevents the prompt from being hidden behind the header
|
||||
paddingInlineEnd={10}
|
||||
paddingInlineStart={3}
|
||||
paddingTop={0}
|
||||
paddingBottom={3}
|
||||
/>
|
||||
<PromptOverlayButtonWrapper>
|
||||
<AddPromptTriggerButton isOpen={isOpen} onOpen={onOpen} />
|
||||
</PromptOverlayButtonWrapper>
|
||||
<PromptLabel label={t('sdxl.posStylePrompt')} />
|
||||
</Box>
|
||||
</PromptPopover>
|
||||
);
|
||||
});
|
||||
|
||||
ParamSDXLPositiveStylePrompt.displayName = 'ParamSDXLPositiveStylePrompt';
|
||||
@@ -1,37 +0,0 @@
|
||||
import { IconButton, Tooltip } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectShouldConcatPrompts, shouldConcatPromptsChanged } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiLinkSimpleBold, PiLinkSimpleBreakBold } from 'react-icons/pi';
|
||||
|
||||
export const SDXLConcatButton = memo(() => {
|
||||
const shouldConcatPrompts = useAppSelector(selectShouldConcatPrompts);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleShouldConcatPromptChange = useCallback(() => {
|
||||
dispatch(shouldConcatPromptsChanged(!shouldConcatPrompts));
|
||||
}, [dispatch, shouldConcatPrompts]);
|
||||
|
||||
const label = useMemo(
|
||||
() => (shouldConcatPrompts ? t('sdxl.concatPromptStyle') : t('sdxl.freePromptStyle')),
|
||||
[shouldConcatPrompts, t]
|
||||
);
|
||||
|
||||
return (
|
||||
<Tooltip label={label}>
|
||||
<IconButton
|
||||
aria-label={label}
|
||||
onClick={handleShouldConcatPromptChange}
|
||||
icon={shouldConcatPrompts ? <PiLinkSimpleBold size={14} /> : <PiLinkSimpleBreakBold size={14} />}
|
||||
variant="promptOverlay"
|
||||
fontSize={12}
|
||||
px={0.5}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
});
|
||||
|
||||
SDXLConcatButton.displayName = 'SDXLConcatButton';
|
||||
Reference in New Issue
Block a user