diff --git a/gui/src/client/types.ts b/gui/src/client/types.ts
index 8de792b9..ee5907e6 100644
--- a/gui/src/client/types.ts
+++ b/gui/src/client/types.ts
@@ -140,9 +140,7 @@ export interface UpscaleParams {
/**
* Parameters for upscale requests.
*/
-export interface UpscaleReqParams {
- prompt: string;
- negativePrompt?: string;
+export interface UpscaleReqParams extends BaseImgParams {
source: Blob;
}
diff --git a/gui/src/components/OnnxWeb.tsx b/gui/src/components/OnnxWeb.tsx
index ca69a816..dcc8634f 100644
--- a/gui/src/components/OnnxWeb.tsx
+++ b/gui/src/components/OnnxWeb.tsx
@@ -8,7 +8,6 @@ import { useHash } from 'react-use/lib/useHash';
import { useStore } from 'zustand';
import { StateContext } from '../state.js';
-import { ModelControl } from './control/ModelControl.js';
import { ImageHistory } from './ImageHistory.js';
import { Logo } from './Logo.js';
import { Blend } from './tab/Blend.js';
@@ -43,9 +42,6 @@ export function OnnxWeb() {
-
-
-
{
diff --git a/gui/src/components/Profiles.tsx b/gui/src/components/Profiles.tsx
index 65ffb5bc..e3a9230d 100644
--- a/gui/src/components/Profiles.tsx
+++ b/gui/src/components/Profiles.tsx
@@ -20,29 +20,35 @@ import { useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { useStore } from 'zustand';
-import { BaseImgParams, Txt2ImgParams } from '../client/types.js';
+import { BaseImgParams, HighresParams, Txt2ImgParams, UpscaleParams } from '../client/types.js';
import { StateContext } from '../state.js';
+const { useState, Fragment } = React;
+
export interface ProfilesProps {
+ highres: HighresParams;
params: BaseImgParams;
- setParams: ((params: BaseImgParams) => void) | undefined;
+ upscale: UpscaleParams;
+
+ setHighres(params: HighresParams): void;
+ setParams(params: BaseImgParams): void;
+ setUpscale(params: UpscaleParams): void;
}
export function Profiles(props: ProfilesProps) {
const state = mustExist(useContext(StateContext));
+ const profiles = useStore(state, (s) => s.profiles);
// eslint-disable-next-line @typescript-eslint/unbound-method
const saveProfile = useStore(state, (s) => s.saveProfile);
// eslint-disable-next-line @typescript-eslint/unbound-method
const removeProfile = useStore(state, (s) => s.removeProfile);
- const profiles = useStore(state, (s) => s.profiles);
- const highres = useStore(state, (s) => s.highres);
- const upscale = useStore(state, (s) => s.upscale);
- const [dialogOpen, setDialogOpen] = React.useState(false);
- const [profileName, setProfileName] = React.useState('');
+
+ const [dialogOpen, setDialogOpen] = useState(false);
+ const [profileName, setProfileName] = useState('');
const { t } = useTranslation();
- return <>
+ return
setDialogOpen(true)}>
-
)}
onChange={(event, value) => {
- if (doesExist(value) && doesExist(props.setParams)) {
+ if (doesExist(value)) {
props.setParams({
...value.params
});
@@ -138,8 +118,8 @@ export function Profiles(props: ProfilesProps) {
saveProfile({
params: props.params,
name: profileName,
- highResParams: highres,
- upscaleParams: upscale,
+ highResParams: props.highres,
+ upscaleParams: props.upscale,
});
setDialogOpen(false);
setProfileName('');
@@ -147,7 +127,33 @@ export function Profiles(props: ProfilesProps) {
>{t('profile.save')}
- >;
+
+ ;
}
export async function loadParamsFromFile(file: File): Promise> {
@@ -276,7 +282,7 @@ export async function parseAutoComment(comment: string): Promise s.setInpaint);
// eslint-disable-next-line @typescript-eslint/unbound-method
- const setUpscale = useStore(state, (s) => s.setUpscaleTab);
+ const setUpscale = useStore(state, (s) => s.setUpscale);
// eslint-disable-next-line @typescript-eslint/unbound-method
const setBlend = useStore(state, (s) => s.setBlend);
diff --git a/gui/src/components/control/HighresControl.tsx b/gui/src/components/control/HighresControl.tsx
index 3467a947..4d2380c2 100644
--- a/gui/src/components/control/HighresControl.tsx
+++ b/gui/src/components/control/HighresControl.tsx
@@ -3,17 +3,21 @@ import { Checkbox, FormControl, FormControlLabel, InputLabel, MenuItem, Select,
import * as React from 'react';
import { useContext } from 'react';
import { useTranslation } from 'react-i18next';
-import { useStore } from 'zustand';
-import { ConfigContext, StateContext } from '../../state.js';
+import { HighresParams } from '../../client/types.js';
+import { ConfigContext } from '../../state.js';
import { NumericField } from '../input/NumericField.js';
-export function HighresControl() {
- const { params } = mustExist(useContext(ConfigContext));
- const state = mustExist(useContext(StateContext));
- const highres = useStore(state, (s) => s.highres);
+export interface HighresControlProps {
+ highres: HighresParams;
+ setHighres(params: Partial): void;
+}
+
+export function HighresControl(props: HighresControlProps) {
// eslint-disable-next-line @typescript-eslint/unbound-method
- const setHighres = useStore(state, (s) => s.setHighres);
+ const { highres, setHighres } = props;
+
+ const { params } = mustExist(useContext(ConfigContext));
const { t } = useTranslation();
return
@@ -22,7 +26,7 @@ export function HighresControl() {
control={ {
+ onChange={(_event) => {
setHighres({
enabled: highres.enabled === false,
});
diff --git a/gui/src/components/control/ImageControl.tsx b/gui/src/components/control/ImageControl.tsx
index c6786d39..cf40979d 100644
--- a/gui/src/components/control/ImageControl.tsx
+++ b/gui/src/components/control/ImageControl.tsx
@@ -13,21 +13,21 @@ import { ClientContext, ConfigContext, OnnxState, StateContext } from '../../sta
import { NumericField } from '../input/NumericField.js';
import { PromptInput } from '../input/PromptInput.js';
import { QueryList } from '../input/QueryList.js';
-import { Profiles } from '../Profiles.js';
export interface ImageControlProps {
- selector: (state: OnnxState) => BaseImgParams;
-
- onChange?: (params: BaseImgParams) => void;
+ onChange(params: BaseImgParams): void;
+ selector(state: OnnxState): BaseImgParams;
}
/**
* Doesn't need to use state directly, the parent component knows which params to pass
*/
export function ImageControl(props: ImageControlProps) {
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const { onChange, selector } = props;
const { params } = mustExist(useContext(ConfigContext));
const state = mustExist(useContext(StateContext));
- const controlState = useStore(state, props.selector);
+ const controlState = useStore(state, selector);
const { t } = useTranslation();
const client = mustExist(useContext(ClientContext));
@@ -40,7 +40,6 @@ export function ImageControl(props: ImageControlProps) {
return
-
{
- if (doesExist(props.onChange)) {
- props.onChange({
+ if (doesExist(onChange)) {
+ onChange({
...controlState,
scheduler: value,
});
@@ -66,8 +65,8 @@ export function ImageControl(props: ImageControlProps) {
step={params.eta.step}
value={controlState.eta}
onChange={(eta) => {
- if (doesExist(props.onChange)) {
- props.onChange({
+ if (doesExist(onChange)) {
+ onChange({
...controlState,
eta,
});
@@ -82,8 +81,8 @@ export function ImageControl(props: ImageControlProps) {
step={params.cfg.step}
value={controlState.cfg}
onChange={(cfg) => {
- if (doesExist(props.onChange)) {
- props.onChange({
+ if (doesExist(onChange)) {
+ onChange({
...controlState,
cfg,
});
@@ -97,12 +96,10 @@ export function ImageControl(props: ImageControlProps) {
step={params.steps.step}
value={controlState.steps}
onChange={(steps) => {
- if (doesExist(props.onChange)) {
- props.onChange({
- ...controlState,
- steps,
- });
- }
+ onChange({
+ ...controlState,
+ steps,
+ });
}}
/>
{
- if (doesExist(props.onChange)) {
- props.onChange({
- ...controlState,
- seed,
- });
- }
+ onChange({
+ ...controlState,
+ seed,
+ });
}}
/>
}
onClick={() => {
const seed = Math.floor(Math.random() * params.seed.max);
- if (doesExist(props.onChange)) {
- props.onChange({
- ...controlState,
- seed,
- });
- }
+ props.onChange({
+ ...controlState,
+ seed,
+ });
}}
>
{t('parameter.newSeed')}
@@ -144,12 +137,10 @@ export function ImageControl(props: ImageControlProps) {
step={params.batch.step}
value={controlState.batch}
onChange={(batch) => {
- if (doesExist(props.onChange)) {
- props.onChange({
- ...controlState,
- batch,
- });
- }
+ props.onChange({
+ ...controlState,
+ batch,
+ });
}}
/>
{
- if (doesExist(props.onChange)) {
- props.onChange({
- ...controlState,
- tiles,
- });
- }
+ props.onChange({
+ ...controlState,
+ tiles,
+ });
}}
/>
{
- if (doesExist(props.onChange)) {
- props.onChange({
- ...controlState,
- overlap,
- });
- }
+ props.onChange({
+ ...controlState,
+ overlap,
+ });
}}
/>
{
- if (doesExist(props.onChange)) {
- props.onChange({
- ...controlState,
- stride,
- });
- }
+ props.onChange({
+ ...controlState,
+ stride,
+ });
}}
/>
{
- if (doesExist(props.onChange)) {
- props.onChange({
- ...controlState,
- tiledVAE: controlState.tiledVAE === false,
- });
- }
+ props.onChange({
+ ...controlState,
+ tiledVAE: controlState.tiledVAE === false,
+ });
}}
/>}
/>
@@ -218,12 +201,10 @@ export function ImageControl(props: ImageControlProps) {
prompt={controlState.prompt}
negativePrompt={controlState.negativePrompt}
onChange={(value) => {
- if (doesExist(props.onChange)) {
- props.onChange({
- ...controlState,
- ...value,
- });
- }
+ props.onChange({
+ ...controlState,
+ ...value,
+ });
}}
/>
;
diff --git a/gui/src/components/control/ModelControl.tsx b/gui/src/components/control/ModelControl.tsx
index 4616aa53..7f103e3f 100644
--- a/gui/src/components/control/ModelControl.tsx
+++ b/gui/src/components/control/ModelControl.tsx
@@ -4,25 +4,25 @@ import { useMutation, useQuery } from '@tanstack/react-query';
import * as React from 'react';
import { useContext } from 'react';
import { useTranslation } from 'react-i18next';
-import { useHash } from 'react-use/lib/useHash';
-import { useStore } from 'zustand';
+import { ModelParams } from '../../client/types.js';
import { STALE_TIME } from '../../config.js';
import { ClientContext, StateContext } from '../../state.js';
import { QueryList } from '../input/QueryList.js';
-import { QueryMenu } from '../input/QueryMenu.js';
-import { getTab } from '../utils.js';
-export function ModelControl() {
+export interface ModelControlProps {
+ model: ModelParams;
+ setModel(params: Partial): void;
+}
+
+export function ModelControl(props: ModelControlProps) {
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const { model, setModel } = props;
+
const client = mustExist(useContext(ClientContext));
const state = mustExist(useContext(StateContext));
- const params = useStore(state, (s) => s.model);
- // eslint-disable-next-line @typescript-eslint/unbound-method
- const setModel = useStore(state, (s) => s.setModel);
const { t } = useTranslation();
- const [hash, _setHash] = useHash();
-
const restart = useMutation(['restart'], async () => client.restart());
const models = useQuery(['models'], async () => client.models(), {
staleTime: STALE_TIME,
@@ -34,135 +34,83 @@ export function ModelControl() {
staleTime: STALE_TIME,
});
- function addToken(type: string, name: string, weight = 1.0) {
- const tab = getTab(hash);
- const current = state.getState();
-
- switch (tab) {
- case 'txt2img': {
- const { prompt } = current.txt2img;
- current.setTxt2Img({
- prompt: `<${type}:${name}:1.0> ${prompt}`,
+ return
+ {
+ setModel({
+ platform,
});
- break;
- }
- case 'img2img': {
- const { prompt } = current.img2img;
- current.setImg2Img({
- prompt: `<${type}:${name}:1.0> ${prompt}`,
+ }}
+ />
+ {
+ setModel({
+ pipeline,
});
- break;
- }
- default:
- // not supported yet
- }
- }
-
- return
-
- {
- setModel({
- platform,
- });
- }}
- />
- {
- setModel({
- pipeline,
- });
- }}
- />
- result.diffusion,
- }}
- value={params.model}
- onChange={(model) => {
- setModel({
- model,
- });
- }}
- />
- result.upscaling,
- }}
- value={params.upscaling}
- onChange={(upscaling) => {
- setModel({
- upscaling,
- });
- }}
- />
- result.correction,
- }}
- value={params.correction}
- onChange={(correction) => {
- setModel({
- correction,
- });
- }}
- />
-
-
- result.networks.filter((network) => network.type === 'inversion').map((network) => network.name),
- }}
- onSelect={(name) => {
- addToken('inversion', name);
- }}
- />
- result.networks.filter((network) => network.type === 'lora').map((network) => network.name),
- }}
- onSelect={(name) => {
- addToken('lora', name);
- }}
- />
-
-
+ }}
+ />
+ result.diffusion,
+ }}
+ value={model.model}
+ onChange={(newModel) => {
+ setModel({
+ model: newModel,
+ });
+ }}
+ />
+ result.upscaling,
+ }}
+ value={model.upscaling}
+ onChange={(upscaling) => {
+ setModel({
+ upscaling,
+ });
+ }}
+ />
+ result.correction,
+ }}
+ value={model.correction}
+ onChange={(correction) => {
+ setModel({
+ correction,
+ });
+ }}
+ />
+
;
}
diff --git a/gui/src/components/control/UpscaleControl.tsx b/gui/src/components/control/UpscaleControl.tsx
index 4eff8c83..f9d739b1 100644
--- a/gui/src/components/control/UpscaleControl.tsx
+++ b/gui/src/components/control/UpscaleControl.tsx
@@ -3,17 +3,21 @@ import { Checkbox, FormControl, FormControlLabel, InputLabel, MenuItem, Select,
import * as React from 'react';
import { useContext } from 'react';
import { useTranslation } from 'react-i18next';
-import { useStore } from 'zustand';
-import { ConfigContext, StateContext } from '../../state.js';
+import { UpscaleParams } from '../../client/types.js';
+import { ConfigContext } from '../../state.js';
import { NumericField } from '../input/NumericField.js';
-export function UpscaleControl() {
- const { params } = mustExist(useContext(ConfigContext));
- const state = mustExist(useContext(StateContext));
- const upscale = useStore(state, (s) => s.upscale);
+export interface UpscaleControlProps {
+ upscale: UpscaleParams;
+ setUpscale(params: Partial): void;
+}
+
+export function UpscaleControl(props: UpscaleControlProps) {
// eslint-disable-next-line @typescript-eslint/unbound-method
- const setUpscale = useStore(state, (s) => s.setUpscale);
+ const { upscale, setUpscale } = props;
+
+ const { params } = mustExist(useContext(ConfigContext));
const { t } = useTranslation();
return
@@ -22,7 +26,7 @@ export function UpscaleControl() {
control={ {
+ onChange={(_event) => {
setUpscale({
enabled: upscale.enabled === false,
});
diff --git a/gui/src/components/input/MaskCanvas.tsx b/gui/src/components/input/MaskCanvas.tsx
index e59ddae0..0bc4673c 100644
--- a/gui/src/components/input/MaskCanvas.tsx
+++ b/gui/src/components/input/MaskCanvas.tsx
@@ -4,8 +4,8 @@ import { Button, Stack, Typography } from '@mui/material';
import { throttle } from 'lodash';
import React, { RefObject, useContext, useEffect, useMemo, useRef } from 'react';
import { useTranslation } from 'react-i18next';
-import { useStore } from 'zustand';
+import { BrushParams } from '../../client/types.js';
import { SAVE_TIME } from '../../config.js';
import { ConfigContext, LoggerContext, StateContext } from '../../state.js';
import { imageFromBlob } from '../../utils.js';
@@ -36,14 +36,17 @@ export interface Point {
}
export interface MaskCanvasProps {
+ brush: BrushParams;
source?: Maybe;
mask?: Maybe;
- onSave: (blob: Blob) => void;
+ onSave(blob: Blob): void;
+ setBrush(brush: Partial): void;
}
export function MaskCanvas(props: MaskCanvasProps) {
- const { source, mask } = props;
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const { source, mask, brush, setBrush } = props;
const { params } = mustExist(useContext(ConfigContext));
const logger = mustExist(useContext(LoggerContext));
@@ -202,9 +205,6 @@ export function MaskCanvas(props: MaskCanvasProps) {
});
const state = mustExist(useContext(StateContext));
- const brush = useStore(state, (s) => s.brush);
- // eslint-disable-next-line @typescript-eslint/unbound-method
- const setBrush = useStore(state, (s) => s.setBrush);
const { t } = useTranslation();
useEffect(() => {
diff --git a/gui/src/components/input/PromptInput.tsx b/gui/src/components/input/PromptInput.tsx
index 475c6c68..2a6a7287 100644
--- a/gui/src/components/input/PromptInput.tsx
+++ b/gui/src/components/input/PromptInput.tsx
@@ -1,16 +1,23 @@
-import { doesExist, Maybe } from '@apextoaster/js-utils';
+import { doesExist, mustExist } from '@apextoaster/js-utils';
import { TextField } from '@mui/material';
import { Stack } from '@mui/system';
+import { useQuery } from '@tanstack/react-query';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
+import { QueryMenu } from '../input/QueryMenu.js';
+import { STALE_TIME } from '../../config.js';
+import { ClientContext } from '../../state.js';
+
+const { useContext } = React;
+
export interface PromptValue {
prompt: string;
negativePrompt?: string;
}
export interface PromptInputProps extends PromptValue {
- onChange?: Maybe<(value: PromptValue) => void>;
+ onChange: (value: PromptValue) => void;
}
export const PROMPT_GROUP = 75;
@@ -29,12 +36,24 @@ export function PromptInput(props: PromptInputProps) {
const tokens = splitPrompt(prompt);
const groups = Math.ceil(tokens.length / PROMPT_GROUP);
+ const client = mustExist(useContext(ClientContext));
+ const models = useQuery(['models'], async () => client.models(), {
+ staleTime: STALE_TIME,
+ });
+
const { t } = useTranslation();
const helper = t('input.prompt.tokens', {
groups,
tokens: tokens.length,
});
+ function addToken(type: string, name: string, weight = 1.0) {
+ props.onChange({
+ prompt: `<${type}:${name}:1.0> ${prompt}`,
+ negativePrompt,
+ });
+ }
+
return
+
+ result.networks.filter((network) => network.type === 'inversion').map((network) => network.name),
+ }}
+ onSelect={(name) => {
+ addToken('inversion', name);
+ }}
+ />
+ result.networks.filter((network) => network.type === 'lora').map((network) => network.name),
+ }}
+ onSelect={(name) => {
+ addToken('lora', name);
+ }}
+ />
+
;
}
diff --git a/gui/src/components/tab/Blend.tsx b/gui/src/components/tab/Blend.tsx
index 7d355742..f54159eb 100644
--- a/gui/src/components/tab/Blend.tsx
+++ b/gui/src/components/tab/Blend.tsx
@@ -15,12 +15,12 @@ import { MaskCanvas } from '../input/MaskCanvas.js';
export function Blend() {
async function uploadSource() {
- const { model, blend, upscale } = state.getState();
- const { image, retry } = await client.blend(model, {
+ const { blend, blendModel, blendUpscale } = state.getState();
+ const { image, retry } = await client.blend(blendModel, {
...blend,
mask: mustExist(blend.mask),
sources: mustExist(blend.sources), // TODO: show an error if this doesn't exist
- }, upscale);
+ }, blendUpscale);
pushHistory(image, retry);
}
@@ -32,10 +32,16 @@ export function Blend() {
});
const state = mustExist(useContext(StateContext));
+ const brush = useStore(state, (s) => s.blendBrush);
const blend = useStore(state, (s) => s.blend);
+ const upscale = useStore(state, (s) => s.blendUpscale);
// eslint-disable-next-line @typescript-eslint/unbound-method
const setBlend = useStore(state, (s) => s.setBlend);
// eslint-disable-next-line @typescript-eslint/unbound-method
+ const setBrush = useStore(state, (s) => s.setBlendBrush);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const setUpscale = useStore(state, (s) => s.setBlendUpscale);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
const pushHistory = useStore(state, (s) => s.pushHistory);
const { t } = useTranslation();
@@ -61,6 +67,7 @@ export function Blend() {
/>
)}
{
@@ -68,8 +75,9 @@ export function Blend() {
mask,
});
}}
+ setBrush={setBrush}
/>
-
+
-
-
+
+
s.txt2img.height);
- const width = useStore(state, (s) => s.txt2img.width);
+ const txt2img = useStore(state, (s) => s.txt2img);
+ const model = useStore(state, (s) => s.txt2imgModel);
+ const highres = useStore(state, (s) => s.txt2imgHighres);
+ const upscale = useStore(state, (s) => s.txt2imgUpscale);
// eslint-disable-next-line @typescript-eslint/unbound-method
- const setTxt2Img = useStore(state, (s) => s.setTxt2Img);
+ const setParams = useStore(state, (s) => s.setTxt2Img);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const setHighres = useStore(state, (s) => s.setTxt2ImgHighres);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const setUpscale = useStore(state, (s) => s.setTxt2ImgUpscale);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const setModel = useStore(state, (s) => s.setTxt2ImgModel);
// eslint-disable-next-line @typescript-eslint/unbound-method
const pushHistory = useStore(state, (s) => s.pushHistory);
const { t } = useTranslation();
return
- s.txt2img} onChange={setTxt2Img} />
+
+
+ s.txt2img} onChange={setParams} />
{
- setTxt2Img({
+ setParams({
width: value,
});
}}
@@ -58,16 +69,16 @@ export function Txt2Img() {
min={params.height.min}
max={params.height.max}
step={params.height.step}
- value={height}
+ value={txt2img.height}
onChange={(value) => {
- setTxt2Img({
+ setParams({
height: value,
});
}}
/>
-
-
+
+
generate.mutate()}
diff --git a/gui/src/components/tab/Upscale.tsx b/gui/src/components/tab/Upscale.tsx
index 3308a8d5..5d6d773c 100644
--- a/gui/src/components/tab/Upscale.tsx
+++ b/gui/src/components/tab/Upscale.tsx
@@ -1,25 +1,27 @@
import { doesExist, mustExist } from '@apextoaster/js-utils';
import { Box, Button, Stack } from '@mui/material';
+import { useMutation, useQueryClient } from '@tanstack/react-query';
import * as React from 'react';
import { useContext } from 'react';
import { useTranslation } from 'react-i18next';
-import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useStore } from 'zustand';
import { IMAGE_FILTER } from '../../config.js';
import { ClientContext, StateContext } from '../../state.js';
+import { HighresControl } from '../control/HighresControl.js';
+import { ModelControl } from '../control/ModelControl.js';
import { UpscaleControl } from '../control/UpscaleControl.js';
import { ImageInput } from '../input/ImageInput.js';
import { PromptInput } from '../input/PromptInput.js';
-import { HighresControl } from '../control/HighresControl.js';
+import { Profiles } from '../Profiles.js';
export function Upscale() {
async function uploadSource() {
- const { highres, model, upscale } = state.getState();
- const { image, retry } = await client.upscale(model, {
- ...params,
- source: mustExist(params.source), // TODO: show an error if this doesn't exist
- }, upscale, highres);
+ const { upscaleHighres, upscaleUpscale, upscaleModel, upscale } = state.getState();
+ const { image, retry } = await client.upscale(upscaleModel, {
+ ...upscale,
+ source: mustExist(upscale.source), // TODO: show an error if this doesn't exist
+ }, upscaleUpscale, upscaleHighres);
pushHistory(image, retry);
}
@@ -31,21 +33,32 @@ export function Upscale() {
});
const state = mustExist(useContext(StateContext));
- const params = useStore(state, (s) => s.upscaleTab);
+ const highres = useStore(state, (s) => s.upscaleHighres);
+ const model = useStore(state, (s) => s.upscaleModel);
+ const params = useStore(state, (s) => s.upscale);
+ const upscale = useStore(state, (s) => s.upscaleUpscale);
// eslint-disable-next-line @typescript-eslint/unbound-method
- const setSource = useStore(state, (s) => s.setUpscaleTab);
+ const setModel = useStore(state, (s) => s.setUpscalingModel);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const setHighres = useStore(state, (s) => s.setUpscaleHighres);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const setUpscale = useStore(state, (s) => s.setUpscaleUpscale);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const setParams = useStore(state, (s) => s.setUpscale);
// eslint-disable-next-line @typescript-eslint/unbound-method
const pushHistory = useStore(state, (s) => s.pushHistory);
const { t } = useTranslation();
return
+
+
{
- setSource({
+ setParams({
source: file,
});
}}
@@ -54,11 +67,11 @@ export function Upscale() {
prompt={params.prompt}
negativePrompt={params.negativePrompt}
onChange={(value) => {
- setSource(value);
+ setParams(value);
}}
/>
-
-
+
+
(persist((...slice) => ({
- ...createBrushSlice(...slice),
...createDefaultSlice(...slice),
...createHistorySlice(...slice),
...createImg2ImgSlice(...slice),
...createInpaintSlice(...slice),
...createModelSlice(...slice),
...createTxt2ImgSlice(...slice),
- ...createOutpaintSlice(...slice),
...createUpscaleSlice(...slice),
- ...createHighresSlice(...slice),
...createBlendSlice(...slice),
...createResetSlice(...slice),
- ...createExtraSlice(...slice),
...createProfileSlice(...slice),
}), {
name: STATE_KEY,
@@ -91,8 +83,8 @@ export async function renderApp(config: Config, params: ServerParams, logger: Lo
mask: undefined,
source: undefined,
},
- upscaleTab: {
- ...s.upscaleTab,
+ upscale: {
+ ...s.upscale,
source: undefined,
},
blend: {
diff --git a/gui/src/state.ts b/gui/src/state.ts
index 089bf6e6..ec64096b 100644
--- a/gui/src/state.ts
+++ b/gui/src/state.ts
@@ -48,12 +48,6 @@ interface ProfileItem {
upscaleParams?: Maybe;
}
-interface BrushSlice {
- brush: BrushParams;
-
- setBrush(brush: Partial): void;
-}
-
interface DefaultSlice {
defaults: TabState;
theme: Theme;
@@ -62,24 +56,6 @@ interface DefaultSlice {
setTheme(theme: Theme): void;
}
-interface ExtraSlice {
- extras: ExtrasFile;
-
- setExtras(extras: Partial): void;
-
- setCorrectionModel(model: CorrectionModel): void;
- setDiffusionModel(model: DiffusionModel): void;
- setExtraNetwork(model: ExtraNetwork): void;
- setExtraSource(model: ExtraSource): void;
- setUpscalingModel(model: UpscalingModel): void;
-
- removeCorrectionModel(model: CorrectionModel): void;
- removeDiffusionModel(model: DiffusionModel): void;
- removeExtraNetwork(model: ExtraNetwork): void;
- removeExtraSource(model: ExtraSource): void;
- removeUpscalingModel(model: UpscalingModel): void;
-}
-
interface HistorySlice {
history: Array;
limit: number;
@@ -91,60 +67,96 @@ interface HistorySlice {
}
interface ModelSlice {
- model: ModelParams;
+ extras: ExtrasFile;
- setModel(model: Partial): void;
+ removeCorrectionModel(model: CorrectionModel): void;
+ removeDiffusionModel(model: DiffusionModel): void;
+ removeExtraNetwork(model: ExtraNetwork): void;
+ removeExtraSource(model: ExtraSource): void;
+ removeUpscalingModel(model: UpscalingModel): void;
+
+ setExtras(extras: Partial): void;
+
+ setCorrectionModel(model: CorrectionModel): void;
+ setDiffusionModel(model: DiffusionModel): void;
+ setExtraNetwork(model: ExtraNetwork): void;
+ setExtraSource(model: ExtraSource): void;
+ setUpscalingModel(model: UpscalingModel): void;
}
// #region tab slices
interface Txt2ImgSlice {
txt2img: TabState;
+ txt2imgModel: ModelParams;
+ txt2imgHighres: HighresParams;
+ txt2imgUpscale: UpscaleParams;
+
+ resetTxt2Img(): void;
setTxt2Img(params: Partial): void;
- resetTxt2Img(): void;
+ setTxt2ImgModel(params: Partial): void;
+ setTxt2ImgHighres(params: Partial): void;
+ setTxt2ImgUpscale(params: Partial): void;
}
interface Img2ImgSlice {
img2img: TabState;
+ img2imgModel: ModelParams;
+ img2imgHighres: HighresParams;
+ img2imgUpscale: UpscaleParams;
+
+ resetImg2Img(): void;
setImg2Img(params: Partial): void;
- resetImg2Img(): void;
+ setImg2ImgModel(params: Partial): void;
+ setImg2ImgHighres(params: Partial): void;
+ setImg2ImgUpscale(params: Partial): void;
}
interface InpaintSlice {
inpaint: TabState;
-
- setInpaint(params: Partial): void;
- resetInpaint(): void;
-}
-
-interface OutpaintSlice {
+ inpaintBrush: BrushParams;
+ inpaintModel: ModelParams;
+ inpaintHighres: HighresParams;
+ inpaintUpscale: UpscaleParams;
outpaint: OutpaintPixels;
+ resetInpaint(): void;
+
+ setInpaint(params: Partial): void;
+ setInpaintBrush(brush: Partial): void;
+ setInpaintModel(params: Partial): void;
+ setInpaintHighres(params: Partial): void;
+ setInpaintUpscale(params: Partial): void;
setOutpaint(pixels: Partial): void;
}
-interface HighresSlice {
- highres: HighresParams;
-
- setHighres(params: Partial): void;
- resetHighres(): void;
-}
-
interface UpscaleSlice {
- upscale: UpscaleParams;
- upscaleTab: TabState;
+ upscale: TabState;
+ upscaleHighres: HighresParams;
+ upscaleModel: ModelParams;
+ upscaleUpscale: UpscaleParams;
- setUpscale(upscale: Partial): void;
- setUpscaleTab(params: Partial): void;
- resetUpscaleTab(): void;
+ resetUpscale(): void;
+
+ setUpscale(params: Partial): void;
+ setUpscaleHighres(params: Partial): void;
+ setUpscaleModel(params: Partial): void;
+ setUpscaleUpscale(params: Partial): void;
}
interface BlendSlice {
blend: TabState;
+ blendBrush: BrushParams;
+ blendModel: ModelParams;
+ blendUpscale: UpscaleParams;
+
+ resetBlend(): void;
setBlend(blend: Partial): void;
- resetBlend(): void;
+ setBlendBrush(brush: Partial): void;
+ setBlendModel(model: Partial): void;
+ setBlendUpscale(params: Partial): void;
}
interface ResetSlice {
@@ -154,8 +166,9 @@ interface ResetSlice {
interface ProfileSlice {
profiles: Array;
- saveProfile(profile: ProfileItem): void;
removeProfile(profileName: string): void;
+
+ saveProfile(profile: ProfileItem): void;
}
// #endregion
@@ -163,19 +176,16 @@ interface ProfileSlice {
* Full merged state including all slices.
*/
export type OnnxState
- = BrushSlice
- & DefaultSlice
+ = DefaultSlice
& HistorySlice
& Img2ImgSlice
& InpaintSlice
& ModelSlice
- & OutpaintSlice
& Txt2ImgSlice
- & HighresSlice
& UpscaleSlice
& BlendSlice
& ResetSlice
- & ExtraSlice
+ & ModelSlice
& ProfileSlice;
/**
@@ -268,14 +278,49 @@ export function baseParamsFromServer(defaults: ServerParams): Required = (set) => ({
txt2img: {
- ...base,
+ ...defaultParams,
width: server.width.default,
height: server.height.default,
},
+ txt2imgHighres: {
+ ...defaultHighres,
+ },
+ txt2imgModel: {
+ ...defaultModel,
+ },
+ txt2imgUpscale: {
+ ...defaultUpscale,
+ },
setTxt2Img(params) {
set((prev) => ({
txt2img: {
@@ -284,10 +329,34 @@ export function createStateSlices(server: ServerParams) {
},
}));
},
+ setTxt2ImgHighres(params) {
+ set((prev) => ({
+ txt2imgHighres: {
+ ...prev.txt2imgHighres,
+ ...params,
+ },
+ }));
+ },
+ setTxt2ImgModel(params) {
+ set((prev) => ({
+ txt2imgModel: {
+ ...prev.txt2imgModel,
+ ...params,
+ },
+ }));
+ },
+ setTxt2ImgUpscale(params) {
+ set((prev) => ({
+ txt2imgUpscale: {
+ ...prev.txt2imgUpscale,
+ ...params,
+ },
+ }));
+ },
resetTxt2Img() {
set({
txt2img: {
- ...base,
+ ...defaultParams,
width: server.width.default,
height: server.height.default,
},
@@ -297,12 +366,32 @@ export function createStateSlices(server: ServerParams) {
const createImg2ImgSlice: Slice = (set) => ({
img2img: {
- ...base,
+ ...defaultParams,
loopback: server.loopback.default,
source: null,
sourceFilter: '',
strength: server.strength.default,
},
+ img2imgHighres: {
+ ...defaultHighres,
+ },
+ img2imgModel: {
+ ...defaultModel,
+ },
+ img2imgUpscale: {
+ ...defaultUpscale,
+ },
+ resetImg2Img() {
+ set({
+ img2img: {
+ ...defaultParams,
+ loopback: server.loopback.default,
+ source: null,
+ sourceFilter: '',
+ strength: server.strength.default,
+ },
+ });
+ },
setImg2Img(params) {
set((prev) => ({
img2img: {
@@ -311,22 +400,35 @@ export function createStateSlices(server: ServerParams) {
},
}));
},
- resetImg2Img() {
- set({
- img2img: {
- ...base,
- loopback: server.loopback.default,
- source: null,
- sourceFilter: '',
- strength: server.strength.default,
+ setImg2ImgHighres(params) {
+ set((prev) => ({
+ img2imgHighres: {
+ ...prev.img2imgHighres,
+ ...params,
},
- });
+ }));
+ },
+ setImg2ImgModel(params) {
+ set((prev) => ({
+ img2imgModel: {
+ ...prev.img2imgModel,
+ ...params,
+ },
+ }));
+ },
+ setImg2ImgUpscale(params) {
+ set((prev) => ({
+ img2imgUpscale: {
+ ...prev.img2imgUpscale,
+ ...params,
+ },
+ }));
},
});
const createInpaintSlice: Slice = (set) => ({
inpaint: {
- ...base,
+ ...defaultParams,
fillColor: server.fillColor.default,
filter: server.filter.default,
mask: null,
@@ -335,18 +437,29 @@ export function createStateSlices(server: ServerParams) {
strength: server.strength.default,
tileOrder: server.tileOrder.default,
},
- setInpaint(params) {
- set((prev) => ({
- inpaint: {
- ...prev.inpaint,
- ...params,
- },
- }));
+ inpaintBrush: {
+ ...DEFAULT_BRUSH,
+ },
+ inpaintHighres: {
+ ...defaultHighres,
+ },
+ inpaintModel: {
+ ...defaultModel,
+ },
+ inpaintUpscale: {
+ ...defaultUpscale,
+ },
+ outpaint: {
+ enabled: false,
+ left: server.left.default,
+ right: server.right.default,
+ top: server.top.default,
+ bottom: server.bottom.default,
},
resetInpaint() {
set({
inpaint: {
- ...base,
+ ...defaultParams,
fillColor: server.fillColor.default,
filter: server.filter.default,
mask: null,
@@ -357,6 +470,54 @@ export function createStateSlices(server: ServerParams) {
},
});
},
+ setInpaint(params) {
+ set((prev) => ({
+ inpaint: {
+ ...prev.inpaint,
+ ...params,
+ },
+ }));
+ },
+ setInpaintBrush(brush) {
+ set((prev) => ({
+ inpaintBrush: {
+ ...prev.inpaintBrush,
+ ...brush,
+ },
+ }));
+ },
+ setInpaintHighres(params) {
+ set((prev) => ({
+ inpaintHighres: {
+ ...prev.inpaintHighres,
+ ...params,
+ },
+ }));
+ },
+ setInpaintModel(params) {
+ set((prev) => ({
+ inpaintModel: {
+ ...prev.inpaintModel,
+ ...params,
+ },
+ }));
+ },
+ setInpaintUpscale(params) {
+ set((prev) => ({
+ inpaintUpscale: {
+ ...prev.inpaintUpscale,
+ ...params,
+ },
+ }));
+ },
+ setOutpaint(pixels) {
+ set((prev) => ({
+ outpaint: {
+ ...prev.outpaint,
+ ...pixels,
+ }
+ }));
+ },
});
const createHistorySlice: Slice = (set) => ({
@@ -405,109 +566,59 @@ export function createStateSlices(server: ServerParams) {
},
});
- const createOutpaintSlice: Slice = (set) => ({
- outpaint: {
- enabled: false,
- left: server.left.default,
- right: server.right.default,
- top: server.top.default,
- bottom: server.bottom.default,
- },
- setOutpaint(pixels) {
- set((prev) => ({
- outpaint: {
- ...prev.outpaint,
- ...pixels,
- }
- }));
- },
- });
-
- const createBrushSlice: Slice = (set) => ({
- brush: {
- ...DEFAULT_BRUSH,
- },
- setBrush(brush) {
- set((prev) => ({
- brush: {
- ...prev.brush,
- ...brush,
- },
- }));
- },
- });
-
const createUpscaleSlice: Slice = (set) => ({
upscale: {
- denoise: server.denoise.default,
- enabled: false,
- faces: false,
- faceOutscale: server.faceOutscale.default,
- faceStrength: server.faceStrength.default,
- outscale: server.outscale.default,
- scale: server.scale.default,
- upscaleOrder: server.upscaleOrder.default,
- },
- upscaleTab: {
- negativePrompt: server.negativePrompt.default,
- prompt: server.prompt.default,
+ ...defaultParams,
source: null,
},
- setUpscale(upscale) {
- set((prev) => ({
- upscale: {
- ...prev.upscale,
- ...upscale,
- },
- }));
+ upscaleHighres: {
+ ...defaultHighres,
},
- setUpscaleTab(source) {
- set((prev) => ({
- upscaleTab: {
- ...prev.upscaleTab,
- ...source,
- },
- }));
+ upscaleModel: {
+ ...defaultModel,
},
- resetUpscaleTab() {
+ upscaleUpscale: {
+ ...defaultUpscale,
+ },
+ resetUpscale() {
set({
- upscaleTab: {
- negativePrompt: server.negativePrompt.default,
- prompt: server.prompt.default,
+ upscale: {
+ ...defaultParams,
source: null,
},
});
},
- });
-
- const createHighresSlice: Slice = (set) => ({
- highres: {
- enabled: false,
- highresIterations: server.highresIterations.default,
- highresMethod: '',
- highresSteps: server.highresSteps.default,
- highresScale: server.highresScale.default,
- highresStrength: server.highresStrength.default,
- },
- setHighres(params) {
+ setUpscale(source) {
set((prev) => ({
- highres: {
- ...prev.highres,
+ upscale: {
+ ...prev.upscale,
+ ...source,
+ },
+ }));
+ },
+ setUpscaleHighres(params) {
+ set((prev) => ({
+ upscaleHighres: {
+ ...prev.upscaleHighres,
...params,
},
}));
},
- resetHighres() {
- set({
- highres: {
- enabled: false,
- highresIterations: server.highresIterations.default,
- highresMethod: '',
- highresSteps: server.highresSteps.default,
- highresScale: server.highresScale.default,
- highresStrength: server.highresStrength.default,
+ setUpscaleModel(params) {
+ set((prev) => ({
+ upscaleModel: {
+ ...prev.upscaleModel,
+ ...defaultModel,
},
- });
+ }));
+ },
+ setUpscaleUpscale(params) {
+ set((prev) => ({
+ upscaleUpscale: {
+ ...prev.upscaleUpscale,
+ ...params,
+ },
+ }));
},
});
@@ -516,13 +627,14 @@ export function createStateSlices(server: ServerParams) {
mask: null,
sources: [],
},
- setBlend(blend) {
- set((prev) => ({
- blend: {
- ...prev.blend,
- ...blend,
- },
- }));
+ blendBrush: {
+ ...DEFAULT_BRUSH,
+ },
+ blendModel: {
+ ...defaultModel,
+ },
+ blendUpscale: {
+ ...defaultUpscale,
},
resetBlend() {
set({
@@ -532,11 +644,43 @@ export function createStateSlices(server: ServerParams) {
},
});
},
+ setBlend(blend) {
+ set((prev) => ({
+ blend: {
+ ...prev.blend,
+ ...blend,
+ },
+ }));
+ },
+ setBlendBrush(brush) {
+ set((prev) => ({
+ blendBrush: {
+ ...prev.blendBrush,
+ ...brush,
+ },
+ }));
+ },
+ setBlendModel(model) {
+ set((prev) => ({
+ blendModel: {
+ ...prev.blendModel,
+ ...model,
+ },
+ }));
+ },
+ setBlendUpscale(params) {
+ set((prev) => ({
+ blendUpscale: {
+ ...prev.blendUpscale,
+ ...params,
+ },
+ }));
+ },
});
const createDefaultSlice: Slice = (set) => ({
defaults: {
- ...base,
+ ...defaultParams,
},
theme: '',
setDefaults(params) {
@@ -554,25 +698,6 @@ export function createStateSlices(server: ServerParams) {
}
});
- const createModelSlice: Slice = (set) => ({
- model: {
- control: server.control.default,
- correction: server.correction.default,
- model: server.model.default,
- pipeline: server.pipeline.default,
- platform: server.platform.default,
- upscaling: server.upscaling.default,
- },
- setModel(params) {
- set((prev) => ({
- model: {
- ...prev.model,
- ...params,
- }
- }));
- },
- });
-
const createResetSlice: Slice = (set) => ({
resetAll() {
set((prev) => {
@@ -580,7 +705,7 @@ export function createStateSlices(server: ServerParams) {
next.resetImg2Img();
next.resetInpaint();
next.resetTxt2Img();
- next.resetUpscaleTab();
+ next.resetUpscale();
next.resetBlend();
return next;
});
@@ -620,7 +745,7 @@ export function createStateSlices(server: ServerParams) {
});
// eslint-disable-next-line sonarjs/cognitive-complexity
- const createExtraSlice: Slice = (set) => ({
+ const createModelSlice: Slice = (set) => ({
extras: {
correction: [],
diffusion: [],
@@ -799,19 +924,15 @@ export function createStateSlices(server: ServerParams) {
});
return {
- createBrushSlice,
createDefaultSlice,
createHistorySlice,
createImg2ImgSlice,
createInpaintSlice,
- createModelSlice,
- createOutpaintSlice,
createTxt2ImgSlice,
createUpscaleSlice,
- createHighresSlice,
createBlendSlice,
createResetSlice,
- createExtraSlice,
+ createModelSlice,
createProfileSlice,
};
}