fix(gui): limit seed to safe values, prep for more settings
This commit is contained in:
parent
c5e0439aa5
commit
3dfbb0061b
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue