diff --git a/invokeai/frontend/public/locales/modelmanager/en.json b/invokeai/frontend/public/locales/modelmanager/en.json index ad320d0969..71c69f2fbe 100644 --- a/invokeai/frontend/public/locales/modelmanager/en.json +++ b/invokeai/frontend/public/locales/modelmanager/en.json @@ -63,5 +63,16 @@ "formMessageDiffusersModelLocation": "Diffusers Model Location", "formMessageDiffusersModelLocationDesc": "Please enter at least one.", "formMessageDiffusersVAELocation": "VAE Location", - "formMessageDiffusersVAELocationDesc": "If not provided, InvokeAI will look for the VAE file inside the model location given above." + "formMessageDiffusersVAELocationDesc": "If not provided, InvokeAI will look for the VAE file inside the model location given above.", + "convert": "Convert", + "convertToDiffusers": "Convert To Diffusers", + "convertToDiffusersHelpText1": "This model will be converted to the 🧨 Diffusers format.", + "convertToDiffusersHelpText2": "This process will replace your Model Manager entry with the Diffusers version of the same model.", + "convertToDiffusersHelpText3": "Your checkpoint file on the disk will NOT be deleted or modified in anyway. You can add your checkpoint to the Model Manager again if you want to.", + "convertToDiffusersHelpText4": "This is a one time process only. It might take around 30s-60s depending on the specifications of your computer.", + "convertToDiffusersHelpText5": "This process will create a Diffusers version of this model in the same directory as your checkpoint. Please make sure you have enough disk space.", + "convertToDiffusersHelpText6": "Do you wish to convert this model?", + "inpaintingModel": "Inpainting Model", + "customConfig": "Custom Config", + "pathToCustomConfig": "Path To Custom Config" } diff --git a/invokeai/frontend/src/app/invokeai.d.ts b/invokeai/frontend/src/app/invokeai.d.ts index 4c978abd80..652c651bd5 100644 --- a/invokeai/frontend/src/app/invokeai.d.ts +++ b/invokeai/frontend/src/app/invokeai.d.ts @@ -219,6 +219,11 @@ export declare type InvokeDiffusersModelConfigProps = { }; }; +export declare type InvokeModelConversionProps = { + name: string; + is_inpainting: boolean; +}; + /** * These types type data received from the server via socketio. */ diff --git a/invokeai/frontend/src/app/socketio/actions.ts b/invokeai/frontend/src/app/socketio/actions.ts index 7f0dbcfb8d..e0a8dbc9e4 100644 --- a/invokeai/frontend/src/app/socketio/actions.ts +++ b/invokeai/frontend/src/app/socketio/actions.ts @@ -38,9 +38,10 @@ export const addNewModel = createAction< export const deleteModel = createAction('socketio/deleteModel'); -export const convertToDiffusers = createAction( - 'socketio/convertToDiffusers' -); +export const convertToDiffusers = + createAction( + 'socketio/convertToDiffusers' + ); export const requestModelChange = createAction( 'socketio/requestModelChange' diff --git a/invokeai/frontend/src/features/system/components/ModelManager/CheckpointModelEdit.tsx b/invokeai/frontend/src/features/system/components/ModelManager/CheckpointModelEdit.tsx index f189dbd964..4d258834ef 100644 --- a/invokeai/frontend/src/features/system/components/ModelManager/CheckpointModelEdit.tsx +++ b/invokeai/frontend/src/features/system/components/ModelManager/CheckpointModelEdit.tsx @@ -27,6 +27,7 @@ import type { InvokeModelConfigProps } from 'app/invokeai'; import type { RootState } from 'app/store'; import type { FieldInputProps, FormikProps } from 'formik'; import { isEqual, pickBy } from 'lodash'; +import ModelConvert from './ModelConvert'; const selector = createSelector( [systemSelector], @@ -101,10 +102,11 @@ export default function CheckpointModelEdit() { return openModel ? ( - + {openModel} + state.system.model_list + ); + + const retrievedModel = model_list[model]; + + const [isInpainting, setIsInpainting] = useState(false); + const [customConfig, setIsCustomConfig] = useState(false); + + const dispatch = useAppDispatch(); + const { t } = useTranslation(); + + const isProcessing = useAppSelector( + (state: RootState) => state.system.isProcessing + ); + + const isConnected = useAppSelector( + (state: RootState) => state.system.isConnected + ); + + useEffect(() => { + setIsInpainting(false); + setIsCustomConfig(false); + }, [model]); + + const modelConvertHandler = () => { + dispatch(setIsProcessing(true)); + dispatch(convertToDiffusers({ name: model, is_inpainting: isInpainting })); + }; + + return ( + + 🧨 {t('modelmanager:convertToDiffusers')} + + } + > + + {t('modelmanager:convertToDiffusersHelpText1')} + + {t('modelmanager:convertToDiffusersHelpText2')} + {t('modelmanager:convertToDiffusersHelpText3')} + {t('modelmanager:convertToDiffusersHelpText4')} + {t('modelmanager:convertToDiffusersHelpText5')} + + {t('modelmanager:convertToDiffusersHelpText6')} + + + { + setIsInpainting(!isInpainting); + setIsCustomConfig(false); + }} + label={t('modelmanager:inpaintingModel')} + isDisabled={customConfig} + /> + { + setIsCustomConfig(!customConfig); + setIsInpainting(false); + }} + label={t('modelmanager:customConfig')} + isDisabled={isInpainting} + /> + + {customConfig && ( + + + {t('modelmanager:pathToCustomConfig')} + + + + )} + + + + ); +} diff --git a/invokeai/frontend/src/features/system/components/ModelManager/ModelList.tsx b/invokeai/frontend/src/features/system/components/ModelManager/ModelList.tsx index 5f7e45197a..fc2adae357 100644 --- a/invokeai/frontend/src/features/system/components/ModelManager/ModelList.tsx +++ b/invokeai/frontend/src/features/system/components/ModelManager/ModelList.tsx @@ -85,7 +85,6 @@ const ModelList = () => { name={model.name} status={model.status} description={model.description} - format={model.format} /> ); if (model.format === isSelectedFilter) { @@ -95,7 +94,6 @@ const ModelList = () => { name={model.name} status={model.status} description={model.description} - format={model.format} /> ); } @@ -107,7 +105,6 @@ const ModelList = () => { name={model.name} status={model.status} description={model.description} - format={model.format} /> ); } else { @@ -117,7 +114,6 @@ const ModelList = () => { name={model.name} status={model.status} description={model.description} - format={model.format} /> ); } diff --git a/invokeai/frontend/src/features/system/components/ModelManager/ModelListItem.tsx b/invokeai/frontend/src/features/system/components/ModelManager/ModelListItem.tsx index 671465ed31..2b712d969a 100644 --- a/invokeai/frontend/src/features/system/components/ModelManager/ModelListItem.tsx +++ b/invokeai/frontend/src/features/system/components/ModelManager/ModelListItem.tsx @@ -1,27 +1,18 @@ import { DeleteIcon, EditIcon } from '@chakra-ui/icons'; import { Box, Button, Flex, Spacer, Text, Tooltip } from '@chakra-ui/react'; import { ModelStatus } from 'app/invokeai'; -import { - convertToDiffusers, - deleteModel, - requestModelChange, -} from 'app/socketio/actions'; +import { deleteModel, requestModelChange } from 'app/socketio/actions'; import { RootState } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import IAIAlertDialog from 'common/components/IAIAlertDialog'; import IAIIconButton from 'common/components/IAIIconButton'; -import { - setIsProcessing, - setOpenModel, -} from 'features/system/store/systemSlice'; +import { setOpenModel } from 'features/system/store/systemSlice'; import { useTranslation } from 'react-i18next'; -import { MdSwitchLeft } from 'react-icons/md'; type ModelListItemProps = { name: string; status: ModelStatus; description: string; - format: string | undefined; }; export default function ModelListItem(props: ModelListItemProps) { @@ -37,7 +28,7 @@ export default function ModelListItem(props: ModelListItemProps) { const dispatch = useAppDispatch(); - const { name, status, description, format } = props; + const { name, status, description } = props; const handleChangeModel = () => { dispatch(requestModelChange(name)); @@ -47,11 +38,6 @@ export default function ModelListItem(props: ModelListItemProps) { dispatch(setOpenModel(name)); }; - const convertModelHandler = () => { - dispatch(setIsProcessing(true)); - dispatch(convertToDiffusers(name)); - }; - const handleModelDelete = () => { dispatch(deleteModel(name)); dispatch(setOpenModel(null)); @@ -106,16 +92,6 @@ export default function ModelListItem(props: ModelListItemProps) { isDisabled={status === 'active' || isProcessing || !isConnected} className=" modal-close-btn" /> - {format !== 'diffusers' && ( - } - size={'sm'} - onClick={convertModelHandler} - aria-label="Convert Model" - isDisabled={status === 'active' || isProcessing || !isConnected} - className=" modal-close-btn" - /> - )}