diff --git a/invokeai/frontend/web/src/app/NodeAPITest.tsx b/invokeai/frontend/web/src/app/NodeAPITest.tsx index a6f4427b60..270b54840f 100644 --- a/invokeai/frontend/web/src/app/NodeAPITest.tsx +++ b/invokeai/frontend/web/src/app/NodeAPITest.tsx @@ -114,6 +114,8 @@ const NodeAPITest = () => { return; } + setResultImages([]); + // set up socket.io listeners // TODO: suppose this should be handled in the socket.io middleware? @@ -190,10 +192,16 @@ const NodeAPITest = () => { Cancel Processing - - Create Session - + Create Session & Invoke + + {/* { colorScheme="accent" > Invoke - + */} { + const { activeTab } = state.ui; + const activeTabName = tabMap[activeTab]; + const nodeId = uuidv4(); + + return { + nodes: { + [nodeId]: { + id: nodeId, + ...mapTabToFunction(activeTabName)(state), + }, + }, + }; +}; diff --git a/invokeai/frontend/web/src/common/util/buildNodes.ts b/invokeai/frontend/web/src/common/util/buildNodes.ts index 273521d0f2..6973a97505 100644 --- a/invokeai/frontend/web/src/common/util/buildNodes.ts +++ b/invokeai/frontend/web/src/common/util/buildNodes.ts @@ -1,4 +1,3 @@ -import { v4 as uuidv4 } from 'uuid'; import { RootState } from 'app/store'; import { ImageToImageInvocation, @@ -12,10 +11,12 @@ import { // be todo add symmetry fields // be todo variations.... -export function buildTxt2ImgNode(state: RootState): TextToImageInvocation { +export function buildTxt2ImgNode( + state: RootState +): Omit { const { generation, system } = state; - const { shouldDisplayInProgressType, openModel } = system; + const { shouldDisplayInProgressType, model } = system; const { prompt, @@ -30,7 +31,6 @@ export function buildTxt2ImgNode(state: RootState): TextToImageInvocation { // missing fields in TextToImageInvocation: strength, hires_fix return { - id: uuidv4(), type: 'txt2img', prompt, seed, @@ -40,12 +40,14 @@ export function buildTxt2ImgNode(state: RootState): TextToImageInvocation { cfg_scale, sampler_name: sampler as TextToImageInvocation['sampler_name'], seamless, - model: openModel as string | undefined, + model, progress_images: shouldDisplayInProgressType === 'full-res', }; } -export function buildImg2ImgNode(state: RootState): ImageToImageInvocation { +export function buildImg2ImgNode( + state: RootState +): Omit { const { generation, system } = state; const { shouldDisplayInProgressType, openModel: model } = system; @@ -65,7 +67,6 @@ export function buildImg2ImgNode(state: RootState): ImageToImageInvocation { } = generation; return { - id: 'a', type: 'img2img', prompt, seed, @@ -86,7 +87,9 @@ export function buildImg2ImgNode(state: RootState): ImageToImageInvocation { }; } -export function buildFacetoolNode(state: RootState): RestoreFaceInvocation { +export function buildFacetoolNode( + state: RootState +): Omit { const { generation, postprocessing } = state; const { initialImage } = generation; @@ -95,7 +98,6 @@ export function buildFacetoolNode(state: RootState): RestoreFaceInvocation { // missing fields in RestoreFaceInvocation: type, codeformer_fidelity return { - id: uuidv4(), type: 'restore_face', image: { image_name: @@ -106,7 +108,9 @@ export function buildFacetoolNode(state: RootState): RestoreFaceInvocation { } // is this ESRGAN?? -export function buildUpscaleNode(state: RootState): UpscaleInvocation { +export function buildUpscaleNode( + state: RootState +): Omit { const { generation, postprocessing } = state; const { initialImage } = generation; @@ -115,7 +119,6 @@ export function buildUpscaleNode(state: RootState): UpscaleInvocation { // missing fields in UpscaleInvocation: denoise_str return { - id: uuidv4(), type: 'upscale', image: { image_name: diff --git a/invokeai/frontend/web/src/features/parameters/components/ProcessButtons/InvokeButton.tsx b/invokeai/frontend/web/src/features/parameters/components/ProcessButtons/InvokeButton.tsx index b68f245044..07363ded1a 100644 --- a/invokeai/frontend/web/src/features/parameters/components/ProcessButtons/InvokeButton.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/ProcessButtons/InvokeButton.tsx @@ -11,6 +11,7 @@ import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { useHotkeys } from 'react-hotkeys-hook'; import { useTranslation } from 'react-i18next'; import { FaPlay } from 'react-icons/fa'; +import { createSession } from 'services/thunks/session'; interface InvokeButton extends Omit { @@ -24,7 +25,8 @@ export default function InvokeButton(props: InvokeButton) { const activeTabName = useAppSelector(activeTabNameSelector); const handleClickGenerate = () => { - dispatch(generateImage(activeTabName)); + // dispatch(generateImage(activeTabName)); + dispatch(createSession()); }; const { t } = useTranslation(); diff --git a/invokeai/frontend/web/src/services/invokeMiddleware.ts b/invokeai/frontend/web/src/services/invokeMiddleware.ts new file mode 100644 index 0000000000..8b5909f98b --- /dev/null +++ b/invokeai/frontend/web/src/services/invokeMiddleware.ts @@ -0,0 +1,17 @@ +import { Middleware } from '@reduxjs/toolkit'; +import { setSessionId } from './apiSlice'; +import { invokeSession } from './thunks/session'; + +export const invokeMiddleware: Middleware = (store) => (next) => (action) => { + const { dispatch } = store; + + if (action.type === 'api/createSession/fulfilled' && action?.payload?.id) { + console.log('createSession.fulfilled'); + + dispatch(setSessionId(action.payload.id)); + // types are wrong but this works + dispatch(invokeSession({ sessionId: action.payload.id })); + } else { + next(action); + } +}; diff --git a/invokeai/frontend/web/src/services/thunks/session.ts b/invokeai/frontend/web/src/services/thunks/session.ts index 0c22fcd474..a1ce7260c9 100644 --- a/invokeai/frontend/web/src/services/thunks/session.ts +++ b/invokeai/frontend/web/src/services/thunks/session.ts @@ -1,5 +1,6 @@ import { createAppAsyncThunk } from 'app/storeUtils'; import { SessionsService } from 'services/api'; +import { buildGraph } from 'common/util/buildGraph'; /** * createSession thunk @@ -18,7 +19,16 @@ type CreateSessionRequestBody = Parameters< export const createSession = createAppAsyncThunk( 'api/createSession', async (arg: CreateSessionRequestBody, _thunkApi) => { - const response = await SessionsService.createSession({ requestBody: arg }); + let graph = arg; + if (!arg) { + const { getState } = _thunkApi; + const state = getState(); + graph = buildGraph(state); + } + + const response = await SessionsService.createSession({ + requestBody: graph, + }); return response; }