Skip to content

Commit 7659771

Browse files
feat(ui): persist sizes of all 4 prompt boxes
1 parent 823b5ca commit 7659771

File tree

4 files changed

+37
-45
lines changed

4 files changed

+37
-45
lines changed

invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Box, Textarea } from '@invoke-ai/ui-library';
22
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
3+
import { usePersistedTextAreaSize } from 'common/hooks/usePersistedTextareaSize';
34
import { negativePromptChanged, selectNegativePrompt } from 'features/controlLayers/store/paramsSlice';
45
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
56
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
@@ -15,12 +16,20 @@ import { memo, useCallback, useRef } from 'react';
1516
import { useTranslation } from 'react-i18next';
1617
import { useListStylePresetsQuery } from 'services/api/endpoints/stylePresets';
1718

19+
const persistOptions: Parameters<typeof usePersistedTextAreaSize>[2] = {
20+
trackWidth: false,
21+
trackHeight: true,
22+
};
23+
1824
export const ParamNegativePrompt = memo(() => {
1925
const dispatch = useAppDispatch();
2026
const prompt = useAppSelector(selectNegativePrompt);
2127
const viewMode = useAppSelector(selectStylePresetViewMode);
2228
const activeStylePresetId = useAppSelector(selectStylePresetActivePresetId);
2329

30+
const textareaRef = useRef<HTMLTextAreaElement>(null);
31+
usePersistedTextAreaSize('negative_prompt', textareaRef, persistOptions);
32+
2433
const { activeStylePreset } = useListStylePresetsQuery(undefined, {
2534
selectFromResult: ({ data }) => {
2635
let activeStylePreset = null;
@@ -31,7 +40,6 @@ export const ParamNegativePrompt = memo(() => {
3140
},
3241
});
3342

34-
const textareaRef = useRef<HTMLTextAreaElement>(null);
3543
const { t } = useTranslation();
3644
const _onChange = useCallback(
3745
(v: string) => {

invokeai/frontend/web/src/features/parameters/components/Core/ParamPositivePrompt.tsx

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Box, Textarea } from '@invoke-ai/ui-library';
22
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
3+
import { usePersistedTextAreaSize } from 'common/hooks/usePersistedTextareaSize';
34
import { positivePromptChanged, selectBase, selectPositivePrompt } from 'features/controlLayers/store/paramsSlice';
45
import { ShowDynamicPromptsPreviewButton } from 'features/dynamicPrompts/components/ShowDynamicPromptsPreviewButton';
56
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
@@ -14,20 +15,26 @@ import {
1415
selectStylePresetViewMode,
1516
} from 'features/stylePresets/store/stylePresetSlice';
1617
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
17-
import { positivePromptBoxHeightChanged, selectPositivePromptBoxHeight } from 'features/ui/store/uiSlice';
18-
import { debounce } from 'lodash-es';
19-
import { memo, useCallback, useEffect, useRef } from 'react';
18+
import { memo, useCallback, useRef } from 'react';
2019
import type { HotkeyCallback } from 'react-hotkeys-hook';
2120
import { useTranslation } from 'react-i18next';
2221
import { useListStylePresetsQuery } from 'services/api/endpoints/stylePresets';
2322

23+
const persistOptions: Parameters<typeof usePersistedTextAreaSize>[2] = {
24+
trackWidth: false,
25+
trackHeight: true,
26+
initialHeight: 120,
27+
};
28+
2429
export const ParamPositivePrompt = memo(() => {
2530
const dispatch = useAppDispatch();
2631
const prompt = useAppSelector(selectPositivePrompt);
2732
const baseModel = useAppSelector(selectBase);
2833
const viewMode = useAppSelector(selectStylePresetViewMode);
2934
const activeStylePresetId = useAppSelector(selectStylePresetActivePresetId);
30-
const positivePromptBoxHeight = useAppSelector(selectPositivePromptBoxHeight);
35+
36+
const textareaRef = useRef<HTMLTextAreaElement>(null);
37+
usePersistedTextAreaSize('positive_prompt', textareaRef, persistOptions);
3138

3239
const { activeStylePreset } = useListStylePresetsQuery(undefined, {
3340
selectFromResult: ({ data }) => {
@@ -39,7 +46,6 @@ export const ParamPositivePrompt = memo(() => {
3946
},
4047
});
4148

42-
const textareaRef = useRef<HTMLTextAreaElement>(null);
4349
const { t } = useTranslation();
4450
const handleChange = useCallback(
4551
(v: string) => {
@@ -53,45 +59,6 @@ export const ParamPositivePrompt = memo(() => {
5359
onChange: handleChange,
5460
});
5561

56-
// Add debounced resize observer to detect height changes
57-
useEffect(() => {
58-
const textarea = textareaRef.current;
59-
if (!textarea) {
60-
return;
61-
}
62-
63-
let currentHeight = textarea.offsetHeight;
64-
65-
const debouncedHeightUpdate = debounce((newHeight: number) => {
66-
dispatch(positivePromptBoxHeightChanged(newHeight));
67-
}, 150);
68-
69-
const resizeObserver = new ResizeObserver((entries) => {
70-
for (const entry of entries) {
71-
const newHeight = (entry.target as HTMLTextAreaElement).offsetHeight;
72-
if (newHeight !== currentHeight) {
73-
currentHeight = newHeight;
74-
debouncedHeightUpdate(newHeight);
75-
}
76-
}
77-
});
78-
79-
resizeObserver.observe(textarea);
80-
return () => {
81-
resizeObserver.disconnect();
82-
debouncedHeightUpdate.cancel();
83-
};
84-
}, [dispatch]);
85-
86-
useEffect(() => {
87-
const textarea = textareaRef.current;
88-
if (!textarea) {
89-
return;
90-
}
91-
92-
textarea.style.height = `${positivePromptBoxHeight}px`;
93-
}, [positivePromptBoxHeight]);
94-
9562
const focus: HotkeyCallback = useCallback(
9663
(e) => {
9764
onFocus();
@@ -125,6 +92,7 @@ export const ParamPositivePrompt = memo(() => {
12592
paddingTop={0}
12693
paddingBottom={3}
12794
resize="vertical"
95+
minH={28}
12896
/>
12997
<PromptOverlayButtonWrapper>
13098
<AddPromptTriggerButton isOpen={isOpen} onOpen={onOpen} />

invokeai/frontend/web/src/features/sdxl/components/SDXLPrompts/ParamSDXLNegativeStylePrompt.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Box, Textarea } from '@invoke-ai/ui-library';
22
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
3+
import { usePersistedTextAreaSize } from 'common/hooks/usePersistedTextareaSize';
34
import { negativePrompt2Changed, selectNegativePrompt2 } from 'features/controlLayers/store/paramsSlice';
45
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
56
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
@@ -9,10 +10,17 @@ import { usePrompt } from 'features/prompt/usePrompt';
910
import { memo, useCallback, useRef } from 'react';
1011
import { useTranslation } from 'react-i18next';
1112

13+
const persistOptions: Parameters<typeof usePersistedTextAreaSize>[2] = {
14+
trackWidth: false,
15+
trackHeight: true,
16+
};
17+
1218
export const ParamSDXLNegativeStylePrompt = memo(() => {
1319
const dispatch = useAppDispatch();
1420
const prompt = useAppSelector(selectNegativePrompt2);
1521
const textareaRef = useRef<HTMLTextAreaElement>(null);
22+
usePersistedTextAreaSize('negative_style_prompt', textareaRef, persistOptions);
23+
1624
const { t } = useTranslation();
1725
const handleChange = useCallback(
1826
(v: string) => {

invokeai/frontend/web/src/features/sdxl/components/SDXLPrompts/ParamSDXLPositiveStylePrompt.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Box, Textarea } from '@invoke-ai/ui-library';
22
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
3+
import { usePersistedTextAreaSize } from 'common/hooks/usePersistedTextareaSize';
34
import { positivePrompt2Changed, selectPositivePrompt2 } from 'features/controlLayers/store/paramsSlice';
45
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
56
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
@@ -9,10 +10,17 @@ import { usePrompt } from 'features/prompt/usePrompt';
910
import { memo, useCallback, useRef } from 'react';
1011
import { useTranslation } from 'react-i18next';
1112

13+
const persistOptions: Parameters<typeof usePersistedTextAreaSize>[2] = {
14+
trackWidth: false,
15+
trackHeight: true,
16+
};
17+
1218
export const ParamSDXLPositiveStylePrompt = memo(() => {
1319
const dispatch = useAppDispatch();
1420
const prompt = useAppSelector(selectPositivePrompt2);
1521
const textareaRef = useRef<HTMLTextAreaElement>(null);
22+
usePersistedTextAreaSize('positive_style_prompt', textareaRef, persistOptions);
23+
1624
const { t } = useTranslation();
1725
const handleChange = useCallback(
1826
(v: string) => {

0 commit comments

Comments
 (0)