From 6aa605e811ba15a5b47cc9b577bba64c20435bf1 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 26 Jun 2025 16:00:19 +0000 Subject: [PATCH] Add toggle for showing/hiding style preset prompt previews Co-authored-by: kent --- invokeai/frontend/web/public/locales/en.json | 4 ++- .../components/StylePresetListItem.tsx | 32 +++++++++++-------- .../components/StylePresetMenu.tsx | 10 ++++-- .../StylePresetPromptPreviewToggle.tsx | 28 ++++++++++++++++ .../stylePresets/store/stylePresetSlice.ts | 10 +++++- .../src/features/stylePresets/store/types.ts | 1 + 6 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 invokeai/frontend/web/src/features/stylePresets/components/StylePresetPromptPreviewToggle.tsx diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index c027feb3b6..fe906a3ada 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -2400,7 +2400,9 @@ "uploadImage": "Upload Image", "useForTemplate": "Use For Prompt Template", "viewList": "View Template List", - "viewModeTooltip": "This is how your prompt will look with your currently selected template. To edit your prompt, click anywhere in the text box." + "viewModeTooltip": "This is how your prompt will look with your currently selected template. To edit your prompt, click anywhere in the text box.", + "showPromptPreviews": "Show Prompt Previews", + "hidePromptPreviews": "Hide Prompt Previews" }, "upsell": { "inviteTeammates": "Invite Teammates", diff --git a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetListItem.tsx b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetListItem.tsx index 45e5c81e6c..1fea084abf 100644 --- a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetListItem.tsx +++ b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetListItem.tsx @@ -5,6 +5,7 @@ import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetM import { $isStylePresetsMenuOpen, activeStylePresetIdChanged, + selectShowPromptPreviews, selectStylePresetActivePresetId, } from 'features/stylePresets/store/stylePresetSlice'; import type { MouseEvent } from 'react'; @@ -18,6 +19,7 @@ import StylePresetImage from './StylePresetImage'; export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithImage }) => { const dispatch = useAppDispatch(); const activeStylePresetId = useAppSelector(selectStylePresetActivePresetId); + const showPromptPreviews = useAppSelector(selectShowPromptPreviews); const { t } = useTranslation(); const deleteStylePreset = useDeleteStylePreset(); @@ -138,20 +140,22 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI - - - - {t('stylePresets.positivePrompt')}: - {' '} - {preset.preset_data.positive_prompt} - - - - {t('stylePresets.negativePrompt')}: - {' '} - {preset.preset_data.negative_prompt} - - + {showPromptPreviews && ( + + + + {t('stylePresets.positivePrompt')}: + {' '} + {preset.preset_data.positive_prompt} + + + + {t('stylePresets.negativePrompt')}: + {' '} + {preset.preset_data.negative_prompt} + + + )} ); diff --git a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetMenu.tsx b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetMenu.tsx index 73cc8b2a41..4b84f13864 100644 --- a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetMenu.tsx +++ b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetMenu.tsx @@ -3,6 +3,7 @@ import { EMPTY_ARRAY } from 'app/store/constants'; import { useAppSelector } from 'app/store/storeHooks'; import { StylePresetExportButton } from 'features/stylePresets/components/StylePresetExportButton'; import { StylePresetImportButton } from 'features/stylePresets/components/StylePresetImportButton'; +import { StylePresetPromptPreviewToggle } from 'features/stylePresets/components/StylePresetPromptPreviewToggle'; import { selectStylePresetSearchTerm } from 'features/stylePresets/store/stylePresetSlice'; import { selectAllowPrivateStylePresets } from 'features/system/store/configSlice'; import { useTranslation } from 'react-i18next'; @@ -54,9 +55,12 @@ export const StylePresetMenu = () => { - - - + + + + + + diff --git a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetPromptPreviewToggle.tsx b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetPromptPreviewToggle.tsx new file mode 100644 index 0000000000..ae55af2138 --- /dev/null +++ b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetPromptPreviewToggle.tsx @@ -0,0 +1,28 @@ +import { IconButton } from '@invoke-ai/ui-library'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { selectShowPromptPreviews, showPromptPreviewsChanged } from 'features/stylePresets/store/stylePresetSlice'; +import { useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; +import { PiEyeBold, PiEyeSlashBold } from 'react-icons/pi'; + +export const StylePresetPromptPreviewToggle = () => { + const dispatch = useAppDispatch(); + const showPromptPreviews = useAppSelector(selectShowPromptPreviews); + const { t } = useTranslation(); + + const handleToggle = useCallback(() => { + dispatch(showPromptPreviewsChanged(!showPromptPreviews)); + }, [dispatch, showPromptPreviews]); + + return ( + : } + colorScheme={showPromptPreviews ? 'invokeBlue' : 'base'} + /> + ); +}; \ No newline at end of file diff --git a/invokeai/frontend/web/src/features/stylePresets/store/stylePresetSlice.ts b/invokeai/frontend/web/src/features/stylePresets/store/stylePresetSlice.ts index ba996defc7..6d36e8770c 100644 --- a/invokeai/frontend/web/src/features/stylePresets/store/stylePresetSlice.ts +++ b/invokeai/frontend/web/src/features/stylePresets/store/stylePresetSlice.ts @@ -12,6 +12,7 @@ const initialState: StylePresetState = { activeStylePresetId: null, searchTerm: '', viewMode: false, + showPromptPreviews: false, }; export const stylePresetSlice = createSlice({ @@ -27,6 +28,9 @@ export const stylePresetSlice = createSlice({ viewModeChanged: (state, action: PayloadAction) => { state.viewMode = action.payload; }, + showPromptPreviewsChanged: (state, action: PayloadAction) => { + state.showPromptPreviews = action.payload; + }, }, extraReducers(builder) { builder.addCase(paramsReset, () => { @@ -53,13 +57,16 @@ export const stylePresetSlice = createSlice({ }, }); -export const { activeStylePresetIdChanged, searchTermChanged, viewModeChanged } = stylePresetSlice.actions; +export const { activeStylePresetIdChanged, searchTermChanged, viewModeChanged, showPromptPreviewsChanged } = stylePresetSlice.actions; /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ const migrateStylePresetState = (state: any): any => { if (!('_version' in state)) { state._version = 1; } + if (!('showPromptPreviews' in state)) { + state.showPromptPreviews = false; + } return state; }; @@ -79,6 +86,7 @@ export const selectStylePresetActivePresetId = createStylePresetSelector( ); export const selectStylePresetViewMode = createStylePresetSelector((stylePreset) => stylePreset.viewMode); export const selectStylePresetSearchTerm = createStylePresetSelector((stylePreset) => stylePreset.searchTerm); +export const selectShowPromptPreviews = createStylePresetSelector((stylePreset) => stylePreset.showPromptPreviews); /** * Tracks whether or not the style preset menu is open. diff --git a/invokeai/frontend/web/src/features/stylePresets/store/types.ts b/invokeai/frontend/web/src/features/stylePresets/store/types.ts index 98b53e307b..d156808384 100644 --- a/invokeai/frontend/web/src/features/stylePresets/store/types.ts +++ b/invokeai/frontend/web/src/features/stylePresets/store/types.ts @@ -2,4 +2,5 @@ export type StylePresetState = { activeStylePresetId: string | null; searchTerm: string; viewMode: boolean; + showPromptPreviews: boolean; };