Skip to content

Commit

Permalink
feat(gui): add error message when server is not available (fixes #48)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed Jan 14, 2023
1 parent 3ad3299 commit 65f2f4d
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 51 deletions.
53 changes: 53 additions & 0 deletions gui/src/components/OnnxError.tsx
Original file line number Diff line number Diff line change
@@ -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>
);
}
2 changes: 1 addition & 1 deletion gui/src/components/OnnxWeb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function OnnxWeb(props: OnnxWebProps) {
<Container>
<Box sx={{ my: 4 }}>
<Typography variant='h3' gutterBottom>
ONNX Web
<a href='https://github.com/ssube/onnx-web'>ONNX Web</a>
</Typography>
</Box>
<Box sx={{ mx: 4, my: 4 }}>
Expand Down
105 changes: 55 additions & 50 deletions gui/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import { doesExist, mustExist } from '@apextoaster/js-utils';
import { merge } from 'lodash';
import * as React from 'react';
import ReactDOM from 'react-dom/client';
import { QueryClient, QueryClientProvider } from 'react-query';
import { QueryCache, QueryClient, QueryClientProvider } from 'react-query';
import { createStore } from 'zustand';
import { createJSONStorage, persist } from 'zustand/middleware';

import { makeClient } from './api/client.js';
import { OnnxError } from './components/OnnxError.js';
import { OnnxWeb } from './components/OnnxWeb.js';
import { Config, loadConfig } from './config.js';
import { ClientContext, createStateSlices, OnnxState, StateContext } from './state.js';
Expand All @@ -31,59 +32,63 @@ export async function main() {
const root = getApiRoot(config);
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
const appElement = mustExist(document.getElementById('app'));
const app = ReactDOM.createRoot(appElement);

// go
app.render(<QueryClientProvider client={query}>
<ClientContext.Provider value={client}>
<StateContext.Provider value={state}>
<OnnxWeb client={client} config={params} />
</StateContext.Provider>
</ClientContext.Provider>
</QueryClientProvider>);
try {
// 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();

// 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', () => {
Expand Down

0 comments on commit 65f2f4d

Please sign in to comment.