diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json
index c44298de665..8fc600d6c96 100644
--- a/invokeai/frontend/web/public/locales/en.json
+++ b/invokeai/frontend/web/public/locales/en.json
@@ -1643,19 +1643,16 @@
},
"upscaling": {
"creativity": "Creativity",
- "currentImageSize": "Current Image Size",
- "outputImageSize": "Output Image Size",
- "sharpness": "Sharpness",
"structure": "Structure",
- "toInstall": "to install",
- "upscaleModel": "Upcale Model",
+ "upscaleModel": "Upscale Model",
"scale": "Scale",
- "visit": "Visit",
- "warningNoMainModel": "a model",
- "warningNoTile": "a {{base_model}} tile controlnet required by this feature",
- "warningNoTileOrUpscaleModel": "an upscaler model and {{base_model}} tile controlnet required by this feature",
- "warningNoUpscaleModel": "an upscaler model required by this feature",
- "upscalingFromTo": "Upscaling from {{from}} to {{to}}"
+ "missingModelsWarning": "Visit the Model Manager to install the required models:",
+ "mainModelDesc": "Main model (SD1.5 or SDXL architecture)",
+ "tileControlNetModelDesc": "Tile ControlNet model for the chosen main model architecture",
+ "upscaleModelDesc": "Upscale (image to image) model",
+ "missingUpscaleInitialImage": "Missing initial image for upscaling",
+ "missingUpscaleModel": "Missing upscale model",
+ "missingTileControlNetModel": "No valid tile ControlNet models installed"
},
"ui": {
"tabs": {
diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedUpscale.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedUpscale.ts
index f51f9e75647..dc870a9f8b5 100644
--- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedUpscale.ts
+++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedUpscale.ts
@@ -2,7 +2,7 @@ import { enqueueRequested } from 'app/store/actions';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { isImageViewerOpenChanged } from 'features/gallery/store/gallerySlice';
import { prepareLinearUIBatch } from 'features/nodes/util/graph/buildLinearBatchConfig';
-import { buildMultidiffusionUpscsaleGraph } from 'features/nodes/util/graph/buildMultidiffusionUpscaleGraph';
+import { buildMultidiffusionUpscaleGraph } from 'features/nodes/util/graph/buildMultidiffusionUpscaleGraph';
import { queueApi } from 'services/api/endpoints/queue';
export const addEnqueueRequestedUpscale = (startAppListening: AppStartListening) => {
@@ -14,7 +14,7 @@ export const addEnqueueRequestedUpscale = (startAppListening: AppStartListening)
const { shouldShowProgressInViewer } = state.ui;
const { prepend } = action.payload;
- const graph = await buildMultidiffusionUpscsaleGraph(state);
+ const graph = await buildMultidiffusionUpscaleGraph(state);
const batchConfig = prepareLinearUIBatch(state, graph, prepend);
diff --git a/invokeai/frontend/web/src/common/hooks/useIsReadyToEnqueue.ts b/invokeai/frontend/web/src/common/hooks/useIsReadyToEnqueue.ts
index 9c465bb3cc1..ba2117f2075 100644
--- a/invokeai/frontend/web/src/common/hooks/useIsReadyToEnqueue.ts
+++ b/invokeai/frontend/web/src/common/hooks/useIsReadyToEnqueue.ts
@@ -208,14 +208,13 @@ const createSelector = (templates: Templates) =>
});
} else if (activeTabName === 'upscaling') {
if (!upscale.upscaleInitialImage) {
- reasons.push({ content: 'No Initial image' });
+ reasons.push({ content: i18n.t('upscaling.missingUpscaleInitialImage') });
}
if (!upscale.upscaleModel) {
- reasons.push({ content: 'No upscale model selected' });
+ reasons.push({ content: i18n.t('upscaling.missingUpscaleModel') });
}
-
if (!upscale.tileControlnetModel) {
- reasons.push({ content: 'No valid tile controlnet available' });
+ reasons.push({ content: i18n.t('upscaling.missingTileControlNetModel') });
}
} else {
// Handling for all other tabs
diff --git a/invokeai/frontend/web/src/features/modelManagerV2/hooks/useStarterModelsToast.tsx b/invokeai/frontend/web/src/features/modelManagerV2/hooks/useStarterModelsToast.tsx
index 6da320aa0b7..101394f85ac 100644
--- a/invokeai/frontend/web/src/features/modelManagerV2/hooks/useStarterModelsToast.tsx
+++ b/invokeai/frontend/web/src/features/modelManagerV2/hooks/useStarterModelsToast.tsx
@@ -1,5 +1,6 @@
import { Button, Text, useToast } from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks';
+import { $installModelsTab } from 'features/modelManagerV2/subpanels/InstallModels';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { setActiveTab } from 'features/ui/store/uiSlice';
import { useCallback, useEffect, useState } from 'react';
@@ -44,6 +45,7 @@ const ToastDescription = () => {
const onClick = useCallback(() => {
dispatch(setActiveTab('models'));
+ $installModelsTab.set(3);
toast.close(TOAST_ID);
}, [dispatch, toast]);
diff --git a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StartModelsResultItem.tsx b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StartModelsResultItem.tsx
index 98e1e396404..754cbbd25ab 100644
--- a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StartModelsResultItem.tsx
+++ b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StartModelsResultItem.tsx
@@ -30,7 +30,7 @@ export const StarterModelsResultItem = ({ result }: Props) => {
- {result.type.replace('_', ' ')}
+ {result.type.replaceAll('_', ' ')}
{result.name}
diff --git a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StarterModelsResults.tsx b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StarterModelsResults.tsx
index 7aa05af3004..ccaa29d5e25 100644
--- a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StarterModelsResults.tsx
+++ b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StarterModelsResults.tsx
@@ -18,14 +18,17 @@ export const StarterModelsResults = ({ results }: StarterModelsResultsProps) =>
const filteredResults = useMemo(() => {
return results.filter((result) => {
- const name = result.name.toLowerCase();
- const type = result.type.toLowerCase();
- return name.includes(searchTerm.toLowerCase()) || type.includes(searchTerm.toLowerCase());
+ const trimmedSearchTerm = searchTerm.trim().toLowerCase();
+ const matchStrings = [result.name.toLowerCase(), result.type.toLowerCase(), result.description.toLowerCase()];
+ if (result.type === 'spandrel_image_to_image') {
+ matchStrings.push('upscale');
+ }
+ return matchStrings.some((matchString) => matchString.includes(trimmedSearchTerm));
});
}, [results, searchTerm]);
const handleSearch: ChangeEventHandler = useCallback((e) => {
- setSearchTerm(e.target.value.trim());
+ setSearchTerm(e.target.value);
}, []);
const clearSearch = useCallback(() => {
diff --git a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/InstallModels.tsx b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/InstallModels.tsx
index d09ab67fa4a..b5110722d5c 100644
--- a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/InstallModels.tsx
+++ b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/InstallModels.tsx
@@ -1,28 +1,28 @@
import { Box, Flex, Heading, Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library';
+import { useStore } from '@nanostores/react';
import { StarterModelsForm } from 'features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StarterModelsForm';
-import { useMemo } from 'react';
+import { atom } from 'nanostores';
+import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
-import { useMainModels } from 'services/api/hooks/modelsByType';
import { HuggingFaceForm } from './AddModelPanel/HuggingFaceFolder/HuggingFaceForm';
import { InstallModelForm } from './AddModelPanel/InstallModelForm';
import { ModelInstallQueue } from './AddModelPanel/ModelInstallQueue/ModelInstallQueue';
import { ScanModelsForm } from './AddModelPanel/ScanFolder/ScanFolderForm';
+export const $installModelsTab = atom(0);
+
export const InstallModels = () => {
const { t } = useTranslation();
- const [mainModels, { data }] = useMainModels();
- const defaultIndex = useMemo(() => {
- if (data && mainModels.length) {
- return 0;
- }
- return 3;
- }, [data, mainModels.length]);
+ const index = useStore($installModelsTab);
+ const onChange = useCallback((index: number) => {
+ $installModelsTab.set(index);
+ }, []);
return (
{t('modelManager.addModel')}
-
+
{t('modelManager.urlOrLocalPath')}
{t('modelManager.huggingFace')}
diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/buildMultidiffusionUpscaleGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/buildMultidiffusionUpscaleGraph.ts
index 638ebf2fb2f..1516a3fae3b 100644
--- a/invokeai/frontend/web/src/features/nodes/util/graph/buildMultidiffusionUpscaleGraph.ts
+++ b/invokeai/frontend/web/src/features/nodes/util/graph/buildMultidiffusionUpscaleGraph.ts
@@ -24,7 +24,7 @@ import { addLoRAs } from './generation/addLoRAs';
import { addSDXLLoRas } from './generation/addSDXLLoRAs';
import { getBoardField, getSDXLStylePrompts } from './graphBuilderUtils';
-export const buildMultidiffusionUpscsaleGraph = async (state: RootState): Promise => {
+export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise => {
const { model, cfgScale: cfg_scale, scheduler, steps, vaePrecision, seed, vae } = state.generation;
const { positivePrompt, negativePrompt } = state.controlLayers.present;
const { upscaleModel, upscaleInitialImage, structure, creativity, tileControlnetModel, scale } = state.upscale;
@@ -213,7 +213,7 @@ export const buildMultidiffusionUpscsaleGraph = async (state: RootState): Promis
control_model: tileControlnetModel,
control_mode: 'balanced',
resize_mode: 'just_resize',
- control_weight: (structure + 10) * 0.0325 + 0.15 + 0.15,
+ control_weight: (structure + 10) * 0.0325 + 0.3,
begin_step_percent: 0,
end_step_percent: (structure + 10) * 0.025 + 0.3,
});
@@ -226,7 +226,7 @@ export const buildMultidiffusionUpscsaleGraph = async (state: RootState): Promis
control_model: tileControlnetModel,
control_mode: 'balanced',
resize_mode: 'just_resize',
- control_weight: ((structure + 10) * 0.0325 + 0.15) * 0.15,
+ control_weight: ((structure + 10) * 0.0325 + 0.15) * 0.45,
begin_step_percent: (structure + 10) * 0.025 + 0.3,
end_step_percent: 0.85,
});
diff --git a/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/MultidiffusionWarning.tsx b/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/MultidiffusionWarning.tsx
index 84b8432aec2..f3e2aa66048 100644
--- a/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/MultidiffusionWarning.tsx
+++ b/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/MultidiffusionWarning.tsx
@@ -1,10 +1,10 @@
-import { Flex, Link, Text } from '@invoke-ai/ui-library';
+import { Button, Flex, ListItem, Text, UnorderedList } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
+import { $installModelsTab } from 'features/modelManagerV2/subpanels/InstallModels';
import { tileControlnetModelChanged } from 'features/parameters/store/upscaleSlice';
-import { MODEL_TYPE_SHORT_MAP } from 'features/parameters/types/constants';
import { setActiveTab } from 'features/ui/store/uiSlice';
import { useCallback, useEffect, useMemo } from 'react';
-import { useTranslation } from 'react-i18next';
+import { Trans, useTranslation } from 'react-i18next';
import { useControlNetModels } from 'services/api/hooks/modelsByType';
export const MultidiffusionWarning = () => {
@@ -23,38 +23,46 @@ export const MultidiffusionWarning = () => {
dispatch(tileControlnetModelChanged(validModel || null));
}, [model?.base, modelConfigs, dispatch]);
- const warningText = useMemo(() => {
+ const warnings = useMemo(() => {
+ const _warnings: string[] = [];
if (!model) {
- return t('upscaling.warningNoMainModel');
+ _warnings.push(t('upscaling.mainModelDesc'));
}
- if (!upscaleModel && !tileControlnetModel) {
- return t('upscaling.warningNoTileOrUpscaleModel', { base_model: MODEL_TYPE_SHORT_MAP[model.base] });
+ if (!tileControlnetModel) {
+ _warnings.push(t('upscaling.tileControlNetModelDesc'));
}
if (!upscaleModel) {
- return t('upscaling.warningNoUpscaleModel');
- }
- if (!tileControlnetModel) {
- return t('upscaling.warningNoTile', { base_model: MODEL_TYPE_SHORT_MAP[model.base] });
+ _warnings.push(t('upscaling.upscaleModelDesc'));
}
+ return _warnings;
}, [model, upscaleModel, tileControlnetModel, t]);
const handleGoToModelManager = useCallback(() => {
dispatch(setActiveTab('models'));
+ $installModelsTab.set(3);
}, [dispatch]);
- if (!warningText || isLoading || !shouldShowButton) {
- return <>>;
+ if (!warnings.length || isLoading || !shouldShowButton) {
+ return null;
}
return (
-
-
- {t('upscaling.visit')}{' '}
-
- {t('modelManager.modelManager')}
- {' '}
- {t('upscaling.toInstall')} {warningText}.
+
+
+
+ ),
+ }}
+ />
+
+ {warnings.map((warning) => (
+ {warning}
+ ))}
+
);
};
diff --git a/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSettingsAccordion.tsx b/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSettingsAccordion.tsx
index c7ac339a518..6002b76521d 100644
--- a/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSettingsAccordion.tsx
+++ b/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSettingsAccordion.tsx
@@ -49,14 +49,16 @@ export const UpscaleSettingsAccordion = memo(() => {
return (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+