Skip to content

Commit

Permalink
feat(gui): add API server to settings
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed Jan 18, 2023
1 parent 87bf27e commit d402db8
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 161 deletions.
10 changes: 5 additions & 5 deletions gui/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { doesExist } from '@apextoaster/js-utils';

import { ConfigParams } from './config.js';
import { ServerParams } from './config.js';

export interface ModelParams {
/**
Expand Down Expand Up @@ -107,7 +107,7 @@ export interface ApiClient {
masks(): Promise<Array<string>>;
models(): Promise<ModelsResponse>;
noises(): Promise<Array<string>>;
params(): Promise<ConfigParams>;
params(): Promise<ServerParams>;
platforms(): Promise<Array<string>>;
schedulers(): Promise<Array<string>>;

Expand All @@ -122,7 +122,7 @@ export interface ApiClient {

export const STATUS_SUCCESS = 200;

export function paramsFromConfig(defaults: ConfigParams): Required<BaseImgParams> {
export function paramsFromConfig(defaults: ServerParams): Required<BaseImgParams> {
return {
cfg: defaults.cfg.default,
negativePrompt: defaults.negativePrompt.default,
Expand Down Expand Up @@ -213,10 +213,10 @@ export function makeClient(root: string, f = fetch): ApiClient {
const res = await f(path);
return await res.json() as Array<string>;
},
async params(): Promise<ConfigParams> {
async params(): Promise<ServerParams> {
const path = makeApiUrl(root, 'settings', 'params');
const res = await f(path);
return await res.json() as ConfigParams;
return await res.json() as ServerParams;
},
async schedulers(): Promise<Array<string>> {
const path = makeApiUrl(root, 'settings', 'schedulers');
Expand Down
4 changes: 2 additions & 2 deletions gui/src/components/ImageCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ export function ImageCard(props: ImageCardProps) {
window.open(output.url, '_blank');
}

return <Card sx={{ maxWidth: config.width.default }} elevation={2}>
<CardMedia sx={{ height: config.height.default }}
return <Card sx={{ maxWidth: config.params.width.default }} elevation={2}>
<CardMedia sx={{ height: config.params.height.default }}
component='img'
image={output.url}
title={params.prompt}
Expand Down
57 changes: 27 additions & 30 deletions gui/src/components/ImageControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@ import { useQuery } from 'react-query';
import { useStore } from 'zustand';

import { BaseImgParams } from '../client.js';
import { ConfigParams, STALE_TIME } from '../config.js';
import { ClientContext, OnnxState, StateContext } from '../state.js';
import { STALE_TIME } from '../config.js';
import { ClientContext, ConfigContext, OnnxState, StateContext } from '../state.js';
import { SCHEDULER_LABELS } from '../strings.js';
import { NumericField } from './NumericField.js';
import { QueryList } from './QueryList.js';

const { useContext } = React;

export interface ImageControlProps {
config: ConfigParams;

selector: (state: OnnxState) => BaseImgParams;

onChange?: (params: BaseImgParams) => void;
Expand All @@ -26,10 +24,9 @@ export interface ImageControlProps {
* doesn't need to use state, the parent component knows which params to pass
*/
export function ImageControl(props: ImageControlProps) {
const { config } = props;

const { params } = mustExist(useContext(ConfigContext));
const state = mustExist(useContext(StateContext));
const params = useStore(state, props.selector);
const controlState = useStore(state, props.selector);

const client = mustExist(useContext(ClientContext));
const schedulers = useQuery('schedulers', async () => client.schedulers(), {
Expand All @@ -44,11 +41,11 @@ export function ImageControl(props: ImageControlProps) {
query={{
result: schedulers,
}}
value={mustDefault(params.scheduler, '')}
value={mustDefault(controlState.scheduler, '')}
onChange={(value) => {
if (doesExist(props.onChange)) {
props.onChange({
...params,
...controlState,
scheduler: value,
});
}
Expand All @@ -58,44 +55,44 @@ export function ImageControl(props: ImageControlProps) {
<NumericField
decimal
label='CFG'
min={config.cfg.min}
max={config.cfg.max}
step={config.cfg.step}
value={params.cfg}
min={params.cfg.min}
max={params.cfg.max}
step={params.cfg.step}
value={controlState.cfg}
onChange={(cfg) => {
if (doesExist(props.onChange)) {
props.onChange({
...params,
...controlState,
cfg,
});
}
}}
/>
<NumericField
label='Steps'
min={config.steps.min}
max={config.steps.max}
step={config.steps.step}
value={params.steps}
min={params.steps.min}
max={params.steps.max}
step={params.steps.step}
value={controlState.steps}
onChange={(steps) => {
if (doesExist(props.onChange)) {
props.onChange({
...params,
...controlState,
steps,
});
}
}}
/>
<NumericField
label='Seed'
min={config.seed.min}
max={config.seed.max}
step={config.seed.step}
value={params.seed}
min={params.seed.min}
max={params.seed.max}
step={params.seed.step}
value={controlState.seed}
onChange={(seed) => {
if (doesExist(props.onChange)) {
props.onChange({
...params,
...controlState,
seed,
});
}
Expand All @@ -105,10 +102,10 @@ export function ImageControl(props: ImageControlProps) {
variant='outlined'
startIcon={<Casino />}
onClick={() => {
const seed = Math.floor(Math.random() * config.seed.max);
const seed = Math.floor(Math.random() * params.seed.max);
if (doesExist(props.onChange)) {
props.onChange({
...params,
...controlState,
seed,
});
}
Expand All @@ -117,18 +114,18 @@ export function ImageControl(props: ImageControlProps) {
New Seed
</Button>
</Stack>
<TextField label='Prompt' variant='outlined' value={params.prompt} onChange={(event) => {
<TextField label='Prompt' variant='outlined' value={controlState.prompt} onChange={(event) => {
if (doesExist(props.onChange)) {
props.onChange({
...params,
...controlState,
prompt: event.target.value,
});
}
}} />
<TextField label='Negative Prompt' variant='outlined' value={params.negativePrompt} onChange={(event) => {
<TextField label='Negative Prompt' variant='outlined' value={controlState.negativePrompt} onChange={(event) => {
if (doesExist(props.onChange)) {
props.onChange({
...params,
...controlState,
negativePrompt: event.target.value,
});
}
Expand Down
12 changes: 6 additions & 6 deletions gui/src/components/Img2Img.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { UpscaleControl } from './UpscaleControl.js';
const { useContext } = React;

export function Img2Img() {
const config = mustExist(useContext(ConfigContext));
const { params } = mustExist(useContext(ConfigContext));

async function uploadSource() {
const { model, img2img, upscale } = state.getState();
Expand Down Expand Up @@ -48,21 +48,21 @@ export function Img2Img() {
source: file,
});
}} />
<ImageControl config={config} selector={(s) => s.img2img} onChange={setImg2Img} />
<ImageControl selector={(s) => s.img2img} onChange={setImg2Img} />
<NumericField
decimal
label='Strength'
min={config.strength.min}
max={config.strength.max}
step={config.strength.step}
min={params.strength.min}
max={params.strength.max}
step={params.strength.step}
value={strength}
onChange={(value) => {
setImg2Img({
strength: value,
});
}}
/>
<UpscaleControl config={config} />
<UpscaleControl />
<Button onClick={() => upload.mutate()}>Generate</Button>
</Stack>
</Box>;
Expand Down
14 changes: 6 additions & 8 deletions gui/src/components/Inpaint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { UpscaleControl } from './UpscaleControl.js';
const { useContext } = React;

export function Inpaint() {
const config = mustExist(useContext(ConfigContext));
const { params } = mustExist(useContext(ConfigContext));
const client = mustExist(useContext(ClientContext));

const masks = useQuery('masks', async () => client.masks(), {
Expand Down Expand Up @@ -92,7 +92,6 @@ export function Inpaint() {
}}
renderImage={(image) =>
<MaskCanvas
config={config}
base={source}
source={image}
onSave={(file) => {
Expand All @@ -104,7 +103,6 @@ export function Inpaint() {
}
/>
<ImageControl
config={config}
selector={(s) => s.inpaint}
onChange={(newParams) => {
setInpaint(newParams);
Expand All @@ -113,9 +111,9 @@ export function Inpaint() {
<Stack direction='row' spacing={2}>
<NumericField
label='Strength'
min={config.strength.min}
max={config.strength.max}
step={config.strength.step}
min={params.strength.min}
max={params.strength.max}
step={params.strength.step}
value={strength}
onChange={(value) => {
setInpaint({
Expand Down Expand Up @@ -153,8 +151,8 @@ export function Inpaint() {
}}
/>
</Stack>
<OutpaintControl config={config} />
<UpscaleControl config={config} />
<OutpaintControl />
<UpscaleControl />
<Button onClick={() => upload.mutate()}>Generate</Button>
</Stack>
</Box>;
Expand Down
8 changes: 4 additions & 4 deletions gui/src/components/LoadingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface LoadingCardProps {

export function LoadingCard(props: LoadingCardProps) {
const client = mustExist(React.useContext(ClientContext));
const config = mustExist(useContext(ConfigContext));
const { params } = mustExist(useContext(ConfigContext));

// eslint-disable-next-line @typescript-eslint/unbound-method
const pushHistory = useStore(mustExist(useContext(StateContext)), (state) => state.pushHistory);
Expand All @@ -32,13 +32,13 @@ export function LoadingCard(props: LoadingCardProps) {
}
}, [ready.status, ready.data?.ready]);

return <Card sx={{ maxWidth: config.width.default }}>
<CardContent sx={{ height: config.height.default }}>
return <Card sx={{ maxWidth: params.width.default }}>
<CardContent sx={{ height: params.height.default }}>
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
minHeight: config.height.default,
minHeight: params.height.default,
}}>
<CircularProgress />
</div>
Expand Down
25 changes: 12 additions & 13 deletions gui/src/components/MaskCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { throttle } from 'lodash';
import React, { RefObject, useContext, useEffect, useMemo, useRef, useState } from 'react';
import { useStore } from 'zustand';

import { ConfigParams, SAVE_TIME } from '../config.js';
import { StateContext } from '../state.js';
import { SAVE_TIME } from '../config.js';
import { ConfigContext, StateContext } from '../state.js';
import { NumericField } from './NumericField';

export const FULL_CIRCLE = 2 * Math.PI;
Expand Down Expand Up @@ -38,16 +38,15 @@ export interface Point {
}

export interface MaskCanvasProps {
config: ConfigParams;

base?: Maybe<Blob>;
source?: Maybe<Blob>;

onSave: (blob: Blob) => void;
}

export function MaskCanvas(props: MaskCanvasProps) {
const { base, config, source } = props;
const { base, source } = props;
const { params } = mustExist(useContext(ConfigContext));

function saveMask(): void {
if (doesExist(bufferRef.current)) {
Expand Down Expand Up @@ -157,8 +156,8 @@ export function MaskCanvas(props: MaskCanvasProps) {
}, [base]);

const styles: React.CSSProperties = {
maxHeight: config.height.default,
maxWidth: config.width.default,
maxHeight: params.height.default,
maxWidth: params.width.default,
};

if (doesExist(background)) {
Expand All @@ -168,24 +167,24 @@ export function MaskCanvas(props: MaskCanvasProps) {
return <Stack spacing={2}>
<canvas
ref={brushRef}
height={config.height.default}
width={config.width.default}
height={params.height.default}
width={params.width.default}
style={{
display: 'none',
}}
/>
<canvas
ref={bufferRef}
height={config.height.default}
width={config.width.default}
height={params.height.default}
width={params.width.default}
style={{
display: 'none',
}}
/>
<canvas
ref={canvasRef}
height={config.height.default}
width={config.width.default}
height={params.height.default}
width={params.width.default}
style={styles}
onClick={(event) => {
const canvas = mustExist(canvasRef.current);
Expand Down
Loading

0 comments on commit d402db8

Please sign in to comment.