Armin Friedl
a279965fed
All checks were successful
continuous-integration/drone/push Build is passing
214 lines
7.3 KiB
TypeScript
214 lines
7.3 KiB
TypeScript
import {
|
|
Configuration, DalleResponse,
|
|
DefaultApi,
|
|
RobertaEmotionResponse,
|
|
RobertaHateResponse,
|
|
RobertaIronyResponse,
|
|
RobertaOffensiveResponse,
|
|
RobertaSentimentResponse
|
|
} from "../service/openapi";
|
|
import {
|
|
Accordion,
|
|
Button,
|
|
Card,
|
|
Col,
|
|
Container,
|
|
Dropdown,
|
|
DropdownButton,
|
|
Form,
|
|
FormControl,
|
|
FormGroup, FormLabel, Image, InputGroup,
|
|
Row, Spinner,
|
|
Table
|
|
} from "react-bootstrap";
|
|
import styles from "../styles/TextInput.module.scss";
|
|
import {createRef, FormEvent, forwardRef, useCallback, useEffect, useState} from "react";
|
|
import _ from "lodash";
|
|
|
|
let debounce = _.debounce(async (fn) => await fn(), 10000)
|
|
|
|
export default function Artsy(props) {
|
|
const [text, setText] = useState("");
|
|
|
|
const [calculating, setCalculating] = useState(false)
|
|
const [model, setModel] = useState("1");
|
|
const [count, setCount] = useState("5");
|
|
const [prompt, setPrompt] = useState("")
|
|
const [artery, setArtery] = useState<Array<string>>(Array.of());
|
|
|
|
interface History {
|
|
model: string,
|
|
count: string,
|
|
prompt: string
|
|
artery: Array<string>
|
|
}
|
|
const [history, setHistory] = useState<Array<History>>(Array.of())
|
|
|
|
const configuration = new Configuration({
|
|
basePath: 'https://warp2.friedl.net'
|
|
});
|
|
|
|
const api = new DefaultApi(configuration);
|
|
|
|
let handleSubmit = async (e: FormEvent) => {
|
|
e.preventDefault();
|
|
if (!text) {
|
|
setText(undefined);
|
|
return;
|
|
}
|
|
|
|
setCalculating(true);
|
|
setPrompt("");
|
|
setArtery(Array.of());
|
|
|
|
try {
|
|
const r: DalleResponse = await api.getImageDalleGenerateGet({text: text, count: parseInt(count)});
|
|
setPrompt(text);
|
|
setArtery(r.imagePaths);
|
|
|
|
history.push({ model: model, count: count, prompt: prompt, artery: [...artery]});
|
|
setHistory(history)
|
|
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
|
|
setCalculating(false);
|
|
return false;
|
|
}
|
|
|
|
let renderCards = () => {
|
|
|
|
let cards = []
|
|
for(const p of artery) {
|
|
cards.push(
|
|
<Col key={p} className={"flex-grow-0"}>
|
|
<Card style={{width: '18rem', height: '100%'}}>
|
|
<Card.Body>
|
|
<Image src={p} />
|
|
</Card.Body>
|
|
</Card>
|
|
</Col>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<>{cards}</>
|
|
);
|
|
}
|
|
|
|
let renderHistory = () => {
|
|
let hist = []
|
|
|
|
let idx = 0
|
|
for(const h of history) {
|
|
|
|
let cards = []
|
|
for(const p of h.artery) {
|
|
cards.push(
|
|
<Col key={p} className={"flex-grow-0"}>
|
|
<Card style={{width: '18rem', height: '100%'}}>
|
|
<Card.Body>
|
|
<Image src={p} />
|
|
</Card.Body>
|
|
</Card>
|
|
</Col>
|
|
)
|
|
}
|
|
|
|
hist.push(
|
|
<>
|
|
<Row className={"mb-3 justify-content-center"} key={`${idx}-prompt`}>
|
|
<h5 style={{width: "auto"}} className={"text-muted"}>{h.prompt}</h5>
|
|
</Row>
|
|
<Row className={"justify-content-center gap-2 mb-5"} key={`${idx}-card`}>
|
|
{cards}
|
|
</Row>
|
|
</>
|
|
)
|
|
|
|
idx++;
|
|
}
|
|
|
|
return(
|
|
<>
|
|
{hist}
|
|
</>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Container fluid={true} className={"bg-primary pb-5"}>
|
|
<Container className={"pb-5 pt-2"}>
|
|
<Row xs={1} xl={2} className={"justify-content-center"}>
|
|
<Col>
|
|
<h1 className={`text-light`}>ALAS</h1>
|
|
</Col>
|
|
</Row>
|
|
</Container>
|
|
</Container>
|
|
<Container>
|
|
<Row xs={1} xl={2} className={`pb-5 justify-content-center`}>
|
|
<Form className={styles.inputForm} onSubmit={handleSubmit}>
|
|
<FormControl value={text}
|
|
placeholder={"Prompt..."}
|
|
onChange={(e) => setText(e.target.value)}
|
|
className={`${styles.textBox} mb-3`} as="textarea"
|
|
disabled={calculating}/>
|
|
|
|
<InputGroup className={"mb-3"}>
|
|
<InputGroup.Text id="model-addon">Model</InputGroup.Text>
|
|
<Form.Select aria-label="Model selection" className={"me-3"} disabled={calculating} value={model} onChange={(e) => setModel(e.currentTarget.value)}>
|
|
<option value="1">MINI</option>
|
|
<option value="2" disabled={true}>MEGA</option>
|
|
<option value="3" disabled={true}>MEGA FULL</option>
|
|
</Form.Select>
|
|
|
|
<InputGroup.Text id="number-addon"># of Images</InputGroup.Text>
|
|
<Form.Select aria-label="Number of generated images" className={"me-3"} onChange={(e) => setCount(e.currentTarget.value)} value={count} disabled={calculating}>
|
|
<option value="1">1</option>
|
|
<option value="2">2</option>
|
|
<option value="3">3</option>
|
|
<option value="4">4</option>
|
|
<option value="5">5</option>
|
|
<option value="6">6</option>
|
|
<option value="7">7</option>
|
|
<option value="8">8</option>
|
|
<option value="9">9</option>
|
|
<option value="10">10</option>
|
|
</Form.Select>
|
|
|
|
<Button className={"float-end"} type={"submit"} disabled={calculating}>Submit</Button>
|
|
</InputGroup>
|
|
|
|
</Form>
|
|
</Row>
|
|
<Row className={"justify-content-center mb-3"}>
|
|
<h1 style={{width: "auto"}} className={"text-primary"}>Art<sup>e<sub>r</sub>y</sup></h1>
|
|
</Row>
|
|
<Row className={"mb-3 justify-content-center"}>
|
|
<h5 style={{width: "auto"}} className={"text-muted"}>{prompt}</h5>
|
|
</Row>
|
|
<Row className={"justify-content-center gap-2"}>
|
|
{
|
|
calculating ? <Spinner animation={"border"}/> : renderCards()
|
|
}
|
|
</Row>
|
|
|
|
<Row className={"mt-5"} />
|
|
{
|
|
history.length > 1 &&
|
|
<Row className={"mt-5 justify-content-center"}>
|
|
<h2 style={{width: "auto"}} className={"text-muted"}>History</h2>
|
|
</Row>
|
|
}
|
|
<Row className={"justify-content-center gap-2"}>
|
|
{
|
|
history.length > 1 && renderHistory()
|
|
}
|
|
</Row>
|
|
</Container>
|
|
</>
|
|
)
|
|
}
|