diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index f7dde4bd302..5f84b849380 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -294,6 +294,11 @@ "disableFailed": "Problem Disabling Invocation Cache", "useCache": "Use Cache" }, + "modelCache": { + "clear": "Clear Model Cache", + "clearSucceeded": "Model Cache Cleared", + "clearFailed": "Problem Clearing Model Cache" + }, "gallery": { "gallery": "Gallery", "alwaysShowImageSizeBadge": "Always Show Image Size Badge", diff --git a/invokeai/frontend/web/src/app/types/invokeai.ts b/invokeai/frontend/web/src/app/types/invokeai.ts index 39b9fea1fa4..9ea267800b3 100644 --- a/invokeai/frontend/web/src/app/types/invokeai.ts +++ b/invokeai/frontend/web/src/app/types/invokeai.ts @@ -23,6 +23,7 @@ export type AppFeature = | 'pauseQueue' | 'resumeQueue' | 'invocationCache' + | 'modelCache' | 'bulkDownload' | 'starterModels' | 'hfToken'; diff --git a/invokeai/frontend/web/src/features/queue/components/ClearModelCacheButton.tsx b/invokeai/frontend/web/src/features/queue/components/ClearModelCacheButton.tsx new file mode 100644 index 00000000000..6c11a9cdc67 --- /dev/null +++ b/invokeai/frontend/web/src/features/queue/components/ClearModelCacheButton.tsx @@ -0,0 +1,39 @@ +import { Button } from '@invoke-ai/ui-library'; +import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; +import { toast } from 'features/toast/toast'; +import { memo, useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useEmptyModelCacheMutation } from 'services/api/endpoints/models'; + +const ClearModelCacheButton = () => { + const isModelCacheEnabled = useFeatureStatus('modelCache'); + const [emptyModelCache, { isLoading }] = useEmptyModelCacheMutation(); + const { t } = useTranslation(); + + const handleClearCache = useCallback(async () => { + try { + await emptyModelCache().unwrap(); + toast({ + status: 'success', + title: t('modelCache.clearSucceeded'), + }); + } catch (error) { + toast({ + status: 'error', + title: t('modelCache.clearFailed'), + }); + } + }, [emptyModelCache, t]); + + if (!isModelCacheEnabled) { + return <>; + } + + return ( + + ); +}; + +export default memo(ClearModelCacheButton); diff --git a/invokeai/frontend/web/src/features/queue/components/QueueTabQueueControls.tsx b/invokeai/frontend/web/src/features/queue/components/QueueTabQueueControls.tsx index 3aed2f237a1..59bd02a7371 100644 --- a/invokeai/frontend/web/src/features/queue/components/QueueTabQueueControls.tsx +++ b/invokeai/frontend/web/src/features/queue/components/QueueTabQueueControls.tsx @@ -1,7 +1,9 @@ +/* eslint-disable i18next/no-literal-string */ import { ButtonGroup, Flex } from '@invoke-ai/ui-library'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { memo } from 'react'; +import ClearModelCacheButton from './ClearModelCacheButton'; import ClearQueueButton from './ClearQueueButton'; import PauseProcessorButton from './PauseProcessorButton'; import PruneQueueButton from './PruneQueueButton'; @@ -11,19 +13,22 @@ const QueueTabQueueControls = () => { const isPauseEnabled = useFeatureStatus('pauseQueue'); const isResumeEnabled = useFeatureStatus('resumeQueue'); return ( - - {isPauseEnabled || isResumeEnabled ? ( + + + {isPauseEnabled || isResumeEnabled ? ( + + {isResumeEnabled ? : <>} + {isPauseEnabled ? : <>} + + ) : ( + <> + )} - {isResumeEnabled ? : <>} - {isPauseEnabled ? : <>} + + - ) : ( - <> - )} - - - - + + ); }; diff --git a/invokeai/frontend/web/src/services/api/endpoints/models.ts b/invokeai/frontend/web/src/services/api/endpoints/models.ts index 3180e932b76..1b2421c4cea 100644 --- a/invokeai/frontend/web/src/services/api/endpoints/models.ts +++ b/invokeai/frontend/web/src/services/api/endpoints/models.ts @@ -275,6 +275,9 @@ export const modelsApi = api.injectEndpoints({ } }, }), + emptyModelCache: build.mutation({ + query: () => ({ url: buildModelsUrl('empty_model_cache'), method: 'POST' }), + }), }), }); @@ -295,6 +298,7 @@ export const { useGetStarterModelsQuery, useGetHFTokenStatusQuery, useSetHFTokenMutation, + useEmptyModelCacheMutation, } = modelsApi; export const selectModelConfigsQuery = modelsApi.endpoints.getModelConfigs.select();