From 471719bbbe8fa74dc1f04da976144c1f730f929e Mon Sep 17 00:00:00 2001 From: chainchompa Date: Wed, 14 Aug 2024 08:47:02 -0400 Subject: [PATCH 1/4] add base prop for selectedWorkflow to allow loading a workflow on launch --- .../frontend/web/src/app/components/App.tsx | 20 +++++++++++++++++-- .../web/src/app/components/InvokeAIUI.tsx | 4 +++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/invokeai/frontend/web/src/app/components/App.tsx b/invokeai/frontend/web/src/app/components/App.tsx index 760eddbee8..c61f892f49 100644 --- a/invokeai/frontend/web/src/app/components/App.tsx +++ b/invokeai/frontend/web/src/app/components/App.tsx @@ -18,10 +18,11 @@ import { languageSelector } from 'features/system/store/systemSelectors'; import InvokeTabs from 'features/ui/components/InvokeTabs'; import type { InvokeTabName } from 'features/ui/store/tabMap'; import { setActiveTab } from 'features/ui/store/uiSlice'; +import { useGetAndLoadLibraryWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow'; import { AnimatePresence } from 'framer-motion'; import i18n from 'i18n'; import { size } from 'lodash-es'; -import { memo, useCallback, useEffect } from 'react'; +import { memo, useCallback, useEffect, useRef } from 'react'; import { ErrorBoundary } from 'react-error-boundary'; import { useGetOpenAPISchemaQuery } from 'services/api/endpoints/appInfo'; @@ -36,14 +37,16 @@ interface Props { imageName: string; action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters'; }; + selectedWorkflow?: string; destination?: InvokeTabName | undefined; } -const App = ({ config = DEFAULT_CONFIG, selectedImage, destination }: Props) => { +const App = ({ config = DEFAULT_CONFIG, selectedImage, selectedWorkflow, destination }: Props) => { const language = useAppSelector(languageSelector); const logger = useLogger('system'); const dispatch = useAppDispatch(); const clearStorage = useClearStorage(); + const hasLoadedRef = useRef(false); // singleton! useSocketIO(); @@ -70,6 +73,19 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage, destination }: Props) => } }, [dispatch, config, logger]); + const { getAndLoadWorkflow } = useGetAndLoadLibraryWorkflow({ + onSuccess: () => { + setActiveTab('workflows'); + }, + }); + + useEffect(() => { + if (selectedWorkflow && !hasLoadedRef.current) { + getAndLoadWorkflow(selectedWorkflow); + hasLoadedRef.current = true; + } + }, [selectedWorkflow, getAndLoadWorkflow]); + useEffect(() => { if (destination) { dispatch(setActiveTab(destination)); diff --git a/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx b/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx index 0a80b7e92d..f1e23ebf16 100644 --- a/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx +++ b/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx @@ -44,6 +44,7 @@ interface Props extends PropsWithChildren { imageName: string; action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters'; }; + selectedWorkflow?: string; destination?: InvokeTabName; customStarUi?: CustomStarUi; socketOptions?: Partial; @@ -64,6 +65,7 @@ const InvokeAIUI = ({ projectUrl, queueId, selectedImage, + selectedWorkflow, destination, customStarUi, socketOptions, @@ -221,7 +223,7 @@ const InvokeAIUI = ({ }> - + From af159acbdfbb50eb161d16ccbe044002626714f2 Mon Sep 17 00:00:00 2001 From: chainchompa Date: Wed, 14 Aug 2024 08:58:38 -0400 Subject: [PATCH 2/4] cleanup --- invokeai/frontend/web/src/app/components/InvokeAIUI.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx b/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx index f1e23ebf16..561a3e997b 100644 --- a/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx +++ b/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx @@ -223,7 +223,12 @@ const InvokeAIUI = ({ }> - + From 88648dca1a5fe2c9c1d4d0782749087f61162607 Mon Sep 17 00:00:00 2001 From: chainchompa Date: Wed, 14 Aug 2024 11:22:32 -0400 Subject: [PATCH 3/4] change selectedWorkflow to selectedWorkflowId --- invokeai/frontend/web/src/app/components/App.tsx | 10 +++++----- .../frontend/web/src/app/components/InvokeAIUI.tsx | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/invokeai/frontend/web/src/app/components/App.tsx b/invokeai/frontend/web/src/app/components/App.tsx index a918454a14..3b4448a12d 100644 --- a/invokeai/frontend/web/src/app/components/App.tsx +++ b/invokeai/frontend/web/src/app/components/App.tsx @@ -38,11 +38,11 @@ interface Props { imageName: string; action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters'; }; - selectedWorkflow?: string; + selectedWorkflowId?: string; destination?: InvokeTabName | undefined; } -const App = ({ config = DEFAULT_CONFIG, selectedImage, selectedWorkflow, destination }: Props) => { +const App = ({ config = DEFAULT_CONFIG, selectedImage, selectedWorkflowId, destination }: Props) => { const language = useAppSelector(languageSelector); const logger = useLogger('system'); const dispatch = useAppDispatch(); @@ -81,11 +81,11 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage, selectedWorkflow, destina }); useEffect(() => { - if (selectedWorkflow && !hasLoadedRef.current) { - getAndLoadWorkflow(selectedWorkflow); + if (selectedWorkflowId && !hasLoadedRef.current) { + getAndLoadWorkflow(selectedWorkflowId); hasLoadedRef.current = true; } - }, [selectedWorkflow, getAndLoadWorkflow]); + }, [selectedWorkflowId, getAndLoadWorkflow]); useEffect(() => { if (destination) { diff --git a/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx b/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx index 561a3e997b..5804902408 100644 --- a/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx +++ b/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx @@ -44,7 +44,7 @@ interface Props extends PropsWithChildren { imageName: string; action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters'; }; - selectedWorkflow?: string; + selectedWorkflowId?: string; destination?: InvokeTabName; customStarUi?: CustomStarUi; socketOptions?: Partial; @@ -65,7 +65,7 @@ const InvokeAIUI = ({ projectUrl, queueId, selectedImage, - selectedWorkflow, + selectedWorkflowId, destination, customStarUi, socketOptions, @@ -226,7 +226,7 @@ const InvokeAIUI = ({ From 268be97ba020d4a43b9afe5a9ef32500970cbc92 Mon Sep 17 00:00:00 2001 From: chainchompa Date: Thu, 15 Aug 2024 09:18:41 -0400 Subject: [PATCH 4/4] remove ref, make options optional for useGetLoadWorkflow --- invokeai/frontend/web/src/app/components/App.tsx | 12 +++--------- .../hooks/useGetAndLoadLibraryWorkflow.ts | 10 +++++----- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/invokeai/frontend/web/src/app/components/App.tsx b/invokeai/frontend/web/src/app/components/App.tsx index 3b4448a12d..41f3d97051 100644 --- a/invokeai/frontend/web/src/app/components/App.tsx +++ b/invokeai/frontend/web/src/app/components/App.tsx @@ -23,7 +23,7 @@ import { useGetAndLoadLibraryWorkflow } from 'features/workflowLibrary/hooks/use import { AnimatePresence } from 'framer-motion'; import i18n from 'i18n'; import { size } from 'lodash-es'; -import { memo, useCallback, useEffect, useRef } from 'react'; +import { memo, useCallback, useEffect } from 'react'; import { ErrorBoundary } from 'react-error-boundary'; import { useGetOpenAPISchemaQuery } from 'services/api/endpoints/appInfo'; @@ -47,7 +47,6 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage, selectedWorkflowId, desti const logger = useLogger('system'); const dispatch = useAppDispatch(); const clearStorage = useClearStorage(); - const hasLoadedRef = useRef(false); // singleton! useSocketIO(); @@ -74,16 +73,11 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage, selectedWorkflowId, desti } }, [dispatch, config, logger]); - const { getAndLoadWorkflow } = useGetAndLoadLibraryWorkflow({ - onSuccess: () => { - setActiveTab('workflows'); - }, - }); + const { getAndLoadWorkflow } = useGetAndLoadLibraryWorkflow(); useEffect(() => { - if (selectedWorkflowId && !hasLoadedRef.current) { + if (selectedWorkflowId) { getAndLoadWorkflow(selectedWorkflowId); - hasLoadedRef.current = true; } }, [selectedWorkflowId, getAndLoadWorkflow]); diff --git a/invokeai/frontend/web/src/features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow.ts b/invokeai/frontend/web/src/features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow.ts index 89933999bd..9f86d11860 100644 --- a/invokeai/frontend/web/src/features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow.ts +++ b/invokeai/frontend/web/src/features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow.ts @@ -15,9 +15,9 @@ type UseGetAndLoadLibraryWorkflowReturn = { getAndLoadWorkflowResult: ReturnType[1]; }; -type UseGetAndLoadLibraryWorkflow = (arg: UseGetAndLoadLibraryWorkflowOptions) => UseGetAndLoadLibraryWorkflowReturn; +type UseGetAndLoadLibraryWorkflow = (arg?: UseGetAndLoadLibraryWorkflowOptions) => UseGetAndLoadLibraryWorkflowReturn; -export const useGetAndLoadLibraryWorkflow: UseGetAndLoadLibraryWorkflow = ({ onSuccess, onError }) => { +export const useGetAndLoadLibraryWorkflow: UseGetAndLoadLibraryWorkflow = (arg) => { const dispatch = useAppDispatch(); const toast = useToast(); const { t } = useTranslation(); @@ -29,17 +29,17 @@ export const useGetAndLoadLibraryWorkflow: UseGetAndLoadLibraryWorkflow = ({ onS // This action expects a stringified workflow, instead of updating the routes and services we will just stringify it here dispatch(workflowLoadRequested({ data: { workflow: JSON.stringify(workflow), graph: null }, asCopy: false })); // No toast - the listener for this action does that after the workflow is loaded - onSuccess && onSuccess(); + arg?.onSuccess && arg.onSuccess(); } catch { toast({ id: `AUTH_ERROR_TOAST_${workflowsApi.endpoints.getWorkflow.name}`, title: t('toast.problemRetrievingWorkflow'), status: 'error', }); - onError && onError(); + arg?.onError && arg.onError(); } }, - [_getAndLoadWorkflow, dispatch, onSuccess, t, onError, toast] + [_getAndLoadWorkflow, dispatch, arg, t, toast] ); return { getAndLoadWorkflow, getAndLoadWorkflowResult };