From 7620bacc01e7381c6720eb1cff19f610e01d2956 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Fri, 2 Jun 2023 17:55:15 +1200 Subject: [PATCH] feat: Add temporary NodeInvokeButton --- .../components/panels/TopCenterPanel.tsx | 10 +- .../nodes/components/ui/NodeInvokeButton.tsx | 96 +++++++++++++++++++ 2 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 invokeai/frontend/web/src/features/nodes/components/ui/NodeInvokeButton.tsx diff --git a/invokeai/frontend/web/src/features/nodes/components/panels/TopCenterPanel.tsx b/invokeai/frontend/web/src/features/nodes/components/panels/TopCenterPanel.tsx index b97bf423e1..b961a9f403 100644 --- a/invokeai/frontend/web/src/features/nodes/components/panels/TopCenterPanel.tsx +++ b/invokeai/frontend/web/src/features/nodes/components/panels/TopCenterPanel.tsx @@ -1,18 +1,14 @@ import { HStack } from '@chakra-ui/react'; -import { userInvoked } from 'app/store/actions'; import { useAppDispatch } from 'app/store/storeHooks'; import IAIButton from 'common/components/IAIButton'; import { memo, useCallback } from 'react'; import { Panel } from 'reactflow'; import { receivedOpenAPISchema } from 'services/thunks/schema'; +import NodeInvokeButton from '../ui/NodeInvokeButton'; const TopCenterPanel = () => { const dispatch = useAppDispatch(); - const handleInvoke = useCallback(() => { - dispatch(userInvoked('nodes')); - }, [dispatch]); - const handleReloadSchema = useCallback(() => { dispatch(receivedOpenAPISchema()); }, [dispatch]); @@ -20,9 +16,7 @@ const TopCenterPanel = () => { return ( - - Will it blend? - + Reload Schema diff --git a/invokeai/frontend/web/src/features/nodes/components/ui/NodeInvokeButton.tsx b/invokeai/frontend/web/src/features/nodes/components/ui/NodeInvokeButton.tsx new file mode 100644 index 0000000000..4b916abd2e --- /dev/null +++ b/invokeai/frontend/web/src/features/nodes/components/ui/NodeInvokeButton.tsx @@ -0,0 +1,96 @@ +import { Box } from '@chakra-ui/react'; +import { readinessSelector } from 'app/selectors/readinessSelector'; +import { userInvoked } from 'app/store/actions'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import IAIButton, { IAIButtonProps } from 'common/components/IAIButton'; +import IAIIconButton, { + IAIIconButtonProps, +} from 'common/components/IAIIconButton'; +import ProgressBar from 'features/system/components/ProgressBar'; +import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; +import { useCallback } from 'react'; +import { useHotkeys } from 'react-hotkeys-hook'; +import { useTranslation } from 'react-i18next'; +import { FaPlay } from 'react-icons/fa'; + +interface InvokeButton + extends Omit { + iconButton?: boolean; +} + +export default function NodeInvokeButton(props: InvokeButton) { + const { iconButton = false, ...rest } = props; + const dispatch = useAppDispatch(); + const { isReady } = useAppSelector(readinessSelector); + const activeTabName = useAppSelector(activeTabNameSelector); + + const handleInvoke = useCallback(() => { + dispatch(userInvoked('nodes')); + }, [dispatch]); + + const { t } = useTranslation(); + + useHotkeys( + ['ctrl+enter', 'meta+enter'], + handleInvoke, + { + enabled: () => isReady, + preventDefault: true, + enableOnFormTags: ['input', 'textarea', 'select'], + }, + [isReady, activeTabName] + ); + + return ( + + + {!isReady && ( + + + + )} + {iconButton ? ( + } + isDisabled={!isReady} + onClick={handleInvoke} + flexGrow={1} + w="100%" + tooltip={t('parameters.invoke')} + tooltipProps={{ placement: 'bottom' }} + colorScheme="accent" + id="invoke-button" + {...rest} + /> + ) : ( + + Invoke + + )} + + + ); +}