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 { queueSlice } from 'features/queue/store/queueSlice';
|
||||
import { sdxlPersistConfig, sdxlSlice } from 'features/sdxl/store/sdxlSlice';
|
||||
import { stylePresetModalSlice } from 'features/stylePresets/store/stylePresetModalSlice';
|
||||
import { stylePresetPersistConfig, stylePresetSlice } from 'features/stylePresets/store/stylePresetSlice';
|
||||
import { configSlice } from 'features/system/store/configSlice';
|
||||
import { systemPersistConfig, systemSlice } from 'features/system/store/systemSlice';
|
||||
@ -71,7 +70,6 @@ const allReducers = {
|
||||
[workflowSettingsSlice.name]: workflowSettingsSlice.reducer,
|
||||
[api.reducerPath]: api.reducer,
|
||||
[upscaleSlice.name]: upscaleSlice.reducer,
|
||||
[stylePresetModalSlice.name]: stylePresetModalSlice.reducer,
|
||||
[stylePresetSlice.name]: stylePresetSlice.reducer,
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
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 { isModalOpenChanged, prefilledFormDataChanged } from 'features/stylePresets/store/stylePresetModalSlice';
|
||||
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||
@ -13,7 +13,6 @@ export const useImageActions = (image_name?: string) => {
|
||||
const [hasMetadata, setHasMetadata] = useState(false);
|
||||
const [hasSeed, setHasSeed] = useState(false);
|
||||
const [hasPrompts, setHasPrompts] = useState(false);
|
||||
const dispatch = useAppDispatch();
|
||||
const { data: imageDTO } = useGetImageDTOQuery(image_name ?? skipToken);
|
||||
|
||||
useEffect(() => {
|
||||
@ -71,17 +70,18 @@ export const useImageActions = (image_name?: string) => {
|
||||
const positivePrompt = await handlers.positivePrompt.parse(metadata);
|
||||
const negativePrompt = await handlers.negativePrompt.parse(metadata);
|
||||
|
||||
dispatch(
|
||||
prefilledFormDataChanged({
|
||||
$stylePresetModalState.set({
|
||||
prefilledFormData: {
|
||||
name: '',
|
||||
positivePrompt,
|
||||
negativePrompt,
|
||||
imageUrl: imageDTO.image_url,
|
||||
})
|
||||
);
|
||||
dispatch(isModalOpenChanged(true));
|
||||
},
|
||||
updatingStylePresetId: null,
|
||||
isModalOpen: true,
|
||||
});
|
||||
}
|
||||
}, [image_name, metadata, dispatch, imageDTO]);
|
||||
}, [image_name, metadata, imageDTO]);
|
||||
|
||||
return {
|
||||
recallAll,
|
||||
|
@ -1,10 +1,5 @@
|
||||
import { Button, Flex, FormControl, FormLabel, Input, Text } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import {
|
||||
isModalOpenChanged,
|
||||
prefilledFormDataChanged,
|
||||
updatingStylePresetIdChanged,
|
||||
} from 'features/stylePresets/store/stylePresetModalSlice';
|
||||
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import type { SubmitHandler } from 'react-hook-form';
|
||||
@ -31,7 +26,6 @@ export const StylePresetForm = ({
|
||||
}) => {
|
||||
const [createStylePreset] = useCreateStylePresetMutation();
|
||||
const [updateStylePreset] = useUpdateStylePresetMutation();
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { handleSubmit, control, register, formState } = useForm<StylePresetFormData>({
|
||||
@ -69,11 +63,13 @@ export const StylePresetForm = ({
|
||||
});
|
||||
}
|
||||
|
||||
dispatch(prefilledFormDataChanged(null));
|
||||
dispatch(updatingStylePresetIdChanged(null));
|
||||
dispatch(isModalOpenChanged(false));
|
||||
$stylePresetModalState.set({
|
||||
prefilledFormData: null,
|
||||
updatingStylePresetId: null,
|
||||
isModalOpen: false,
|
||||
});
|
||||
},
|
||||
[dispatch, updatingStylePresetId, updateStylePreset, createStylePreset]
|
||||
[updatingStylePresetId, updateStylePreset, createStylePreset]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -1,11 +1,7 @@
|
||||
import { Badge, ConfirmationAlertDialog, Flex, IconButton, Text, useDisclosure } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
||||
import {
|
||||
isModalOpenChanged,
|
||||
prefilledFormDataChanged,
|
||||
updatingStylePresetIdChanged,
|
||||
} from 'features/stylePresets/store/stylePresetModalSlice';
|
||||
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||
import { activeStylePresetIdChanged } from 'features/stylePresets/store/stylePresetSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import type { MouseEvent } from 'react';
|
||||
@ -30,19 +26,18 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI
|
||||
const { name, preset_data } = preset;
|
||||
const { positive_prompt, negative_prompt } = preset_data;
|
||||
|
||||
dispatch(
|
||||
prefilledFormDataChanged({
|
||||
$stylePresetModalState.set({
|
||||
prefilledFormData: {
|
||||
name,
|
||||
positivePrompt: positive_prompt || '',
|
||||
negativePrompt: negative_prompt || '',
|
||||
imageUrl: preset.image,
|
||||
})
|
||||
);
|
||||
|
||||
dispatch(updatingStylePresetIdChanged(preset.id));
|
||||
dispatch(isModalOpenChanged(true));
|
||||
},
|
||||
updatingStylePresetId: preset.id,
|
||||
isModalOpen: true,
|
||||
});
|
||||
},
|
||||
[dispatch, preset]
|
||||
[preset]
|
||||
);
|
||||
|
||||
const handleClickApply = useCallback(async () => {
|
||||
@ -64,19 +59,18 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI
|
||||
const { name, preset_data } = preset;
|
||||
const { positive_prompt, negative_prompt } = preset_data;
|
||||
|
||||
dispatch(
|
||||
prefilledFormDataChanged({
|
||||
$stylePresetModalState.set({
|
||||
prefilledFormData: {
|
||||
name: `${name} (${t('common.copy')})`,
|
||||
positivePrompt: positive_prompt || '',
|
||||
negativePrompt: negative_prompt || '',
|
||||
imageUrl: preset.image,
|
||||
})
|
||||
);
|
||||
|
||||
dispatch(updatingStylePresetIdChanged(null));
|
||||
dispatch(isModalOpenChanged(true));
|
||||
},
|
||||
updatingStylePresetId: null,
|
||||
isModalOpen: true,
|
||||
});
|
||||
},
|
||||
[dispatch, preset, t]
|
||||
[preset, t]
|
||||
);
|
||||
|
||||
const handleDeletePreset = useCallback(async () => {
|
||||
|
@ -1,11 +1,7 @@
|
||||
import { Flex, IconButton, Text } from '@invoke-ai/ui-library';
|
||||
import { EMPTY_ARRAY } from 'app/store/constants';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import {
|
||||
isModalOpenChanged,
|
||||
prefilledFormDataChanged,
|
||||
updatingStylePresetIdChanged,
|
||||
} from 'features/stylePresets/store/stylePresetModalSlice';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiPlusBold } from 'react-icons/pi';
|
||||
@ -40,14 +36,15 @@ export const StylePresetMenu = () => {
|
||||
},
|
||||
});
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleClickAddNew = useCallback(() => {
|
||||
dispatch(prefilledFormDataChanged(null));
|
||||
dispatch(updatingStylePresetIdChanged(null));
|
||||
dispatch(isModalOpenChanged(true));
|
||||
}, [dispatch]);
|
||||
$stylePresetModalState.set({
|
||||
prefilledFormData: null,
|
||||
updatingStylePresetId: null,
|
||||
isModalOpen: true,
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Flex flexDir="column" gap={2} padding={3} layerStyle="second" borderRadius="base">
|
||||
|
@ -8,13 +8,9 @@ import {
|
||||
ModalOverlay,
|
||||
Spinner,
|
||||
} from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { convertImageUrlToBlob } from 'common/util/convertImageUrlToBlob';
|
||||
import {
|
||||
isModalOpenChanged,
|
||||
prefilledFormDataChanged,
|
||||
updatingStylePresetIdChanged,
|
||||
} from 'features/stylePresets/store/stylePresetModalSlice';
|
||||
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||
import type { PrefilledFormData } from 'features/stylePresets/store/types';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -24,21 +20,22 @@ import { StylePresetForm } from './StylePresetForm';
|
||||
|
||||
export const StylePresetModal = () => {
|
||||
const [formData, setFormData] = useState<StylePresetFormData | null>(null);
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const isModalOpen = useAppSelector((s) => s.stylePresetModal.isModalOpen);
|
||||
const updatingStylePresetId = useAppSelector((s) => s.stylePresetModal.updatingStylePresetId);
|
||||
const prefilledFormData = useAppSelector((s) => s.stylePresetModal.prefilledFormData);
|
||||
const stylePresetModalState = useStore($stylePresetModalState);
|
||||
|
||||
const modalTitle = useMemo(() => {
|
||||
return updatingStylePresetId ? t('stylePresets.updatePromptTemplate') : t('stylePresets.createPromptTemplate');
|
||||
}, [updatingStylePresetId, t]);
|
||||
return stylePresetModalState.updatingStylePresetId
|
||||
? t('stylePresets.updatePromptTemplate')
|
||||
: t('stylePresets.createPromptTemplate');
|
||||
}, [stylePresetModalState.updatingStylePresetId, t]);
|
||||
|
||||
const handleCloseModal = useCallback(() => {
|
||||
dispatch(prefilledFormDataChanged(null));
|
||||
dispatch(updatingStylePresetIdChanged(null));
|
||||
dispatch(isModalOpenChanged(false));
|
||||
}, [dispatch]);
|
||||
$stylePresetModalState.set({
|
||||
prefilledFormData: null,
|
||||
updatingStylePresetId: null,
|
||||
isModalOpen: false,
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setFormData(null);
|
||||
@ -62,18 +59,18 @@ export const StylePresetModal = () => {
|
||||
});
|
||||
}
|
||||
};
|
||||
convertImageToBlob(prefilledFormData);
|
||||
}, [prefilledFormData]);
|
||||
convertImageToBlob(stylePresetModalState.prefilledFormData);
|
||||
}, [stylePresetModalState.prefilledFormData]);
|
||||
|
||||
return (
|
||||
<Modal isOpen={isModalOpen} onClose={handleCloseModal} isCentered size="2xl">
|
||||
<Modal isOpen={stylePresetModalState.isModalOpen} onClose={handleCloseModal} isCentered size="2xl">
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>{modalTitle}</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody display="flex" flexDir="column" gap={4}>
|
||||
{!prefilledFormData || formData ? (
|
||||
<StylePresetForm updatingStylePresetId={updatingStylePresetId} formData={formData} />
|
||||
{!stylePresetModalState.prefilledFormData || formData ? (
|
||||
<StylePresetForm updatingStylePresetId={stylePresetModalState.updatingStylePresetId} formData={formData} />
|
||||
) : (
|
||||
<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