translations and lint fix

This commit is contained in:
Mary Hipp 2024-07-18 20:26:17 -04:00 committed by psychedelicious
parent 4a09cc57be
commit 9e3412d776
22 changed files with 293 additions and 251 deletions

View File

@ -1027,6 +1027,7 @@
"imageActions": "Image Actions", "imageActions": "Image Actions",
"sendToImg2Img": "Send to Image to Image", "sendToImg2Img": "Send to Image to Image",
"sendToUnifiedCanvas": "Send To Unified Canvas", "sendToUnifiedCanvas": "Send To Unified Canvas",
"sendToUpscale": "Send To Upscale",
"showOptionsPanel": "Show Side Panel (O or T)", "showOptionsPanel": "Show Side Panel (O or T)",
"shuffle": "Shuffle Seed", "shuffle": "Shuffle Seed",
"steps": "Steps", "steps": "Steps",
@ -1640,6 +1641,22 @@
"layers_one": "Layer", "layers_one": "Layer",
"layers_other": "Layers" "layers_other": "Layers"
}, },
"upscaling": {
"creativity": "Creativity",
"currentImageSize": "Current Image Size",
"outputImageSize": "Output Image Size",
"sharpness": "Sharpness",
"structure": "Structure",
"tiledVAE": "Tiled VAE",
"toInstall": "to install",
"upscaleModel": "Upcale Model",
"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",
"x": "x"
},
"ui": { "ui": {
"tabs": { "tabs": {
"generation": "Generation", "generation": "Generation",

View File

@ -86,7 +86,7 @@ addGalleryOffsetChangedListener(startAppListening);
addEnqueueRequestedCanvasListener(startAppListening); addEnqueueRequestedCanvasListener(startAppListening);
addEnqueueRequestedNodes(startAppListening); addEnqueueRequestedNodes(startAppListening);
addEnqueueRequestedLinear(startAppListening); addEnqueueRequestedLinear(startAppListening);
addEnqueueRequestedUpscale(startAppListening) addEnqueueRequestedUpscale(startAppListening);
addAnyEnqueuedListener(startAppListening); addAnyEnqueuedListener(startAppListening);
addBatchEnqueuedListener(startAppListening); addBatchEnqueuedListener(startAppListening);

View File

@ -10,13 +10,11 @@ export const addEnqueueRequestedUpscale = (startAppListening: AppStartListening)
predicate: (action): action is ReturnType<typeof enqueueRequested> => predicate: (action): action is ReturnType<typeof enqueueRequested> =>
enqueueRequested.match(action) && action.payload.tabName === 'upscaling', enqueueRequested.match(action) && action.payload.tabName === 'upscaling',
effect: async (action, { getState, dispatch }) => { effect: async (action, { getState, dispatch }) => {
const state = getState(); const state = getState();
const { shouldShowProgressInViewer } = state.ui; const { shouldShowProgressInViewer } = state.ui;
const { prepend } = action.payload; const { prepend } = action.payload;
const graph = await buildMultidiffusionUpscsaleGraph(state);
const graph = await buildMultidiffusionUpscsaleGraph(state)
const batchConfig = prepareLinearUIBatch(state, graph, prepend); const batchConfig = prepareLinearUIBatch(state, graph, prepend);

View File

@ -94,7 +94,7 @@ export const addImageUploadedFulfilledListener = (startAppListening: AppStartLis
dispatch(upscaleInitialImageChanged(imageDTO)); dispatch(upscaleInitialImageChanged(imageDTO));
toast({ toast({
...DEFAULT_UPLOADED_TOAST, ...DEFAULT_UPLOADED_TOAST,
description: "set as upscale initial image", description: 'set as upscale initial image',
}); });
return; return;
} }

View File

@ -18,7 +18,12 @@ import { forEach } from 'lodash-es';
import type { Logger } from 'roarr'; import type { Logger } from 'roarr';
import { modelConfigsAdapterSelectors, modelsApi } from 'services/api/endpoints/models'; import { modelConfigsAdapterSelectors, modelsApi } from 'services/api/endpoints/models';
import type { AnyModelConfig } from 'services/api/types'; import type { AnyModelConfig } from 'services/api/types';
import { isNonRefinerMainModelConfig, isRefinerMainModelModelConfig, isSpandrelImageToImageModelConfig, isVAEModelConfig } from 'services/api/types'; import {
isNonRefinerMainModelConfig,
isRefinerMainModelModelConfig,
isSpandrelImageToImageModelConfig,
isVAEModelConfig,
} from 'services/api/types';
export const addModelsLoadedListener = (startAppListening: AppStartListening) => { export const addModelsLoadedListener = (startAppListening: AppStartListening) => {
startAppListening({ startAppListening({
@ -193,10 +198,9 @@ const handleSpandrelImageToImageModels: ModelHandler = (models, state, dispatch,
const firstModel = upscaleModels[0]; const firstModel = upscaleModels[0];
if (firstModel) { if (firstModel) {
dispatch(upscaleModelChanged(firstModel)) dispatch(upscaleModelChanged(firstModel));
return return;
} }
dispatch(upscaleModelChanged(null)) dispatch(upscaleModelChanged(null));
}; };

View File

@ -70,7 +70,7 @@ const allReducers = {
[controlLayersSlice.name]: undoable(controlLayersSlice.reducer, controlLayersUndoableConfig), [controlLayersSlice.name]: undoable(controlLayersSlice.reducer, controlLayersUndoableConfig),
[workflowSettingsSlice.name]: workflowSettingsSlice.reducer, [workflowSettingsSlice.name]: workflowSettingsSlice.reducer,
[api.reducerPath]: api.reducer, [api.reducerPath]: api.reducer,
[upscaleSlice.name]: upscaleSlice.reducer [upscaleSlice.name]: upscaleSlice.reducer,
}; };
const rootReducer = combineReducers(allReducers); const rootReducer = combineReducers(allReducers);
@ -116,7 +116,7 @@ const persistConfigs: { [key in keyof typeof allReducers]?: PersistConfig } = {
[hrfPersistConfig.name]: hrfPersistConfig, [hrfPersistConfig.name]: hrfPersistConfig,
[controlLayersPersistConfig.name]: controlLayersPersistConfig, [controlLayersPersistConfig.name]: controlLayersPersistConfig,
[workflowSettingsPersistConfig.name]: workflowSettingsPersistConfig, [workflowSettingsPersistConfig.name]: workflowSettingsPersistConfig,
[upscalePersistConfig.name]: upscalePersistConfig [upscalePersistConfig.name]: upscalePersistConfig,
}; };
const unserialize: UnserializeFunction = (data, key) => { const unserialize: UnserializeFunction = (data, key) => {

View File

@ -41,9 +41,19 @@ const createSelector = (templates: Templates) =>
selectDynamicPromptsSlice, selectDynamicPromptsSlice,
selectControlLayersSlice, selectControlLayersSlice,
activeTabNameSelector, activeTabNameSelector,
selectUpscalelice selectUpscalelice,
], ],
(controlAdapters, generation, system, nodes, workflowSettings, dynamicPrompts, controlLayers, activeTabName, upscale) => { (
controlAdapters,
generation,
system,
nodes,
workflowSettings,
dynamicPrompts,
controlLayers,
activeTabName,
upscale
) => {
const { model } = generation; const { model } = generation;
const { size } = controlLayers.present; const { size } = controlLayers.present;
const { positivePrompt } = controlLayers.present; const { positivePrompt } = controlLayers.present;
@ -196,16 +206,16 @@ const createSelector = (templates: Templates) =>
reasons.push({ prefix, content }); reasons.push({ prefix, content });
} }
}); });
} else if (activeTabName === "upscaling") { } else if (activeTabName === 'upscaling') {
if (!upscale.upscaleInitialImage) { if (!upscale.upscaleInitialImage) {
reasons.push({ content: "No Initial image" }) reasons.push({ content: 'No Initial image' });
} }
if (!upscale.upscaleModel) { if (!upscale.upscaleModel) {
reasons.push({ content: "No upscale model selected" }) reasons.push({ content: 'No upscale model selected' });
} }
if (!upscale.tileControlnetModel) { if (!upscale.tileControlnetModel) {
reasons.push({ content: "No valid tile controlnet available" }) reasons.push({ content: 'No valid tile controlnet available' });
} }
} else { } else {
// Handling for all other tabs // Handling for all other tabs

View File

@ -91,8 +91,6 @@ export type SelectForCompareDropData = BaseDropData & {
}; };
}; };
export type TypesafeDroppableData = export type TypesafeDroppableData =
| CurrentImageDropData | CurrentImageDropData
| ControlAdapterDropData | ControlAdapterDropData
@ -166,11 +164,11 @@ interface DragEvent {
over: TypesafeOver | null; over: TypesafeOver | null;
} }
export interface DragStartEvent extends Pick<DragEvent, 'active'> { } export interface DragStartEvent extends Pick<DragEvent, 'active'> {}
interface DragMoveEvent extends DragEvent { } interface DragMoveEvent extends DragEvent {}
interface DragOverEvent extends DragMoveEvent { } interface DragOverEvent extends DragMoveEvent {}
export interface DragEndEvent extends DragEvent { } export interface DragEndEvent extends DragEvent {}
interface DragCancelEvent extends DragEndEvent { } interface DragCancelEvent extends DragEndEvent {}
export interface DndContextTypesafeProps export interface DndContextTypesafeProps
extends Omit<DndContextProps, 'onDragStart' | 'onDragMove' | 'onDragOver' | 'onDragEnd' | 'onDragCancel'> { extends Omit<DndContextProps, 'onDragStart' | 'onDragMove' | 'onDragOver' | 'onDragEnd' | 'onDragCancel'> {

View File

@ -192,7 +192,7 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
</MenuItem> </MenuItem>
)} )}
<MenuItem icon={<PiShareFatBold />} onClickCapture={handleSendToUpscale} id="send-to-upscale"> <MenuItem icon={<PiShareFatBold />} onClickCapture={handleSendToUpscale} id="send-to-upscale">
Send to upscale {t('parameters.sendToUpscale')}
</MenuItem> </MenuItem>
<MenuDivider /> <MenuDivider />
<MenuItem icon={<PiFoldersBold />} onClickCapture={handleChangeBoard}> <MenuItem icon={<PiFoldersBold />} onClickCapture={handleChangeBoard}>

View File

@ -4,97 +4,103 @@ import { Graph } from 'features/nodes/util/graph/generation/Graph';
import { isParamESRGANModelName } from 'features/parameters/store/postprocessingSlice'; import { isParamESRGANModelName } from 'features/parameters/store/postprocessingSlice';
import { assert } from 'tsafe'; import { assert } from 'tsafe';
import { CLIP_SKIP, CONTROL_NET_COLLECT, ESRGAN, IMAGE_TO_LATENTS, LATENTS_TO_IMAGE, MAIN_MODEL_LOADER, NEGATIVE_CONDITIONING, NOISE, POSITIVE_CONDITIONING, RESIZE, SDXL_MODEL_LOADER, TILED_MULTI_DIFFUSION_DENOISE_LATENTS, UNSHARP_MASK, VAE_LOADER } from './constants'; import {
CLIP_SKIP,
CONTROL_NET_COLLECT,
ESRGAN,
IMAGE_TO_LATENTS,
LATENTS_TO_IMAGE,
MAIN_MODEL_LOADER,
NEGATIVE_CONDITIONING,
NOISE,
POSITIVE_CONDITIONING,
RESIZE,
SDXL_MODEL_LOADER,
TILED_MULTI_DIFFUSION_DENOISE_LATENTS,
UNSHARP_MASK,
VAE_LOADER,
} from './constants';
import { addLoRAs } from './generation/addLoRAs'; import { addLoRAs } from './generation/addLoRAs';
import { addSDXLLoRas } from './generation/addSDXLLoRAs'; import { addSDXLLoRas } from './generation/addSDXLLoRAs';
import { getBoardField, getSDXLStylePrompts } from './graphBuilderUtils'; import { getBoardField, getSDXLStylePrompts } from './graphBuilderUtils';
export const buildMultidiffusionUpscsaleGraph = async (state: RootState): Promise<GraphType> => { export const buildMultidiffusionUpscsaleGraph = async (state: RootState): Promise<GraphType> => {
const { const { model, cfgScale: cfg_scale, scheduler, steps, vaePrecision, seed, vae } = state.generation;
model,
cfgScale: cfg_scale,
scheduler,
steps,
vaePrecision,
seed,
vae,
} = state.generation;
const { positivePrompt, negativePrompt } = state.controlLayers.present; const { positivePrompt, negativePrompt } = state.controlLayers.present;
const { upscaleModel, upscaleInitialImage, sharpness, structure, creativity, tiledVAE, scale, tileControlnetModel } = state.upscale; const { upscaleModel, upscaleInitialImage, sharpness, structure, creativity, tiledVAE, scale, tileControlnetModel } =
state.upscale;
assert(model, 'No model found in state'); assert(model, 'No model found in state');
assert(upscaleModel, 'No upscale model found in state'); assert(upscaleModel, 'No upscale model found in state');
assert(upscaleInitialImage, 'No initial image found in state'); assert(upscaleInitialImage, 'No initial image found in state');
assert(isParamESRGANModelName(upscaleModel.name), "Model must be valid upscale model") assert(isParamESRGANModelName(upscaleModel.name), 'Model must be valid upscale model');
assert(scale, 'Scale is required') assert(scale, 'Scale is required');
assert(tileControlnetModel, "Tile controlnet is required") assert(tileControlnetModel, 'Tile controlnet is required');
const g = new Graph() const g = new Graph();
const unsharpMaskNode1 = g.addNode({ const unsharpMaskNode1 = g.addNode({
id: `${UNSHARP_MASK}_1`, id: `${UNSHARP_MASK}_1`,
type: 'unsharp_mask', type: 'unsharp_mask',
image: upscaleInitialImage, image: upscaleInitialImage,
radius: 2, radius: 2,
strength: ((sharpness + 10) * 3.75) + 25 strength: (sharpness + 10) * 3.75 + 25,
}) });
const upscaleNode = g.addNode({ const upscaleNode = g.addNode({
id: ESRGAN, id: ESRGAN,
type: 'esrgan', type: 'esrgan',
model_name: upscaleModel.name, model_name: upscaleModel.name,
tile_size: 500 tile_size: 500,
}) });
g.addEdge(unsharpMaskNode1, 'image', upscaleNode, 'image') g.addEdge(unsharpMaskNode1, 'image', upscaleNode, 'image');
const unsharpMaskNode2 = g.addNode({ const unsharpMaskNode2 = g.addNode({
id: `${UNSHARP_MASK}_2`, id: `${UNSHARP_MASK}_2`,
type: 'unsharp_mask', type: 'unsharp_mask',
radius: 2, radius: 2,
strength: 50 strength: 50,
}) });
g.addEdge(upscaleNode, 'image', unsharpMaskNode2, 'image',) g.addEdge(upscaleNode, 'image', unsharpMaskNode2, 'image');
const resizeNode = g.addNode({ const resizeNode = g.addNode({
id: RESIZE, id: RESIZE,
type: 'img_resize', type: 'img_resize',
width: ((upscaleInitialImage.width * scale) / 8) * 8, width: ((upscaleInitialImage.width * scale) / 8) * 8,
height: ((upscaleInitialImage.height * scale) / 8) * 8, height: ((upscaleInitialImage.height * scale) / 8) * 8,
resample_mode: "lanczos", resample_mode: 'lanczos',
}) });
g.addEdge(unsharpMaskNode2, 'image', resizeNode, "image") g.addEdge(unsharpMaskNode2, 'image', resizeNode, 'image');
const noiseNode = g.addNode({ const noiseNode = g.addNode({
id: NOISE, id: NOISE,
type: "noise", type: 'noise',
seed, seed,
}) });
g.addEdge(resizeNode, 'width', noiseNode, "width") g.addEdge(resizeNode, 'width', noiseNode, 'width');
g.addEdge(resizeNode, 'height', noiseNode, "height") g.addEdge(resizeNode, 'height', noiseNode, 'height');
const i2lNode = g.addNode({ const i2lNode = g.addNode({
id: IMAGE_TO_LATENTS, id: IMAGE_TO_LATENTS,
type: "i2l", type: 'i2l',
fp32: vaePrecision === "fp32", fp32: vaePrecision === 'fp32',
tiled: tiledVAE tiled: tiledVAE,
}) });
g.addEdge(resizeNode, 'image', i2lNode, "image") g.addEdge(resizeNode, 'image', i2lNode, 'image');
const l2iNode = g.addNode({ const l2iNode = g.addNode({
type: "l2i", type: 'l2i',
id: LATENTS_TO_IMAGE, id: LATENTS_TO_IMAGE,
fp32: vaePrecision === "fp32", fp32: vaePrecision === 'fp32',
tiled: tiledVAE, tiled: tiledVAE,
board: getBoardField(state), board: getBoardField(state),
is_intermediate: false, is_intermediate: false,
});
})
const tiledMultidiffusionNode = g.addNode({ const tiledMultidiffusionNode = g.addNode({
id: TILED_MULTI_DIFFUSION_DENOISE_LATENTS, id: TILED_MULTI_DIFFUSION_DENOISE_LATENTS,
@ -105,26 +111,28 @@ export const buildMultidiffusionUpscsaleGraph = async (state: RootState): Promis
steps, steps,
cfg_scale, cfg_scale,
scheduler, scheduler,
denoising_start: (((creativity * -1) + 10) * 4.99) / 100, denoising_start: ((creativity * -1 + 10) * 4.99) / 100,
denoising_end: 1 denoising_end: 1,
}); });
let posCondNode; let negCondNode; let modelNode; let posCondNode;
let negCondNode;
let modelNode;
if (model.base === "sdxl") { if (model.base === 'sdxl') {
const { positiveStylePrompt, negativeStylePrompt } = getSDXLStylePrompts(state); const { positiveStylePrompt, negativeStylePrompt } = getSDXLStylePrompts(state);
posCondNode = g.addNode({ posCondNode = g.addNode({
type: 'sdxl_compel_prompt', type: 'sdxl_compel_prompt',
id: POSITIVE_CONDITIONING, id: POSITIVE_CONDITIONING,
prompt: positivePrompt, prompt: positivePrompt,
style: positiveStylePrompt style: positiveStylePrompt,
}); });
negCondNode = g.addNode({ negCondNode = g.addNode({
type: 'sdxl_compel_prompt', type: 'sdxl_compel_prompt',
id: NEGATIVE_CONDITIONING, id: NEGATIVE_CONDITIONING,
prompt: negativePrompt, prompt: negativePrompt,
style: negativeStylePrompt style: negativeStylePrompt,
}); });
modelNode = g.addNode({ modelNode = g.addNode({
type: 'sdxl_model_loader', type: 'sdxl_model_loader',
@ -163,64 +171,59 @@ export const buildMultidiffusionUpscsaleGraph = async (state: RootState): Promis
addLoRAs(state, g, tiledMultidiffusionNode, modelNode, null, clipSkipNode, posCondNode, negCondNode); addLoRAs(state, g, tiledMultidiffusionNode, modelNode, null, clipSkipNode, posCondNode, negCondNode);
} }
let vaeNode; let vaeNode;
if (vae) { if (vae) {
vaeNode = g.addNode({ vaeNode = g.addNode({
id: VAE_LOADER, id: VAE_LOADER,
type: "vae_loader", type: 'vae_loader',
vae_model: vae vae_model: vae,
}) });
} }
g.addEdge(vaeNode || modelNode, "vae", i2lNode, "vae") g.addEdge(vaeNode || modelNode, 'vae', i2lNode, 'vae');
g.addEdge(vaeNode || modelNode, "vae", l2iNode, "vae") g.addEdge(vaeNode || modelNode, 'vae', l2iNode, 'vae');
g.addEdge(noiseNode, 'noise', tiledMultidiffusionNode, 'noise');
g.addEdge(noiseNode, "noise", tiledMultidiffusionNode, "noise") g.addEdge(i2lNode, 'latents', tiledMultidiffusionNode, 'latents');
g.addEdge(i2lNode, "latents", tiledMultidiffusionNode, "latents")
g.addEdge(posCondNode, 'conditioning', tiledMultidiffusionNode, 'positive_conditioning'); g.addEdge(posCondNode, 'conditioning', tiledMultidiffusionNode, 'positive_conditioning');
g.addEdge(negCondNode, 'conditioning', tiledMultidiffusionNode, 'negative_conditioning'); g.addEdge(negCondNode, 'conditioning', tiledMultidiffusionNode, 'negative_conditioning');
g.addEdge(modelNode, "unet", tiledMultidiffusionNode, "unet") g.addEdge(modelNode, 'unet', tiledMultidiffusionNode, 'unet');
g.addEdge(tiledMultidiffusionNode, "latents", l2iNode, "latents") g.addEdge(tiledMultidiffusionNode, 'latents', l2iNode, 'latents');
const controlnetNode1 = g.addNode({ const controlnetNode1 = g.addNode({
id: 'controlnet_1', id: 'controlnet_1',
type: "controlnet", type: 'controlnet',
control_model: tileControlnetModel, control_model: tileControlnetModel,
control_mode: "balanced", control_mode: 'balanced',
resize_mode: "just_resize", resize_mode: 'just_resize',
control_weight: ((((structure + 10) * 0.025) + 0.3) * 0.013) + 0.35, control_weight: ((structure + 10) * 0.025 + 0.3) * 0.013 + 0.35,
begin_step_percent: 0, begin_step_percent: 0,
end_step_percent: ((structure + 10) * 0.025) + 0.3 end_step_percent: (structure + 10) * 0.025 + 0.3,
}) });
g.addEdge(resizeNode, "image", controlnetNode1, "image") g.addEdge(resizeNode, 'image', controlnetNode1, 'image');
const controlnetNode2 = g.addNode({ const controlnetNode2 = g.addNode({
id: "controlnet_2", id: 'controlnet_2',
type: "controlnet", type: 'controlnet',
control_model: tileControlnetModel, control_model: tileControlnetModel,
control_mode: "balanced", control_mode: 'balanced',
resize_mode: "just_resize", resize_mode: 'just_resize',
control_weight: (((structure + 10) * 0.025) + 0.3) * 0.013, control_weight: ((structure + 10) * 0.025 + 0.3) * 0.013,
begin_step_percent: ((structure + 10) * 0.025) + 0.3, begin_step_percent: (structure + 10) * 0.025 + 0.3,
end_step_percent: 0.8 end_step_percent: 0.8,
}) });
g.addEdge(resizeNode, "image", controlnetNode2, "image") g.addEdge(resizeNode, 'image', controlnetNode2, 'image');
const collectNode = g.addNode({ const collectNode = g.addNode({
id: CONTROL_NET_COLLECT, id: CONTROL_NET_COLLECT,
type: "collect", type: 'collect',
}) });
g.addEdge(controlnetNode1, "control", collectNode, "item") g.addEdge(controlnetNode1, 'control', collectNode, 'item');
g.addEdge(controlnetNode2, "control", collectNode, "item") g.addEdge(controlnetNode2, 'control', collectNode, 'item');
g.addEdge(collectNode, "collection", tiledMultidiffusionNode, "control")
g.addEdge(collectNode, 'collection', tiledMultidiffusionNode, 'control');
return g.getGraph(); return g.getGraph();
};
}

View File

@ -53,8 +53,8 @@ export const PROMPT_REGION_NEGATIVE_COND_PREFIX = 'prompt_region_negative_cond';
export const PROMPT_REGION_POSITIVE_COND_INVERTED_PREFIX = 'prompt_region_positive_cond_inverted'; export const PROMPT_REGION_POSITIVE_COND_INVERTED_PREFIX = 'prompt_region_positive_cond_inverted';
export const POSITIVE_CONDITIONING_COLLECT = 'positive_conditioning_collect'; export const POSITIVE_CONDITIONING_COLLECT = 'positive_conditioning_collect';
export const NEGATIVE_CONDITIONING_COLLECT = 'negative_conditioning_collect'; export const NEGATIVE_CONDITIONING_COLLECT = 'negative_conditioning_collect';
export const UNSHARP_MASK = 'unsharp_mask' export const UNSHARP_MASK = 'unsharp_mask';
export const TILED_MULTI_DIFFUSION_DENOISE_LATENTS = "tiled_multi_diffusion_denoise_latents" export const TILED_MULTI_DIFFUSION_DENOISE_LATENTS = 'tiled_multi_diffusion_denoise_latents';
// friendly graph ids // friendly graph ids
export const CONTROL_LAYERS_GRAPH = 'control_layers_graph'; export const CONTROL_LAYERS_GRAPH = 'control_layers_graph';

View File

@ -1,8 +1,8 @@
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { creativityChanged } from 'features/parameters/store/upscaleSlice';
import { memo, useCallback, useMemo } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { creativityChanged } from '../../store/upscaleSlice';
const ParamCreativity = () => { const ParamCreativity = () => {
const creativity = useAppSelector((s) => s.upscale.creativity); const creativity = useAppSelector((s) => s.upscale.creativity);
@ -25,7 +25,7 @@ const ParamCreativity = () => {
return ( return (
<FormControl> <FormControl>
<FormLabel>Creativity</FormLabel> <FormLabel>{t('upscaling.creativity')}</FormLabel>
<CompositeSlider <CompositeSlider
value={creativity} value={creativity}
defaultValue={initial} defaultValue={initial}

View File

@ -1,8 +1,8 @@
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { sharpnessChanged } from 'features/parameters/store/upscaleSlice';
import { memo, useCallback, useMemo } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { sharpnessChanged } from '../../store/upscaleSlice';
const ParamSharpness = () => { const ParamSharpness = () => {
const sharpness = useAppSelector((s) => s.upscale.sharpness); const sharpness = useAppSelector((s) => s.upscale.sharpness);
@ -25,7 +25,7 @@ const ParamSharpness = () => {
return ( return (
<FormControl> <FormControl>
<FormLabel>Sharpness</FormLabel> <FormLabel>{t('upscaling.sharpness')}</FormLabel>
<CompositeSlider <CompositeSlider
value={sharpness} value={sharpness}
defaultValue={initial} defaultValue={initial}

View File

@ -31,7 +31,7 @@ const ParamSpandrelModel = () => {
return ( return (
<FormControl orientation="vertical"> <FormControl orientation="vertical">
<FormLabel>Upscale Model</FormLabel> <FormLabel>{t('upscaling.upscaleModel')}</FormLabel>
<Combobox <Combobox
value={value} value={value}
placeholder={placeholder} placeholder={placeholder}

View File

@ -1,8 +1,8 @@
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { structureChanged } from 'features/parameters/store/upscaleSlice';
import { memo, useCallback, useMemo } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { structureChanged } from '../../store/upscaleSlice';
const ParamStructure = () => { const ParamStructure = () => {
const structure = useAppSelector((s) => s.upscale.structure); const structure = useAppSelector((s) => s.upscale.structure);
@ -25,7 +25,7 @@ const ParamStructure = () => {
return ( return (
<FormControl> <FormControl>
<FormLabel>Structure</FormLabel> <FormLabel>{t('upscaling.structure')}</FormLabel>
<CompositeSlider <CompositeSlider
value={structure} value={structure}
defaultValue={initial} defaultValue={initial}

View File

@ -1,9 +1,11 @@
import { FormControl, FormLabel, Switch } from '@invoke-ai/ui-library'; import { FormControl, FormLabel, Switch } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from '../../../../app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { tiledVAEChanged } from 'features/parameters/store/upscaleSlice';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { tiledVAEChanged } from '../../store/upscaleSlice'; import { useTranslation } from 'react-i18next';
export const ParamTiledVAEToggle = () => { export const ParamTiledVAEToggle = () => {
const { t } = useTranslation();
const tiledVAE = useAppSelector((s) => s.upscale.tiledVAE); const tiledVAE = useAppSelector((s) => s.upscale.tiledVAE);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -16,7 +18,7 @@ export const ParamTiledVAEToggle = () => {
return ( return (
<FormControl> <FormControl>
<Switch isChecked={tiledVAE} onChange={handleChange} /> <Switch isChecked={tiledVAE} onChange={handleChange} />
<FormLabel>Tiled VAE</FormLabel> <FormLabel>{t('upscaling.tiledVAE')}</FormLabel>
</FormControl> </FormControl>
); );
}; };

View File

@ -6,7 +6,6 @@ import { useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import type { ImageDTO } from 'services/api/types'; import type { ImageDTO } from 'services/api/types';
const getUpscaledPixels = (imageDTO?: ImageDTO, maxUpscalePixels?: number) => { const getUpscaledPixels = (imageDTO?: ImageDTO, maxUpscalePixels?: number) => {
if (!imageDTO) { if (!imageDTO) {
return; return;

View File

@ -10,7 +10,7 @@ import type {
ParameterSeed, ParameterSeed,
ParameterSteps, ParameterSteps,
ParameterStrength, ParameterStrength,
ParameterVAEModel ParameterVAEModel,
} from 'features/parameters/types/parameterSchemas'; } from 'features/parameters/types/parameterSchemas';
import type { RgbaColor } from 'react-colorful'; import type { RgbaColor } from 'react-colorful';

View File

@ -4,7 +4,6 @@ import type { PersistConfig, RootState } from 'app/store/store';
import type { ParameterSpandrelImageToImageModel } from 'features/parameters/types/parameterSchemas'; import type { ParameterSpandrelImageToImageModel } from 'features/parameters/types/parameterSchemas';
import type { ControlNetModelConfig, ImageDTO } from 'services/api/types'; import type { ControlNetModelConfig, ImageDTO } from 'services/api/types';
interface UpscaleState { interface UpscaleState {
_version: 1; _version: 1;
upscaleModel: ParameterSpandrelImageToImageModel | null; upscaleModel: ParameterSpandrelImageToImageModel | null;
@ -14,7 +13,7 @@ interface UpscaleState {
creativity: number; creativity: number;
tiledVAE: boolean; tiledVAE: boolean;
scale: number | null; scale: number | null;
tileControlnetModel: ControlNetModelConfig | null tileControlnetModel: ControlNetModelConfig | null;
} }
const initialUpscaleState: UpscaleState = { const initialUpscaleState: UpscaleState = {
@ -26,7 +25,7 @@ const initialUpscaleState: UpscaleState = {
creativity: 0, creativity: 0,
tiledVAE: false, tiledVAE: false,
scale: null, scale: null,
tileControlnetModel: null tileControlnetModel: null,
}; };
export const upscaleSlice = createSlice({ export const upscaleSlice = createSlice({
@ -68,7 +67,16 @@ export const upscaleSlice = createSlice({
}, },
}); });
export const { upscaleModelChanged, upscaleInitialImageChanged, tiledVAEChanged, structureChanged, creativityChanged, sharpnessChanged, scaleChanged, tileControlnetModelChanged } = upscaleSlice.actions; export const {
upscaleModelChanged,
upscaleInitialImageChanged,
tiledVAEChanged,
structureChanged,
creativityChanged,
sharpnessChanged,
scaleChanged,
tileControlnetModelChanged,
} = upscaleSlice.actions;
export const selectUpscalelice = (state: RootState) => state.upscale; export const selectUpscalelice = (state: RootState) => state.upscale;

View File

@ -1,12 +1,14 @@
import { Flex, Link, Text } from '@invoke-ai/ui-library'; import { Flex, Link, Text } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from '../../../../app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { useControlNetModels } from '../../../../services/api/hooks/modelsByType'; 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 { useCallback, useEffect, useMemo } from 'react';
import { tileControlnetModelChanged } from '../../../parameters/store/upscaleSlice'; import { useTranslation } from 'react-i18next';
import { MODEL_TYPE_SHORT_MAP } from '../../../parameters/types/constants'; import { useControlNetModels } from 'services/api/hooks/modelsByType';
import { setActiveTab } from '../../../ui/store/uiSlice';
export const MultidiffusionWarning = () => { export const MultidiffusionWarning = () => {
const { t } = useTranslation();
const model = useAppSelector((s) => s.generation.model); const model = useAppSelector((s) => s.generation.model);
const { tileControlnetModel, upscaleModel } = useAppSelector((s) => s.upscale); const { tileControlnetModel, upscaleModel } = useAppSelector((s) => s.upscale);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -23,19 +25,18 @@ export const MultidiffusionWarning = () => {
const warningText = useMemo(() => { const warningText = useMemo(() => {
if (!model) { if (!model) {
return `a model`; return t('upscaling.warningNoMainModel');
} }
if (!upscaleModel && !tileControlnetModel) { if (!upscaleModel && !tileControlnetModel) {
return `an upscaler model and ${MODEL_TYPE_SHORT_MAP[model.base]} tile controlnet`; return t('upscaling.warningNoTileOrUpscaleModel', { base_model: MODEL_TYPE_SHORT_MAP[model.base] });
} }
if (!upscaleModel) { if (!upscaleModel) {
return 'an upscaler model'; return t('upscaling.warningNoUpscaleModel');
} }
if (!tileControlnetModel) { if (!tileControlnetModel) {
return `a ${MODEL_TYPE_SHORT_MAP[model.base]} tile controlnet`; return t('upscaling.warningNoTile', { base_model: MODEL_TYPE_SHORT_MAP[model.base] });
} }
}, [model?.base, upscaleModel, tileControlnetModel]); }, [model, upscaleModel, tileControlnetModel, t]);
const handleGoToModelManager = useCallback(() => { const handleGoToModelManager = useCallback(() => {
dispatch(setActiveTab('models')); dispatch(setActiveTab('models'));
@ -46,13 +47,13 @@ export const MultidiffusionWarning = () => {
} }
return ( return (
<Flex bg="error.500" borderRadius={'base'} padding="2" direction="column"> <Flex bg="error.500" borderRadius="base" padding="2" direction="column">
<Text fontSize="xs" textAlign="center" display={'inline-block'}> <Text fontSize="xs" textAlign="center" display="inline-block">
Visit{' '} {t('upscaling.visit')}{' '}
<Link fontWeight="bold" onClick={handleGoToModelManager}> <Link fontWeight="bold" onClick={handleGoToModelManager}>
Model Manager {t('modelManager.modelManager')}
</Link>{' '} </Link>{' '}
to install {warningText} required by this feature {t('upscaling.toInstall')} {warningText}.
</Text> </Text>
</Flex> </Flex>
); );

View File

@ -12,9 +12,9 @@ import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { MultidiffusionWarning } from './MultidiffusionWarning';
import { UpscaleInitialImage } from './UpscaleInitialImage'; import { UpscaleInitialImage } from './UpscaleInitialImage';
import { UpscaleSizeDetails } from './UpscaleSizeDetails'; import { UpscaleSizeDetails } from './UpscaleSizeDetails';
import { MultidiffusionWarning } from './MultidiffusionWarning';
const selector = createMemoizedSelector([selectUpscalelice], (upscale) => { const selector = createMemoizedSelector([selectUpscalelice], (upscale) => {
const badges: string[] = []; const badges: string[] = [];

View File

@ -1,15 +1,17 @@
import { Flex, Text } from '@invoke-ai/ui-library'; import { Flex, Text } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
export const UpscaleSizeDetails = () => { export const UpscaleSizeDetails = () => {
const { t } = useTranslation();
const { upscaleInitialImage, scale } = useAppSelector((s) => s.upscale); const { upscaleInitialImage, scale } = useAppSelector((s) => s.upscale);
const outputSizeText = useMemo(() => { const outputSizeText = useMemo(() => {
if (upscaleInitialImage && scale) { if (upscaleInitialImage && scale) {
return `Output image size: ${upscaleInitialImage.width * scale} x ${upscaleInitialImage.height * scale}`; return `${t('upscaling.outputImageSize')}: ${upscaleInitialImage.width * scale} ${t('upscaling.x')} ${upscaleInitialImage.height * scale}`;
} }
}, [upscaleInitialImage, scale]); }, [upscaleInitialImage, scale, t]);
if (!outputSizeText || !upscaleInitialImage) { if (!outputSizeText || !upscaleInitialImage) {
return <></>; return <></>;
@ -18,7 +20,7 @@ export const UpscaleSizeDetails = () => {
return ( return (
<Flex direction="column"> <Flex direction="column">
<Text variant="subtext" fontWeight="bold"> <Text variant="subtext" fontWeight="bold">
Current image size: {upscaleInitialImage.width} x {upscaleInitialImage.height} {t('upscaling.currentImageSize')}: {upscaleInitialImage.width} {t('upscaling.x')} {upscaleInitialImage.height}
</Text> </Text>
<Text variant="subtext" fontWeight="bold"> <Text variant="subtext" fontWeight="bold">
{outputSizeText} {outputSizeText}