1
0
Fork 0

fix(gui): limit seed to safe values, prep for more settings

This commit is contained in:
Sean Sube 2023-01-08 14:25:25 -06:00
parent c5e0439aa5
commit 3dfbb0061b
5 changed files with 101 additions and 38 deletions

View File

@ -1,10 +1,11 @@
import { doesExist } from '@apextoaster/js-utils'; import { doesExist } from '@apextoaster/js-utils';
import { IconButton, Stack, TextField } from '@mui/material';
import { Casino } from '@mui/icons-material'; import { Casino } from '@mui/icons-material';
import { IconButton, Stack, TextField } from '@mui/material';
import * as React from 'react'; import * as React from 'react';
import { NumericField } from './NumericField.js';
import { BaseImgParams } from '../api/client.js'; import { BaseImgParams } from '../api/client.js';
import { CONFIG_DEFAULTS } from '../config.js';
import { NumericField } from './NumericField.js';
export interface ImageControlProps { export interface ImageControlProps {
params: BaseImgParams; params: BaseImgParams;
@ -18,9 +19,9 @@ export function ImageControl(props: ImageControlProps) {
<Stack direction='row' spacing={4}> <Stack direction='row' spacing={4}>
<NumericField <NumericField
label='CFG' label='CFG'
min={0} min={CONFIG_DEFAULTS.cfg.min}
max={30} max={CONFIG_DEFAULTS.cfg.max}
step={1} step={CONFIG_DEFAULTS.cfg.step}
value={params.cfg} value={params.cfg}
onChange={(cfg) => { onChange={(cfg) => {
if (doesExist(props.onChange)) { if (doesExist(props.onChange)) {
@ -33,9 +34,9 @@ export function ImageControl(props: ImageControlProps) {
/> />
<NumericField <NumericField
label='Steps' label='Steps'
min={1} min={CONFIG_DEFAULTS.steps.min}
max={150} max={CONFIG_DEFAULTS.steps.max}
step={1} step={CONFIG_DEFAULTS.steps.step}
value={params.steps} value={params.steps}
onChange={(steps) => { onChange={(steps) => {
if (doesExist(props.onChange)) { if (doesExist(props.onChange)) {
@ -50,9 +51,9 @@ export function ImageControl(props: ImageControlProps) {
<Stack direction='row' spacing={4}> <Stack direction='row' spacing={4}>
<NumericField <NumericField
label='Seed' label='Seed'
min={-1} min={CONFIG_DEFAULTS.seed.min}
max={Number.MAX_SAFE_INTEGER} max={CONFIG_DEFAULTS.seed.max}
step={1} step={CONFIG_DEFAULTS.seed.step}
value={params.seed} value={params.seed}
onChange={(seed) => { onChange={(seed) => {
if (doesExist(props.onChange)) { if (doesExist(props.onChange)) {
@ -64,7 +65,7 @@ export function ImageControl(props: ImageControlProps) {
}} }}
/> />
<IconButton onClick={() => { <IconButton onClick={() => {
const seed = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); const seed = Math.floor(Math.random() * CONFIG_DEFAULTS.seed.max);
if (doesExist(props.onChange)) { if (doesExist(props.onChange)) {
props.onChange({ props.onChange({
...params, ...params,

View File

@ -4,7 +4,7 @@ import * as React from 'react';
import { useMutation, useQuery } from 'react-query'; import { useMutation, useQuery } from 'react-query';
import { ApiClient, BaseImgParams } from '../api/client.js'; import { ApiClient, BaseImgParams } from '../api/client.js';
import { Config } from '../config.js'; import { Config, CONFIG_DEFAULTS, STALE_TIME } from '../config.js';
import { SCHEDULER_LABELS } from '../strings.js'; import { SCHEDULER_LABELS } from '../strings.js';
import { ImageCard } from './ImageCard.js'; import { ImageCard } from './ImageCard.js';
import { ImageControl } from './ImageControl.js'; import { ImageControl } from './ImageControl.js';
@ -14,7 +14,6 @@ import { QueryList } from './QueryList.js';
const { useState } = React; const { useState } = React;
export const STALE_TIME = 3_000;
export interface Img2ImgProps { export interface Img2ImgProps {
client: ApiClient; client: ApiClient;
config: Config; config: Config;
@ -52,11 +51,11 @@ export function Img2Img(props: Img2ImgProps) {
}); });
const [source, setSource] = useState<File>(); const [source, setSource] = useState<File>();
const [strength, setStrength] = useState(0.5); const [strength, setStrength] = useState(CONFIG_DEFAULTS.strength.default);
const [params, setParams] = useState<BaseImgParams>({ const [params, setParams] = useState<BaseImgParams>({
cfg: 6, cfg: CONFIG_DEFAULTS.cfg.default,
seed: -1, seed: CONFIG_DEFAULTS.seed.default,
steps: 25, steps: CONFIG_DEFAULTS.steps.default,
prompt: config.default.prompt, prompt: config.default.prompt,
}); });
const [scheduler, setScheduler] = useState(config.default.scheduler); const [scheduler, setScheduler] = useState(config.default.scheduler);
@ -81,10 +80,10 @@ export function Img2Img(props: Img2ImgProps) {
}} /> }} />
<NumericField <NumericField
decimal decimal
label='Weight' label='Strength'
min={0} min={CONFIG_DEFAULTS.strength.min}
max={1} max={CONFIG_DEFAULTS.strength.max}
step={0.01} step={CONFIG_DEFAULTS.strength.step}
value={strength} value={strength}
onChange={(value) => { onChange={(value) => {
setStrength(value); setStrength(value);

View File

@ -4,11 +4,11 @@ import * as React from 'react';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { ApiClient } from '../api/client.js'; import { ApiClient } from '../api/client.js';
import { Config } from '../config.js'; import { Config, STALE_TIME } from '../config.js';
import { MODEL_LABELS, PLATFORM_LABELS } from '../strings.js'; import { MODEL_LABELS, PLATFORM_LABELS } from '../strings.js';
import { Img2Img } from './Img2Img.js'; import { Img2Img } from './Img2Img.js';
import { QueryList } from './QueryList.js'; import { QueryList } from './QueryList.js';
import { STALE_TIME, Txt2Img } from './Txt2Img.js'; import { Txt2Img } from './Txt2Img.js';
const { useState } = React; const { useState } = React;

View File

@ -3,7 +3,7 @@ import * as React from 'react';
import { useMutation, useQuery } from 'react-query'; import { useMutation, useQuery } from 'react-query';
import { ApiClient, BaseImgParams } from '../api/client.js'; import { ApiClient, BaseImgParams } from '../api/client.js';
import { Config } from '../config.js'; import { Config, CONFIG_DEFAULTS, STALE_TIME } from '../config.js';
import { SCHEDULER_LABELS } from '../strings.js'; import { SCHEDULER_LABELS } from '../strings.js';
import { ImageCard } from './ImageCard.js'; import { ImageCard } from './ImageCard.js';
import { ImageControl } from './ImageControl.js'; import { ImageControl } from './ImageControl.js';
@ -13,7 +13,6 @@ import { QueryList } from './QueryList.js';
const { useState } = React; const { useState } = React;
export const STALE_TIME = 3_000;
export interface Txt2ImgProps { export interface Txt2ImgProps {
client: ApiClient; client: ApiClient;
config: Config; config: Config;
@ -41,12 +40,12 @@ export function Txt2Img(props: Txt2ImgProps) {
staleTime: STALE_TIME, staleTime: STALE_TIME,
}); });
const [height, setHeight] = useState(512); const [height, setHeight] = useState(CONFIG_DEFAULTS.height.default);
const [width, setWidth] = useState(512); const [width, setWidth] = useState(CONFIG_DEFAULTS.width.default);
const [params, setParams] = useState<BaseImgParams>({ const [params, setParams] = useState<BaseImgParams>({
cfg: 6, cfg: CONFIG_DEFAULTS.cfg.default,
seed: -1, seed: CONFIG_DEFAULTS.seed.default,
steps: 25, steps: CONFIG_DEFAULTS.steps.default,
prompt: config.default.prompt, prompt: config.default.prompt,
}); });
const [scheduler, setScheduler] = useState(config.default.scheduler); const [scheduler, setScheduler] = useState(config.default.scheduler);
@ -71,9 +70,9 @@ export function Txt2Img(props: Txt2ImgProps) {
<Stack direction='row' spacing={4}> <Stack direction='row' spacing={4}>
<NumericField <NumericField
label='Width' label='Width'
min={8} min={CONFIG_DEFAULTS.width.min}
max={512} max={CONFIG_DEFAULTS.width.max}
step={8} step={CONFIG_DEFAULTS.width.step}
value={width} value={width}
onChange={(value) => { onChange={(value) => {
setWidth(value); setWidth(value);
@ -81,9 +80,9 @@ export function Txt2Img(props: Txt2ImgProps) {
/> />
<NumericField <NumericField
label='Height' label='Height'
min={8} min={CONFIG_DEFAULTS.height.min}
max={512} max={CONFIG_DEFAULTS.height.max}
step={8} step={CONFIG_DEFAULTS.height.step}
value={height} value={height}
onChange={(value) => { onChange={(value) => {
setHeight(value); setHeight(value);

View File

@ -1,4 +1,4 @@
import { STATUS_SUCCESS } from './api/client.js'; import { Img2ImgParams, STATUS_SUCCESS, Txt2ImgParams } from './api/client.js';
export interface Config { export interface Config {
api: { api: {
@ -21,3 +21,67 @@ export async function loadConfig(): Promise<Config> {
throw new Error('could not load config'); throw new Error('could not load config');
} }
} }
export interface ConfigRange {
default: number;
min: number;
max: number;
step: number;
}
export type KeyFilter<T extends object> = {
[K in keyof T]: T[K] extends number ? K : T[K] extends string ? K : never;
}[keyof T];
export type ConfigRanges<T extends object> = {
[K in KeyFilter<T>]: T[K] extends number ? ConfigRange : T[K] extends string ? string : never;
};
export const IMAGE_STEP = 8;
export const IMAGE_MAX = 512;
export const CONFIG_DEFAULTS: ConfigRanges<Required<Img2ImgParams & Txt2ImgParams>> = {
cfg: {
default: 6,
min: 1,
max: 30,
step: 0.1,
},
height: {
default: IMAGE_MAX,
min: IMAGE_STEP,
max: IMAGE_MAX,
step: IMAGE_STEP,
},
model: '',
negativePrompt: '',
platform: '',
prompt: 'an astronaut eating a hamburger',
scheduler: '',
steps: {
default: 25,
min: 1,
max: 200,
step: 1,
},
seed: {
default: -1,
min: -1,
max: (2 ** 32) - 1,
step: 1,
},
strength: {
default: 0.5,
min: 0,
max: 1,
step: 0.01,
},
width: {
default: IMAGE_MAX,
min: IMAGE_STEP,
max: IMAGE_MAX,
step: IMAGE_STEP,
},
};
export const STALE_TIME = 3_000;