diff --git a/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx b/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx index 49f9d0fbfd..853d1326ef 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx @@ -1,5 +1,6 @@ import { Box, Textarea } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { usePersistedTextAreaSize } from 'common/hooks/usePersistedTextareaSize'; import { negativePromptChanged, selectNegativePrompt } from 'features/controlLayers/store/paramsSlice'; import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel'; import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper'; @@ -15,12 +16,20 @@ import { memo, useCallback, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { useListStylePresetsQuery } from 'services/api/endpoints/stylePresets'; +const persistOptions: Parameters[2] = { + trackWidth: false, + trackHeight: true, +}; + export const ParamNegativePrompt = memo(() => { const dispatch = useAppDispatch(); const prompt = useAppSelector(selectNegativePrompt); const viewMode = useAppSelector(selectStylePresetViewMode); const activeStylePresetId = useAppSelector(selectStylePresetActivePresetId); + const textareaRef = useRef(null); + usePersistedTextAreaSize('negative_prompt', textareaRef, persistOptions); + const { activeStylePreset } = useListStylePresetsQuery(undefined, { selectFromResult: ({ data }) => { let activeStylePreset = null; @@ -31,7 +40,6 @@ export const ParamNegativePrompt = memo(() => { }, }); - const textareaRef = useRef(null); const { t } = useTranslation(); const _onChange = useCallback( (v: string) => { diff --git a/invokeai/frontend/web/src/features/parameters/components/Core/ParamPositivePrompt.tsx b/invokeai/frontend/web/src/features/parameters/components/Core/ParamPositivePrompt.tsx index fb015d726a..037c1021fb 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Core/ParamPositivePrompt.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Core/ParamPositivePrompt.tsx @@ -1,5 +1,6 @@ import { Box, Textarea } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { usePersistedTextAreaSize } from 'common/hooks/usePersistedTextareaSize'; import { positivePromptChanged, selectBase, selectPositivePrompt } from 'features/controlLayers/store/paramsSlice'; import { ShowDynamicPromptsPreviewButton } from 'features/dynamicPrompts/components/ShowDynamicPromptsPreviewButton'; import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel'; @@ -14,20 +15,26 @@ import { selectStylePresetViewMode, } from 'features/stylePresets/store/stylePresetSlice'; import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData'; -import { positivePromptBoxHeightChanged, selectPositivePromptBoxHeight } from 'features/ui/store/uiSlice'; -import { debounce } from 'lodash-es'; -import { memo, useCallback, useEffect, useRef } from 'react'; +import { memo, useCallback, useRef } from 'react'; import type { HotkeyCallback } from 'react-hotkeys-hook'; import { useTranslation } from 'react-i18next'; import { useListStylePresetsQuery } from 'services/api/endpoints/stylePresets'; +const persistOptions: Parameters[2] = { + trackWidth: false, + trackHeight: true, + initialHeight: 120, +}; + export const ParamPositivePrompt = memo(() => { const dispatch = useAppDispatch(); const prompt = useAppSelector(selectPositivePrompt); const baseModel = useAppSelector(selectBase); const viewMode = useAppSelector(selectStylePresetViewMode); const activeStylePresetId = useAppSelector(selectStylePresetActivePresetId); - const positivePromptBoxHeight = useAppSelector(selectPositivePromptBoxHeight); + + const textareaRef = useRef(null); + usePersistedTextAreaSize('positive_prompt', textareaRef, persistOptions); const { activeStylePreset } = useListStylePresetsQuery(undefined, { selectFromResult: ({ data }) => { @@ -39,7 +46,6 @@ export const ParamPositivePrompt = memo(() => { }, }); - const textareaRef = useRef(null); const { t } = useTranslation(); const handleChange = useCallback( (v: string) => { @@ -53,45 +59,6 @@ export const ParamPositivePrompt = memo(() => { onChange: handleChange, }); - // Add debounced resize observer to detect height changes - useEffect(() => { - const textarea = textareaRef.current; - if (!textarea) { - return; - } - - let currentHeight = textarea.offsetHeight; - - const debouncedHeightUpdate = debounce((newHeight: number) => { - dispatch(positivePromptBoxHeightChanged(newHeight)); - }, 150); - - const resizeObserver = new ResizeObserver((entries) => { - for (const entry of entries) { - const newHeight = (entry.target as HTMLTextAreaElement).offsetHeight; - if (newHeight !== currentHeight) { - currentHeight = newHeight; - debouncedHeightUpdate(newHeight); - } - } - }); - - resizeObserver.observe(textarea); - return () => { - resizeObserver.disconnect(); - debouncedHeightUpdate.cancel(); - }; - }, [dispatch]); - - useEffect(() => { - const textarea = textareaRef.current; - if (!textarea) { - return; - } - - textarea.style.height = `${positivePromptBoxHeight}px`; - }, [positivePromptBoxHeight]); - const focus: HotkeyCallback = useCallback( (e) => { onFocus(); @@ -125,6 +92,7 @@ export const ParamPositivePrompt = memo(() => { paddingTop={0} paddingBottom={3} resize="vertical" + minH={28} /> diff --git a/invokeai/frontend/web/src/features/sdxl/components/SDXLPrompts/ParamSDXLNegativeStylePrompt.tsx b/invokeai/frontend/web/src/features/sdxl/components/SDXLPrompts/ParamSDXLNegativeStylePrompt.tsx index 8872512209..d31eeafbd5 100644 --- a/invokeai/frontend/web/src/features/sdxl/components/SDXLPrompts/ParamSDXLNegativeStylePrompt.tsx +++ b/invokeai/frontend/web/src/features/sdxl/components/SDXLPrompts/ParamSDXLNegativeStylePrompt.tsx @@ -1,5 +1,6 @@ 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'; @@ -9,10 +10,17 @@ import { usePrompt } from 'features/prompt/usePrompt'; import { memo, useCallback, useRef } from 'react'; import { useTranslation } from 'react-i18next'; +const persistOptions: Parameters[2] = { + trackWidth: false, + trackHeight: true, +}; + export const ParamSDXLNegativeStylePrompt = memo(() => { const dispatch = useAppDispatch(); const prompt = useAppSelector(selectNegativePrompt2); const textareaRef = useRef(null); + usePersistedTextAreaSize('negative_style_prompt', textareaRef, persistOptions); + const { t } = useTranslation(); const handleChange = useCallback( (v: string) => { diff --git a/invokeai/frontend/web/src/features/sdxl/components/SDXLPrompts/ParamSDXLPositiveStylePrompt.tsx b/invokeai/frontend/web/src/features/sdxl/components/SDXLPrompts/ParamSDXLPositiveStylePrompt.tsx index 5290ac959c..c9e76ddfca 100644 --- a/invokeai/frontend/web/src/features/sdxl/components/SDXLPrompts/ParamSDXLPositiveStylePrompt.tsx +++ b/invokeai/frontend/web/src/features/sdxl/components/SDXLPrompts/ParamSDXLPositiveStylePrompt.tsx @@ -1,5 +1,6 @@ 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'; @@ -9,10 +10,17 @@ import { usePrompt } from 'features/prompt/usePrompt'; import { memo, useCallback, useRef } from 'react'; import { useTranslation } from 'react-i18next'; +const persistOptions: Parameters[2] = { + trackWidth: false, + trackHeight: true, +}; + export const ParamSDXLPositiveStylePrompt = memo(() => { const dispatch = useAppDispatch(); const prompt = useAppSelector(selectPositivePrompt2); const textareaRef = useRef(null); + usePersistedTextAreaSize('positive_style_prompt', textareaRef, persistOptions); + const { t } = useTranslation(); const handleChange = useCallback( (v: string) => {