1
0
Fork 0

feat(gui): add error message when server is not available (fixes #48)

This commit is contained in:
Sean Sube 2023-01-14 11:25:53 -06:00
parent 3ad3299734
commit 65f2f4d953
3 changed files with 109 additions and 51 deletions

View File

@ -0,0 +1,53 @@
import { Alert, AlertTitle, Box, Container, Stack, Typography } from '@mui/material';
import * as React from 'react';
export interface OnnxErrorProps {
root: string;
}
export function OnnxError(props: OnnxErrorProps) {
return (
<Container>
<Box sx={{ my: 4 }}>
<Typography variant='h3' gutterBottom>
<a href='https://github.com/ssube/onnx-web'>ONNX Web</a>
</Typography>
</Box>
<Box sx={{ my: 4 }}>
<Stack spacing={2}>
<Alert severity='error'>
<AlertTitle>
Server Error
</AlertTitle>
Could not fetch parameters from the ONNX web API server at <code>{props.root}</code>.
</Alert>
<Typography variant='body1'>
This is a web UI for running ONNX models with GPU acceleration or in software, running locally or on a
remote machine.
</Typography>
<Typography variant='body1'>
The API runs on both Linux and Windows and provides access to the major functionality of diffusers, along
with metadata about the available models and accelerators, and the output of previous runs. Hardware
acceleration is supported on both AMD and Nvidia, with a CPU fallback capable of running on laptop-class
machines.
</Typography>
<Typography variant='body1'>
The GUI runs in all major browsers, including on mobile devices, and allows you to select the model and
accelerator being used, along with the prompt and other image parameters. The last few output images are
shown below the image controls, making it easy to refer back to previous parameters or save an image from
earlier.
</Typography>
<Typography variant='body1'>
Please <a href='https://github.com/ssube/onnx-web'>visit the Github project</a> for more information and
make sure that <a href='https://github.com/ssube/onnx-web#configuring-and-running-the-server'>your API
server is running</a> at <a href={props.root}>{props.root}</a>.
</Typography>
<Typography variant='body1' gutterBottom>
If you are trying to use a remote API server or an alternative port, you can put the address into the
query string, like <code>{window.location.origin}?api=http://localhost:5001</code>.
</Typography>
</Stack>
</Box>
</Container>
);
}

View File

@ -41,7 +41,7 @@ export function OnnxWeb(props: OnnxWebProps) {
<Container> <Container>
<Box sx={{ my: 4 }}> <Box sx={{ my: 4 }}>
<Typography variant='h3' gutterBottom> <Typography variant='h3' gutterBottom>
ONNX Web <a href='https://github.com/ssube/onnx-web'>ONNX Web</a>
</Typography> </Typography>
</Box> </Box>
<Box sx={{ mx: 4, my: 4 }}> <Box sx={{ mx: 4, my: 4 }}>

View File

@ -3,11 +3,12 @@ import { doesExist, mustExist } from '@apextoaster/js-utils';
import { merge } from 'lodash'; import { merge } from 'lodash';
import * as React from 'react'; import * as React from 'react';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import { QueryClient, QueryClientProvider } from 'react-query'; import { QueryCache, QueryClient, QueryClientProvider } from 'react-query';
import { createStore } from 'zustand'; import { createStore } from 'zustand';
import { createJSONStorage, persist } from 'zustand/middleware'; import { createJSONStorage, persist } from 'zustand/middleware';
import { makeClient } from './api/client.js'; import { makeClient } from './api/client.js';
import { OnnxError } from './components/OnnxError.js';
import { OnnxWeb } from './components/OnnxWeb.js'; import { OnnxWeb } from './components/OnnxWeb.js';
import { Config, loadConfig } from './config.js'; import { Config, loadConfig } from './config.js';
import { ClientContext, createStateSlices, OnnxState, StateContext } from './state.js'; import { ClientContext, createStateSlices, OnnxState, StateContext } from './state.js';
@ -31,59 +32,63 @@ export async function main() {
const root = getApiRoot(config); const root = getApiRoot(config);
const client = makeClient(root); const client = makeClient(root);
// load full params from the API server and merge with the initial client config
const params = await client.params();
merge(params, config.params);
// prep zustand with a slice for each tab, using local storage
const {
createDefaultSlice,
createHistorySlice,
createImg2ImgSlice,
createInpaintSlice,
createTxt2ImgSlice,
} = createStateSlices(params);
const state = createStore<OnnxState, [['zustand/persist', OnnxState]]>(persist((...slice) => ({
...createTxt2ImgSlice(...slice),
...createImg2ImgSlice(...slice),
...createInpaintSlice(...slice),
...createHistorySlice(...slice),
...createDefaultSlice(...slice),
}), {
name: 'onnx-web',
partialize(s) {
return {
...s,
img2img: {
...s.img2img,
source: undefined,
},
inpaint: {
...s.inpaint,
mask: undefined,
source: undefined,
},
};
},
storage: createJSONStorage(() => localStorage),
version: 3,
}));
// prep react-query client
const query = new QueryClient();
// prep react-dom // prep react-dom
const appElement = mustExist(document.getElementById('app')); const appElement = mustExist(document.getElementById('app'));
const app = ReactDOM.createRoot(appElement); const app = ReactDOM.createRoot(appElement);
// go try {
app.render(<QueryClientProvider client={query}> // load full params from the API server and merge with the initial client config
<ClientContext.Provider value={client}> const params = await client.params();
<StateContext.Provider value={state}> merge(params, config.params);
<OnnxWeb client={client} config={params} />
</StateContext.Provider> // prep zustand with a slice for each tab, using local storage
</ClientContext.Provider> const {
</QueryClientProvider>); createDefaultSlice,
createHistorySlice,
createImg2ImgSlice,
createInpaintSlice,
createTxt2ImgSlice,
} = createStateSlices(params);
const state = createStore<OnnxState, [['zustand/persist', OnnxState]]>(persist((...slice) => ({
...createTxt2ImgSlice(...slice),
...createImg2ImgSlice(...slice),
...createInpaintSlice(...slice),
...createHistorySlice(...slice),
...createDefaultSlice(...slice),
}), {
name: 'onnx-web',
partialize(s) {
return {
...s,
img2img: {
...s.img2img,
source: undefined,
},
inpaint: {
...s.inpaint,
mask: undefined,
source: undefined,
},
};
},
storage: createJSONStorage(() => localStorage),
version: 3,
}));
// prep react-query client
const query = new QueryClient();
// go
app.render(<QueryClientProvider client={query}>
<ClientContext.Provider value={client}>
<StateContext.Provider value={state}>
<OnnxWeb client={client} config={params} />
</StateContext.Provider>
</ClientContext.Provider>
</QueryClientProvider>);
} catch (err) {
app.render(<OnnxError root={root} />);
}
} }
window.addEventListener('load', () => { window.addEventListener('load', () => {