diff --git a/gui/src/api/client.ts b/gui/src/api/client.ts new file mode 100644 index 00000000..1ca245ec --- /dev/null +++ b/gui/src/api/client.ts @@ -0,0 +1,28 @@ +export interface Txt2ImgParams { + prompt: string; + cfg: number; + steps: number; +} + +export interface ApiClient { + txt2img(params: Txt2ImgParams): Promise; +} + +export function makeClient(root: string, f = fetch): ApiClient { + return { + async txt2img(params: Txt2ImgParams): Promise { + const { prompt, cfg, steps } = params; + + const safePrompt = encodeURIComponent(prompt); + const url = `${root}/txt2img?prompt=${safePrompt}&steps=${steps.toFixed(0)}&cfg=${cfg.toFixed(0)}`; + const res = await f(url); + + if (res.status === 200) { + const imageBlob = await res.blob(); + return URL.createObjectURL(imageBlob); + } else { + throw new Error('request error'); + } + }, + } +} \ No newline at end of file diff --git a/gui/src/components/OnnxWeb.tsx b/gui/src/components/OnnxWeb.tsx index 49374736..124fe84d 100644 --- a/gui/src/components/OnnxWeb.tsx +++ b/gui/src/components/OnnxWeb.tsx @@ -1,9 +1,19 @@ import { TabContext, TabList, TabPanel } from '@mui/lab'; -import { Box, Container, Tab, Typography } from '@mui/material'; +import { Box, Container, MenuItem, Select, Tab, Typography } from '@mui/material'; import * as React from 'react'; -export function OnnxWeb() { - const [tab, setTab] = React.useState('1'); +import { ApiClient } from '../api/client.js'; +import { Txt2Img } from './Txt2Img.js'; + +const { useState } = React; + +export interface OnnxWebProps { + client: ApiClient; +} + +export function OnnxWeb(props: OnnxWebProps) { + const [tab, setTab] = useState('1'); + const [model, setModel] = useState('v1.5'); return (
@@ -13,6 +23,14 @@ export function OnnxWeb() { ONNX Web GUI + + + { @@ -23,9 +41,18 @@ export function OnnxWeb() { - txt2img - img2img - settings + + + txt2img using {model} + + + + + + img2img using {model} + + + settings for onnx-web
diff --git a/gui/src/components/Txt2Img.tsx b/gui/src/components/Txt2Img.tsx new file mode 100644 index 00000000..b703017b --- /dev/null +++ b/gui/src/components/Txt2Img.tsx @@ -0,0 +1,47 @@ +import { Box, Button, TextField } from "@mui/material"; +import * as React from 'react'; +import { ApiClient } from "../api/client"; + +const { useEffect, useState } = React; + +export interface Txt2ImgProps { + client: ApiClient; +} + +export function Txt2Img(props: Txt2ImgProps) { + const { client } = props; + const [image, setImage] = useState(''); + + const [cfg, setCfg] = useState(5); + const [prompt, setPrompt] = useState('an astronaut eating a hamburger'); + const [steps, setSteps] = useState(20); + + async function getImage() { + const image = await client.txt2img({ prompt, cfg, steps }); + console.log(prompt, image); + setImage(image); + } + + function renderImage() { + if (image === '') { + return
No image
; + } else { + return ; + } + } + + return + { + setCfg(parseInt(event.target.value, 10)); + }} /> + { + setSteps(parseInt(event.target.value, 10)); + }} /> + { + console.log('changing prompt', event.target.value); + setPrompt(event.target.value); + }} /> + + {renderImage()} + ; +} diff --git a/gui/src/config.ts b/gui/src/config.ts new file mode 100644 index 00000000..d8e64de2 --- /dev/null +++ b/gui/src/config.ts @@ -0,0 +1,5 @@ +export const CONFIG = { + api: { + root: 'http://ssube-desktop.home.holdmyran.ch:5000', + }, +}; diff --git a/gui/src/main.tsx b/gui/src/main.tsx index 84d099c7..1d848374 100644 --- a/gui/src/main.tsx +++ b/gui/src/main.tsx @@ -1,12 +1,15 @@ import { mustExist } from '@apextoaster/js-utils'; import * as React from 'react'; import ReactDOM from 'react-dom/client'; +import { makeClient } from './api/client'; import { OnnxWeb } from './components/OnnxWeb'; +import { CONFIG } from './config'; export function main() { const appElement = mustExist(document.getElementById('app')); const app = ReactDOM.createRoot(appElement); - app.render(); + const client = makeClient(CONFIG.api.root); + app.render(); } main();