1
0
Fork 0

fix(gui): dedupe query lists into a component

This commit is contained in:
Sean Sube 2023-01-05 23:53:39 -06:00
parent cab13f665a
commit 1c9eed3a90
4 changed files with 69 additions and 70 deletions

View File

@ -1,10 +1,10 @@
import { mustExist } from '@apextoaster/js-utils';
import { TabContext, TabList, TabPanel } from '@mui/lab';
import { Box, Container, MenuItem, Select, Tab, Typography } from '@mui/material';
import { Box, Container, Tab, Typography } from '@mui/material';
import * as React from 'react';
import { useQuery } from 'react-query';
import { ApiClient } from '../api/client.js';
import { QueryList } from './QueryList.js';
import { STALE_TIME, Txt2Img } from './Txt2Img.js';
const { useState } = React;
@ -13,6 +13,10 @@ export interface OnnxWebProps {
client: ApiClient;
}
const MODEL_LABELS = {
'stable-diffusion-onnx-v1-5': 'Stable Diffusion v1.5',
};
export function OnnxWeb(props: OnnxWebProps) {
const [tab, setTab] = useState('1');
const [model, setModel] = useState('stable-diffusion-onnx-v1-5');
@ -21,19 +25,6 @@ export function OnnxWeb(props: OnnxWebProps) {
staleTime: STALE_TIME,
});
function renderModels() {
switch (models.status) {
case 'error':
return <MenuItem value='error'>Error</MenuItem>;
case 'loading':
return <MenuItem value='loading'>Loading</MenuItem>;
case 'success':
return mustExist(models.data).map((name) => <MenuItem key={name} value={name}>{name}</MenuItem>);
default:
return <MenuItem value='error'>Unknown Error</MenuItem>;
}
}
return (
<div>
<Container>
@ -43,11 +34,9 @@ export function OnnxWeb(props: OnnxWebProps) {
</Typography>
</Box>
<Box sx={{ my: 4 }}>
<Select value={model} onChange={(e) => {
setModel(e.target.value);
}}>
{renderModels()}
</Select>
<QueryList result={models} labels={MODEL_LABELS} value={model} onChange={(value) => {
setModel(value);
}} />
</Box>
<TabContext value={tab}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>

View File

@ -0,0 +1,42 @@
import { doesExist, mustDefault, mustExist } from '@apextoaster/js-utils';
import { MenuItem, Select } from '@mui/material';
import * as React from 'react';
import { UseQueryResult } from 'react-query';
export interface QueryListProps {
labels: Record<string, string>;
result: UseQueryResult<Array<string>>;
value: string;
onChange?: (value: string) => void;
}
export function QueryList(props: QueryListProps) {
const { labels, result, value } = props;
if (result.status === 'error') {
if (result.error instanceof Error) {
return <div>Error: {result.error.message}</div>;
} else {
return <div>Unknown Error</div>;
}
}
if (result.status === 'loading') {
return <div>Loading...</div>;
}
if (result.status === 'idle') {
return <div>Idle?</div>;
}
// else: success
const data = mustExist(result.data);
return <Select value={value} onChange={(e) => {
if (doesExist(props.onChange)) {
props.onChange(e.target.value);
}
}}>
{data.map((name) => <MenuItem key={name} value={name}>{mustDefault(labels[name], name)}</MenuItem>)}
</Select>;
}

View File

@ -1,22 +1,22 @@
import { mustExist } from '@apextoaster/js-utils';
import { Box, Button, MenuItem, Select, Stack, TextField } from '@mui/material';
import { Box, Button, Stack, TextField } from '@mui/material';
import * as React from 'react';
import { useMutation, useQuery } from 'react-query';
import { ApiClient } from '../api/client.js';
import { ImageControl, ImageParams } from './ImageControl.js';
import { QueryList } from './QueryList.js';
const { useState } = React;
export const STALE_TIME = 3_000;
// TODO: set up i18next
const PLATFORM_NAMES: Record<string, string> = {
const PLATFORM_LABELS: Record<string, string> = {
amd: 'AMD GPU',
cpu: 'CPU',
};
const SCHEDULER_NAMES: Record<string, string> = {
const SCHEDULER_LABELS: Record<string, string> = {
'ddim': 'DDIM',
'ddpm': 'DDPM',
'dpm-multi': 'DPM Multistep',
@ -32,12 +32,12 @@ export interface Txt2ImgProps {
}
export function Txt2Img(props: Txt2ImgProps) {
const { client } = props;
const { client, model } = props;
async function generateImage() {
return client.txt2img({
...params,
model: props.model,
model,
prompt,
scheduler,
});
@ -78,53 +78,19 @@ export function Txt2Img(props: Txt2ImgProps) {
}
}
function renderSchedulers() {
switch (schedulers.status) {
case 'error':
return <MenuItem value='error'>Error</MenuItem>;
case 'loading':
return <MenuItem value='loading'>Loading</MenuItem>;
case 'success':
return mustExist(schedulers.data).map((name) => <MenuItem key={name} value={name}>{SCHEDULER_NAMES[name]}</MenuItem>);
default:
return <MenuItem value='error'>Unknown Error</MenuItem>;
}
}
function renderPlatforms() {
switch (platforms.status) {
case 'error':
return <MenuItem value='error'>Error</MenuItem>;
case 'loading':
return <MenuItem value='loading'>Loading</MenuItem>;
case 'success':
return mustExist(platforms.data).map((name) => <MenuItem key={name} value={name}>{PLATFORM_NAMES[name]}</MenuItem>);
default:
return <MenuItem value='error'>Unknown Error</MenuItem>;
}
}
return <Box>
<Stack spacing={2}>
<Stack direction='row' spacing={2}>
<Select
value={scheduler}
label="Scheduler"
onChange={(event) => {
setScheduler(event.target.value);
<QueryList result={schedulers} value={scheduler} labels={SCHEDULER_LABELS}
onChange={(value) => {
setScheduler(value);
}}
>
{renderSchedulers()}
</Select>
<Select
value={platform}
label="Platform"
onChange={(event) => {
setPlatform(event.target.value);
/>
<QueryList result={platforms} value={platform} labels={PLATFORM_LABELS}
onChange={(value) => {
setPlatform(value);
}}
>
{renderPlatforms()}
</Select>
/>
</Stack>
<ImageControl params={params} onChange={(newParams) => {
setParams(newParams);

View File

@ -13,7 +13,7 @@ export interface Config {
};
}
export async function loadConfig() {
export async function loadConfig(): Promise<Config> {
const configPath = new URL('./config.json', window.origin);
const configReq = await fetch(configPath);
if (configReq.status === STATUS_SUCCESS) {
@ -30,7 +30,9 @@ export async function main() {
const appElement = mustExist(document.getElementById('app'));
const app = ReactDOM.createRoot(appElement);
app.render(<QueryClientProvider client={query}><OnnxWeb client={client} /></QueryClientProvider>);
app.render(<QueryClientProvider client={query}>
<OnnxWeb client={client} />
</QueryClientProvider>);
}
window.addEventListener('load', () => {