diff --git a/gui/src/api/client.ts b/gui/src/api/client.ts index 4584baa2..b14be99d 100644 --- a/gui/src/api/client.ts +++ b/gui/src/api/client.ts @@ -1,4 +1,4 @@ -import { doesExist, NotImplementedError } from '@apextoaster/js-utils'; +import { doesExist } from '@apextoaster/js-utils'; import { ConfigParams } from '../config.js'; @@ -43,13 +43,11 @@ export type Txt2ImgResponse = Required; export interface InpaintParams extends BaseImgParams { mask: Blob; source: Blob; -} -export interface OutpaintParams extends Img2ImgParams { - up: boolean; - down: boolean; - left: boolean; - right: boolean; + left?: number; + right?: number; + top?: number; + bottom?: number; } export interface ApiResponse { @@ -72,9 +70,7 @@ export interface ApiClient { img2img(params: Img2ImgParams): Promise; txt2img(params: Txt2ImgParams): Promise; - inpaint(params: InpaintParams): Promise; - outpaint(params: OutpaintParams): Promise; ready(params: ApiResponse): Promise; } @@ -214,6 +210,23 @@ export function makeClient(root: string, f = fetch): ApiClient { const url = makeImageURL(root, 'inpaint', params); + if (doesExist(params.left)) { + url.searchParams.append('left', params.left.toFixed(0)); + } + + + if (doesExist(params.right)) { + url.searchParams.append('right', params.right.toFixed(0)); + } + + if (doesExist(params.top)) { + url.searchParams.append('top', params.top.toFixed(0)); + } + + if (doesExist(params.bottom)) { + url.searchParams.append('bottom', params.bottom.toFixed(0)); + } + const body = new FormData(); body.append('mask', params.mask, 'mask'); body.append('source', params.source, 'source'); @@ -226,9 +239,6 @@ export function makeClient(root: string, f = fetch): ApiClient { // eslint-disable-next-line no-return-await return await pending; }, - async outpaint() { - throw new NotImplementedError(); - }, async ready(params: ApiResponse): Promise { const path = makeApiUrl(root, 'ready'); path.searchParams.append('output', params.output.key); @@ -240,7 +250,7 @@ export function makeClient(root: string, f = fetch): ApiClient { } export async function parseApiResponse(root: string, res: Response): Promise { - type LimitedResponse = Omit & {output: string}; + type LimitedResponse = Omit & { output: string }; if (res.status === STATUS_SUCCESS) { const data = await res.json() as LimitedResponse; diff --git a/gui/src/components/Inpaint.tsx b/gui/src/components/Inpaint.tsx index f84d4f55..f441937d 100644 --- a/gui/src/components/Inpaint.tsx +++ b/gui/src/components/Inpaint.tsx @@ -9,6 +9,7 @@ import { ClientContext, StateContext } from '../state.js'; import { ImageControl } from './ImageControl.js'; import { ImageInput } from './ImageInput.js'; import { MaskCanvas } from './MaskCanvas.js'; +import { OutpaintControl } from './OutpaintControl.js'; const { useContext } = React; @@ -88,6 +89,7 @@ export function Inpaint(props: InpaintProps) { setInpaint(newParams); }} /> + ; diff --git a/gui/src/components/OutpaintControl.tsx b/gui/src/components/OutpaintControl.tsx new file mode 100644 index 00000000..d620936c --- /dev/null +++ b/gui/src/components/OutpaintControl.tsx @@ -0,0 +1,73 @@ +import { mustExist } from '@apextoaster/js-utils'; +import { Stack } from '@mui/material'; +import * as React from 'react'; +import { useContext } from 'react'; +import { useStore } from 'zustand'; + +import { ConfigParams } from '../config.js'; +import { StateContext } from '../state.js'; +import { NumericField } from './NumericField.js'; + +export interface OutpaintControlProps { + config: ConfigParams; +} + +export function OutpaintControl(props: OutpaintControlProps) { + const { config } = props; + + const state = mustExist(useContext(StateContext)); + const params = useStore(state, (s) => s.inpaint); + // eslint-disable-next-line @typescript-eslint/unbound-method + const setInpaint = useStore(state, (s) => s.setInpaint); + + return + { + setInpaint({ + left, + }); + }} + /> + { + setInpaint({ + right, + }); + }} + /> + { + setInpaint({ + top, + }); + }} + /> + { + setInpaint({ + bottom, + }); + }} + /> + ; +} diff --git a/gui/src/state.ts b/gui/src/state.ts index 22e2bed6..89887090 100644 --- a/gui/src/state.ts +++ b/gui/src/state.ts @@ -114,6 +114,10 @@ export function createStateSlices(base: ConfigParams) { ...defaults, mask: null, source: null, + left: 0, + right: 0, + top: 0, + bottom: 0, }, setInpaint(params) { set((prev) => ({ @@ -129,6 +133,10 @@ export function createStateSlices(base: ConfigParams) { ...defaults, mask: null, source: null, + left: 0, + right: 0, + top: 0, + bottom: 0, }, }); },