mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
move mdoal state into nanostore
This commit is contained in:
parent
096f001634
commit
6c927a9fd4
@ -28,7 +28,6 @@ import { generationPersistConfig, generationSlice } from 'features/parameters/st
|
|||||||
import { upscalePersistConfig, upscaleSlice } from 'features/parameters/store/upscaleSlice';
|
import { upscalePersistConfig, upscaleSlice } from 'features/parameters/store/upscaleSlice';
|
||||||
import { queueSlice } from 'features/queue/store/queueSlice';
|
import { queueSlice } from 'features/queue/store/queueSlice';
|
||||||
import { sdxlPersistConfig, sdxlSlice } from 'features/sdxl/store/sdxlSlice';
|
import { sdxlPersistConfig, sdxlSlice } from 'features/sdxl/store/sdxlSlice';
|
||||||
import { stylePresetModalSlice } from 'features/stylePresets/store/stylePresetModalSlice';
|
|
||||||
import { stylePresetPersistConfig, stylePresetSlice } from 'features/stylePresets/store/stylePresetSlice';
|
import { stylePresetPersistConfig, stylePresetSlice } from 'features/stylePresets/store/stylePresetSlice';
|
||||||
import { configSlice } from 'features/system/store/configSlice';
|
import { configSlice } from 'features/system/store/configSlice';
|
||||||
import { systemPersistConfig, systemSlice } from 'features/system/store/systemSlice';
|
import { systemPersistConfig, systemSlice } from 'features/system/store/systemSlice';
|
||||||
@ -71,7 +70,6 @@ const allReducers = {
|
|||||||
[workflowSettingsSlice.name]: workflowSettingsSlice.reducer,
|
[workflowSettingsSlice.name]: workflowSettingsSlice.reducer,
|
||||||
[api.reducerPath]: api.reducer,
|
[api.reducerPath]: api.reducer,
|
||||||
[upscaleSlice.name]: upscaleSlice.reducer,
|
[upscaleSlice.name]: upscaleSlice.reducer,
|
||||||
[stylePresetModalSlice.name]: stylePresetModalSlice.reducer,
|
|
||||||
[stylePresetSlice.name]: stylePresetSlice.reducer,
|
[stylePresetSlice.name]: stylePresetSlice.reducer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { handlers, parseAndRecallAllMetadata, parseAndRecallPrompts } from 'features/metadata/util/handlers';
|
import { handlers, parseAndRecallAllMetadata, parseAndRecallPrompts } from 'features/metadata/util/handlers';
|
||||||
import { isModalOpenChanged, prefilledFormDataChanged } from 'features/stylePresets/store/stylePresetModalSlice';
|
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||||
@ -13,7 +13,6 @@ export const useImageActions = (image_name?: string) => {
|
|||||||
const [hasMetadata, setHasMetadata] = useState(false);
|
const [hasMetadata, setHasMetadata] = useState(false);
|
||||||
const [hasSeed, setHasSeed] = useState(false);
|
const [hasSeed, setHasSeed] = useState(false);
|
||||||
const [hasPrompts, setHasPrompts] = useState(false);
|
const [hasPrompts, setHasPrompts] = useState(false);
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { data: imageDTO } = useGetImageDTOQuery(image_name ?? skipToken);
|
const { data: imageDTO } = useGetImageDTOQuery(image_name ?? skipToken);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -71,17 +70,18 @@ export const useImageActions = (image_name?: string) => {
|
|||||||
const positivePrompt = await handlers.positivePrompt.parse(metadata);
|
const positivePrompt = await handlers.positivePrompt.parse(metadata);
|
||||||
const negativePrompt = await handlers.negativePrompt.parse(metadata);
|
const negativePrompt = await handlers.negativePrompt.parse(metadata);
|
||||||
|
|
||||||
dispatch(
|
$stylePresetModalState.set({
|
||||||
prefilledFormDataChanged({
|
prefilledFormData: {
|
||||||
name: '',
|
name: '',
|
||||||
positivePrompt,
|
positivePrompt,
|
||||||
negativePrompt,
|
negativePrompt,
|
||||||
imageUrl: imageDTO.image_url,
|
imageUrl: imageDTO.image_url,
|
||||||
})
|
},
|
||||||
);
|
updatingStylePresetId: null,
|
||||||
dispatch(isModalOpenChanged(true));
|
isModalOpen: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, [image_name, metadata, dispatch, imageDTO]);
|
}, [image_name, metadata, imageDTO]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
recallAll,
|
recallAll,
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
import { Button, Flex, FormControl, FormLabel, Input, Text } from '@invoke-ai/ui-library';
|
import { Button, Flex, FormControl, FormLabel, Input, Text } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||||
import {
|
|
||||||
isModalOpenChanged,
|
|
||||||
prefilledFormDataChanged,
|
|
||||||
updatingStylePresetIdChanged,
|
|
||||||
} from 'features/stylePresets/store/stylePresetModalSlice';
|
|
||||||
import { toast } from 'features/toast/toast';
|
import { toast } from 'features/toast/toast';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import type { SubmitHandler } from 'react-hook-form';
|
import type { SubmitHandler } from 'react-hook-form';
|
||||||
@ -31,7 +26,6 @@ export const StylePresetForm = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [createStylePreset] = useCreateStylePresetMutation();
|
const [createStylePreset] = useCreateStylePresetMutation();
|
||||||
const [updateStylePreset] = useUpdateStylePresetMutation();
|
const [updateStylePreset] = useUpdateStylePresetMutation();
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { handleSubmit, control, register, formState } = useForm<StylePresetFormData>({
|
const { handleSubmit, control, register, formState } = useForm<StylePresetFormData>({
|
||||||
@ -69,11 +63,13 @@ export const StylePresetForm = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(prefilledFormDataChanged(null));
|
$stylePresetModalState.set({
|
||||||
dispatch(updatingStylePresetIdChanged(null));
|
prefilledFormData: null,
|
||||||
dispatch(isModalOpenChanged(false));
|
updatingStylePresetId: null,
|
||||||
|
isModalOpen: false,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[dispatch, updatingStylePresetId, updateStylePreset, createStylePreset]
|
[updatingStylePresetId, updateStylePreset, createStylePreset]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
import { Badge, ConfirmationAlertDialog, Flex, IconButton, Text, useDisclosure } from '@invoke-ai/ui-library';
|
import { Badge, ConfirmationAlertDialog, Flex, IconButton, Text, useDisclosure } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
||||||
import {
|
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||||
isModalOpenChanged,
|
|
||||||
prefilledFormDataChanged,
|
|
||||||
updatingStylePresetIdChanged,
|
|
||||||
} from 'features/stylePresets/store/stylePresetModalSlice';
|
|
||||||
import { activeStylePresetIdChanged } from 'features/stylePresets/store/stylePresetSlice';
|
import { activeStylePresetIdChanged } from 'features/stylePresets/store/stylePresetSlice';
|
||||||
import { toast } from 'features/toast/toast';
|
import { toast } from 'features/toast/toast';
|
||||||
import type { MouseEvent } from 'react';
|
import type { MouseEvent } from 'react';
|
||||||
@ -30,19 +26,18 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI
|
|||||||
const { name, preset_data } = preset;
|
const { name, preset_data } = preset;
|
||||||
const { positive_prompt, negative_prompt } = preset_data;
|
const { positive_prompt, negative_prompt } = preset_data;
|
||||||
|
|
||||||
dispatch(
|
$stylePresetModalState.set({
|
||||||
prefilledFormDataChanged({
|
prefilledFormData: {
|
||||||
name,
|
name,
|
||||||
positivePrompt: positive_prompt || '',
|
positivePrompt: positive_prompt || '',
|
||||||
negativePrompt: negative_prompt || '',
|
negativePrompt: negative_prompt || '',
|
||||||
imageUrl: preset.image,
|
imageUrl: preset.image,
|
||||||
})
|
},
|
||||||
);
|
updatingStylePresetId: preset.id,
|
||||||
|
isModalOpen: true,
|
||||||
dispatch(updatingStylePresetIdChanged(preset.id));
|
});
|
||||||
dispatch(isModalOpenChanged(true));
|
|
||||||
},
|
},
|
||||||
[dispatch, preset]
|
[preset]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleClickApply = useCallback(async () => {
|
const handleClickApply = useCallback(async () => {
|
||||||
@ -64,19 +59,18 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI
|
|||||||
const { name, preset_data } = preset;
|
const { name, preset_data } = preset;
|
||||||
const { positive_prompt, negative_prompt } = preset_data;
|
const { positive_prompt, negative_prompt } = preset_data;
|
||||||
|
|
||||||
dispatch(
|
$stylePresetModalState.set({
|
||||||
prefilledFormDataChanged({
|
prefilledFormData: {
|
||||||
name: `${name} (${t('common.copy')})`,
|
name: `${name} (${t('common.copy')})`,
|
||||||
positivePrompt: positive_prompt || '',
|
positivePrompt: positive_prompt || '',
|
||||||
negativePrompt: negative_prompt || '',
|
negativePrompt: negative_prompt || '',
|
||||||
imageUrl: preset.image,
|
imageUrl: preset.image,
|
||||||
})
|
},
|
||||||
);
|
updatingStylePresetId: null,
|
||||||
|
isModalOpen: true,
|
||||||
dispatch(updatingStylePresetIdChanged(null));
|
});
|
||||||
dispatch(isModalOpenChanged(true));
|
|
||||||
},
|
},
|
||||||
[dispatch, preset, t]
|
[preset, t]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDeletePreset = useCallback(async () => {
|
const handleDeletePreset = useCallback(async () => {
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
import { Flex, IconButton, Text } from '@invoke-ai/ui-library';
|
import { Flex, IconButton, Text } from '@invoke-ai/ui-library';
|
||||||
import { EMPTY_ARRAY } from 'app/store/constants';
|
import { EMPTY_ARRAY } from 'app/store/constants';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import {
|
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||||
isModalOpenChanged,
|
|
||||||
prefilledFormDataChanged,
|
|
||||||
updatingStylePresetIdChanged,
|
|
||||||
} from 'features/stylePresets/store/stylePresetModalSlice';
|
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PiPlusBold } from 'react-icons/pi';
|
import { PiPlusBold } from 'react-icons/pi';
|
||||||
@ -40,14 +36,15 @@ export const StylePresetMenu = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleClickAddNew = useCallback(() => {
|
const handleClickAddNew = useCallback(() => {
|
||||||
dispatch(prefilledFormDataChanged(null));
|
$stylePresetModalState.set({
|
||||||
dispatch(updatingStylePresetIdChanged(null));
|
prefilledFormData: null,
|
||||||
dispatch(isModalOpenChanged(true));
|
updatingStylePresetId: null,
|
||||||
}, [dispatch]);
|
isModalOpen: true,
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex flexDir="column" gap={2} padding={3} layerStyle="second" borderRadius="base">
|
<Flex flexDir="column" gap={2} padding={3} layerStyle="second" borderRadius="base">
|
||||||
|
@ -8,13 +8,9 @@ import {
|
|||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
Spinner,
|
Spinner,
|
||||||
} from '@invoke-ai/ui-library';
|
} from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useStore } from '@nanostores/react';
|
||||||
import { convertImageUrlToBlob } from 'common/util/convertImageUrlToBlob';
|
import { convertImageUrlToBlob } from 'common/util/convertImageUrlToBlob';
|
||||||
import {
|
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||||
isModalOpenChanged,
|
|
||||||
prefilledFormDataChanged,
|
|
||||||
updatingStylePresetIdChanged,
|
|
||||||
} from 'features/stylePresets/store/stylePresetModalSlice';
|
|
||||||
import type { PrefilledFormData } from 'features/stylePresets/store/types';
|
import type { PrefilledFormData } from 'features/stylePresets/store/types';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -24,21 +20,22 @@ import { StylePresetForm } from './StylePresetForm';
|
|||||||
|
|
||||||
export const StylePresetModal = () => {
|
export const StylePresetModal = () => {
|
||||||
const [formData, setFormData] = useState<StylePresetFormData | null>(null);
|
const [formData, setFormData] = useState<StylePresetFormData | null>(null);
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const isModalOpen = useAppSelector((s) => s.stylePresetModal.isModalOpen);
|
const stylePresetModalState = useStore($stylePresetModalState);
|
||||||
const updatingStylePresetId = useAppSelector((s) => s.stylePresetModal.updatingStylePresetId);
|
|
||||||
const prefilledFormData = useAppSelector((s) => s.stylePresetModal.prefilledFormData);
|
|
||||||
|
|
||||||
const modalTitle = useMemo(() => {
|
const modalTitle = useMemo(() => {
|
||||||
return updatingStylePresetId ? t('stylePresets.updatePromptTemplate') : t('stylePresets.createPromptTemplate');
|
return stylePresetModalState.updatingStylePresetId
|
||||||
}, [updatingStylePresetId, t]);
|
? t('stylePresets.updatePromptTemplate')
|
||||||
|
: t('stylePresets.createPromptTemplate');
|
||||||
|
}, [stylePresetModalState.updatingStylePresetId, t]);
|
||||||
|
|
||||||
const handleCloseModal = useCallback(() => {
|
const handleCloseModal = useCallback(() => {
|
||||||
dispatch(prefilledFormDataChanged(null));
|
$stylePresetModalState.set({
|
||||||
dispatch(updatingStylePresetIdChanged(null));
|
prefilledFormData: null,
|
||||||
dispatch(isModalOpenChanged(false));
|
updatingStylePresetId: null,
|
||||||
}, [dispatch]);
|
isModalOpen: false,
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFormData(null);
|
setFormData(null);
|
||||||
@ -62,18 +59,18 @@ export const StylePresetModal = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
convertImageToBlob(prefilledFormData);
|
convertImageToBlob(stylePresetModalState.prefilledFormData);
|
||||||
}, [prefilledFormData]);
|
}, [stylePresetModalState.prefilledFormData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isModalOpen} onClose={handleCloseModal} isCentered size="2xl">
|
<Modal isOpen={stylePresetModalState.isModalOpen} onClose={handleCloseModal} isCentered size="2xl">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
<ModalHeader>{modalTitle}</ModalHeader>
|
<ModalHeader>{modalTitle}</ModalHeader>
|
||||||
<ModalCloseButton />
|
<ModalCloseButton />
|
||||||
<ModalBody display="flex" flexDir="column" gap={4}>
|
<ModalBody display="flex" flexDir="column" gap={4}>
|
||||||
{!prefilledFormData || formData ? (
|
{!stylePresetModalState.prefilledFormData || formData ? (
|
||||||
<StylePresetForm updatingStylePresetId={updatingStylePresetId} formData={formData} />
|
<StylePresetForm updatingStylePresetId={stylePresetModalState.updatingStylePresetId} formData={formData} />
|
||||||
) : (
|
) : (
|
||||||
<Spinner />
|
<Spinner />
|
||||||
)}
|
)}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
import { atom } from 'nanostores';
|
||||||
|
|
||||||
|
const initialState: StylePresetModalState = {
|
||||||
|
isModalOpen: false,
|
||||||
|
updatingStylePresetId: null,
|
||||||
|
prefilledFormData: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks the state for the style preset modal.
|
||||||
|
*/
|
||||||
|
export const $stylePresetModalState = atom<StylePresetModalState>(initialState);
|
||||||
|
|
||||||
|
export type StylePresetModalState = {
|
||||||
|
isModalOpen: boolean;
|
||||||
|
updatingStylePresetId: string | null;
|
||||||
|
prefilledFormData: PrefilledFormData | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PrefilledFormData = {
|
||||||
|
name: string;
|
||||||
|
positivePrompt: string;
|
||||||
|
negativePrompt: string;
|
||||||
|
imageUrl: string | null;
|
||||||
|
};
|
@ -1,29 +0,0 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
|
||||||
|
|
||||||
import type { PrefilledFormData, StylePresetModalState } from './types';
|
|
||||||
|
|
||||||
const initialState: StylePresetModalState = {
|
|
||||||
isModalOpen: false,
|
|
||||||
updatingStylePresetId: null,
|
|
||||||
prefilledFormData: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const stylePresetModalSlice = createSlice({
|
|
||||||
name: 'stylePresetModal',
|
|
||||||
initialState: initialState,
|
|
||||||
reducers: {
|
|
||||||
isModalOpenChanged: (state, action: PayloadAction<boolean>) => {
|
|
||||||
state.isModalOpen = action.payload;
|
|
||||||
},
|
|
||||||
updatingStylePresetIdChanged: (state, action: PayloadAction<string | null>) => {
|
|
||||||
state.updatingStylePresetId = action.payload;
|
|
||||||
},
|
|
||||||
prefilledFormDataChanged: (state, action: PayloadAction<PrefilledFormData | null>) => {
|
|
||||||
state.prefilledFormData = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { isModalOpenChanged, updatingStylePresetIdChanged, prefilledFormDataChanged } =
|
|
||||||
stylePresetModalSlice.actions;
|
|
Loading…
Reference in New Issue
Block a user