diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx index 7a46f4c934..7d25d6bc05 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx @@ -139,8 +139,19 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => { useHotkeys('s', handleUseSeed, [imageDTO]); const handleUsePrompt = useCallback(() => { - recallBothPrompts(metadata?.positive_prompt, metadata?.negative_prompt); - }, [metadata?.negative_prompt, metadata?.positive_prompt, recallBothPrompts]); + recallBothPrompts( + metadata?.positive_prompt, + metadata?.negative_prompt, + metadata?.positive_style_prompt, + metadata?.negative_style_prompt + ); + }, [ + metadata?.negative_prompt, + metadata?.positive_prompt, + metadata?.positive_style_prompt, + metadata?.negative_style_prompt, + recallBothPrompts, + ]); useHotkeys('p', handleUsePrompt, [imageDTO]); diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx index 237a38ca33..c7b1494ecb 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx @@ -102,8 +102,19 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { // Recall parameters handlers const handleRecallPrompt = useCallback(() => { - recallBothPrompts(metadata?.positive_prompt, metadata?.negative_prompt); - }, [metadata?.negative_prompt, metadata?.positive_prompt, recallBothPrompts]); + recallBothPrompts( + metadata?.positive_prompt, + metadata?.negative_prompt, + metadata?.positive_style_prompt, + metadata?.negative_style_prompt + ); + }, [ + metadata?.negative_prompt, + metadata?.positive_prompt, + metadata?.positive_style_prompt, + metadata?.negative_style_prompt, + recallBothPrompts, + ]); const handleRecallSeed = useCallback(() => { recallSeed(metadata?.seed); diff --git a/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts b/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts index e19f4cd5f4..0165245bd0 100644 --- a/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts +++ b/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts @@ -1,5 +1,15 @@ import { useAppToaster } from 'app/components/Toaster'; import { useAppDispatch } from 'app/store/storeHooks'; +import { + refinerModelChanged, + setNegativeStylePromptSDXL, + setPositiveStylePromptSDXL, + setRefinerAestheticScore, + setRefinerCFGScale, + setRefinerScheduler, + setRefinerStart, + setRefinerSteps, +} from 'features/sdxl/store/sdxlSlice'; import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { UnsafeImageMetadata } from 'services/api/endpoints/images'; @@ -22,6 +32,10 @@ import { isValidMainModel, isValidNegativePrompt, isValidPositivePrompt, + isValidSDXLNegativeStylePrompt, + isValidSDXLPositiveStylePrompt, + isValidSDXLRefinerAestheticScore, + isValidSDXLRefinerStart, isValidScheduler, isValidSeed, isValidSteps, @@ -74,17 +88,34 @@ export const useRecallParameters = () => { * Recall both prompts with toast */ const recallBothPrompts = useCallback( - (positivePrompt: unknown, negativePrompt: unknown) => { + ( + positivePrompt: unknown, + negativePrompt: unknown, + positiveStylePrompt: unknown, + negativeStylePrompt: unknown + ) => { if ( isValidPositivePrompt(positivePrompt) || - isValidNegativePrompt(negativePrompt) + isValidNegativePrompt(negativePrompt) || + isValidSDXLPositiveStylePrompt(positiveStylePrompt) || + isValidSDXLNegativeStylePrompt(negativeStylePrompt) ) { if (isValidPositivePrompt(positivePrompt)) { dispatch(setPositivePrompt(positivePrompt)); } + if (isValidNegativePrompt(negativePrompt)) { dispatch(setNegativePrompt(negativePrompt)); } + + if (isValidSDXLPositiveStylePrompt(positiveStylePrompt)) { + dispatch(setPositiveStylePromptSDXL(positiveStylePrompt)); + } + + if (isValidSDXLPositiveStylePrompt(negativeStylePrompt)) { + dispatch(setNegativeStylePromptSDXL(negativeStylePrompt)); + } + parameterSetToast(); return; } @@ -123,6 +154,36 @@ export const useRecallParameters = () => { [dispatch, parameterSetToast, parameterNotSetToast] ); + /** + * Recall SDXL Positive Style Prompt with toast + */ + const recallSDXLPositiveStylePrompt = useCallback( + (positiveStylePrompt: unknown) => { + if (!isValidSDXLPositiveStylePrompt(positiveStylePrompt)) { + parameterNotSetToast(); + return; + } + dispatch(setPositiveStylePromptSDXL(positiveStylePrompt)); + parameterSetToast(); + }, + [dispatch, parameterSetToast, parameterNotSetToast] + ); + + /** + * Recall SDXL Negative Style Prompt with toast + */ + const recallSDXLNegativeStylePrompt = useCallback( + (negativeStylePrompt: unknown) => { + if (!isValidSDXLNegativeStylePrompt(negativeStylePrompt)) { + parameterNotSetToast(); + return; + } + dispatch(setNegativeStylePromptSDXL(negativeStylePrompt)); + parameterSetToast(); + }, + [dispatch, parameterSetToast, parameterNotSetToast] + ); + /** * Recall seed with toast */ @@ -271,6 +332,14 @@ export const useRecallParameters = () => { steps, width, strength, + positive_style_prompt, + negative_style_prompt, + refiner_model, + refiner_cfg_scale, + refiner_steps, + refiner_scheduler, + refiner_aesthetic_store, + refiner_start, } = metadata; if (isValidCfgScale(cfg_scale)) { @@ -304,6 +373,38 @@ export const useRecallParameters = () => { dispatch(setImg2imgStrength(strength)); } + if (isValidSDXLPositiveStylePrompt(positive_style_prompt)) { + dispatch(setPositiveStylePromptSDXL(positive_style_prompt)); + } + + if (isValidSDXLNegativeStylePrompt(negative_style_prompt)) { + dispatch(setNegativeStylePromptSDXL(negative_style_prompt)); + } + + if (isValidMainModel(refiner_model)) { + dispatch(refinerModelChanged(refiner_model)); + } + + if (isValidSteps(refiner_steps)) { + dispatch(setRefinerSteps(refiner_steps)); + } + + if (isValidCfgScale(refiner_cfg_scale)) { + dispatch(setRefinerCFGScale(refiner_cfg_scale)); + } + + if (isValidScheduler(refiner_scheduler)) { + dispatch(setRefinerScheduler(refiner_scheduler)); + } + + if (isValidSDXLRefinerAestheticScore(refiner_aesthetic_store)) { + dispatch(setRefinerAestheticScore(refiner_aesthetic_store)); + } + + if (isValidSDXLRefinerStart(refiner_start)) { + dispatch(setRefinerStart(refiner_start)); + } + allParameterSetToast(); }, [allParameterNotSetToast, allParameterSetToast, dispatch] @@ -313,6 +414,8 @@ export const useRecallParameters = () => { recallBothPrompts, recallPositivePrompt, recallNegativePrompt, + recallSDXLPositiveStylePrompt, + recallSDXLNegativeStylePrompt, recallSeed, recallCfgScale, recallModel, diff --git a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts index 64f4665c5f..9cdfaeade3 100644 --- a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts +++ b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts @@ -310,6 +310,39 @@ export type PrecisionParam = z.infer; export const isValidPrecision = (val: unknown): val is PrecisionParam => zPrecision.safeParse(val).success; +/** + * Zod schema for SDXL refiner aesthetic score parameter + */ +export const zSDXLRefinerAestheticScore = z.number().min(1).max(10); +/** + * Type alias for SDXL refiner aesthetic score parameter, inferred from its zod schema + */ +export type SDXLRefinerAestheticScoreParam = z.infer< + typeof zSDXLRefinerAestheticScore +>; +/** + * Validates/type-guards a value as a SDXL refiner aesthetic score parameter + */ +export const isValidSDXLRefinerAestheticScore = ( + val: unknown +): val is SDXLRefinerAestheticScoreParam => + zSDXLRefinerAestheticScore.safeParse(val).success; + +/** + * Zod schema for SDXL start parameter + */ +export const zSDXLRefinerstart = z.number().min(0).max(1); +/** + * Type alias for SDXL start, inferred from its zod schema + */ +export type SDXLRefinerStartParam = z.infer; +/** + * Validates/type-guards a value as a SDXL refiner aesthetic score parameter + */ +export const isValidSDXLRefinerStart = ( + val: unknown +): val is SDXLRefinerStartParam => zSDXLRefinerstart.safeParse(val).success; + // /** // * Zod schema for BaseModelType // */ diff --git a/invokeai/frontend/web/src/features/sdxl/components/ParamSDXLConcatButton.tsx b/invokeai/frontend/web/src/features/sdxl/components/ParamSDXLConcatButton.tsx index 9393b245ef..7d51c6dea7 100644 --- a/invokeai/frontend/web/src/features/sdxl/components/ParamSDXLConcatButton.tsx +++ b/invokeai/frontend/web/src/features/sdxl/components/ParamSDXLConcatButton.tsx @@ -21,8 +21,8 @@ export default function ParamSDXLConcatButton() { return (