Make Invoke Button also the progress bar (#3492)

Find on some screens the progress bar at top is hard to see, Bar should
only show when in progress


![Animation](https://github.com/invoke-ai/InvokeAI/assets/115216705/04f945d3-377b-4646-b125-1355e74b6b09)
This commit is contained in:
blessedcoolant 2023-06-02 19:30:45 +12:00 committed by GitHub
commit 82231369d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 166 additions and 61 deletions

View File

@ -1,27 +1,26 @@
import ImageUploader from 'common/components/ImageUploader';
import SiteHeader from 'features/system/components/SiteHeader';
import ProgressBar from 'features/system/components/ProgressBar';
import InvokeTabs from 'features/ui/components/InvokeTabs';
import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton';
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
import { Box, Flex, Grid, Portal } from '@chakra-ui/react';
import { APP_HEIGHT, APP_WIDTH } from 'theme/util/constants';
import { useLogger } from 'app/logging/useLogger';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { PartialAppConfig } from 'app/types/invokeai';
import ImageUploader from 'common/components/ImageUploader';
import Loading from 'common/components/Loading/Loading';
import GalleryDrawer from 'features/gallery/components/GalleryPanel';
import Lightbox from 'features/lightbox/components/Lightbox';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { memo, ReactNode, useCallback, useEffect, useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import Loading from 'common/components/Loading/Loading';
import { useIsApplicationReady } from 'features/system/hooks/useIsApplicationReady';
import { PartialAppConfig } from 'app/types/invokeai';
import { configChanged } from 'features/system/store/configSlice';
import SiteHeader from 'features/system/components/SiteHeader';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { useLogger } from 'app/logging/useLogger';
import ParametersDrawer from 'features/ui/components/ParametersDrawer';
import { useIsApplicationReady } from 'features/system/hooks/useIsApplicationReady';
import { configChanged } from 'features/system/store/configSlice';
import { languageSelector } from 'features/system/store/systemSelectors';
import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton';
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
import InvokeTabs from 'features/ui/components/InvokeTabs';
import ParametersDrawer from 'features/ui/components/ParametersDrawer';
import { AnimatePresence, motion } from 'framer-motion';
import i18n from 'i18n';
import Toaster from './Toaster';
import { ReactNode, memo, useCallback, useEffect, useState } from 'react';
import { APP_HEIGHT, APP_WIDTH } from 'theme/util/constants';
import GlobalHotkeys from './GlobalHotkeys';
import Toaster from './Toaster';
const DEFAULT_CONFIG = {};
@ -76,7 +75,6 @@ const App = ({
<Grid w="100vw" h="100vh" position="relative" overflow="hidden">
{isLightboxEnabled && <Lightbox />}
<ImageUploader>
<ProgressBar />
<Grid
gap={4}
p={4}

View File

@ -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 (
<Panel position="top-center">
<HStack>
<IAIButton colorScheme="accent" onClick={handleInvoke}>
Will it blend?
</IAIButton>
<NodeInvokeButton />
<IAIButton onClick={handleReloadSchema}>Reload Schema</IAIButton>
</HStack>
</Panel>

View File

@ -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<IAIButtonProps | IAIIconButtonProps, 'aria-label'> {
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 (
<Box style={{ flexGrow: 4 }} position="relative">
<Box style={{ position: 'relative' }}>
{!isReady && (
<Box
style={{
position: 'absolute',
bottom: '0',
left: '0',
right: '0',
height: '100%',
overflow: 'clip',
borderRadius: 4,
}}
>
<ProgressBar />
</Box>
)}
{iconButton ? (
<IAIIconButton
aria-label={t('parameters.invoke')}
type="submit"
icon={<FaPlay />}
isDisabled={!isReady}
onClick={handleInvoke}
flexGrow={1}
w="100%"
tooltip={t('parameters.invoke')}
tooltipProps={{ placement: 'bottom' }}
colorScheme="accent"
id="invoke-button"
{...rest}
/>
) : (
<IAIButton
aria-label={t('parameters.invoke')}
type="submit"
isDisabled={!isReady}
onClick={handleInvoke}
flexGrow={1}
w="100%"
colorScheme="accent"
id="invoke-button"
fontWeight={700}
{...rest}
>
Invoke
</IAIButton>
)}
</Box>
</Box>
);
}

View File

@ -7,6 +7,7 @@ import IAIIconButton, {
IAIIconButtonProps,
} from 'common/components/IAIIconButton';
import { clampSymmetrySteps } from 'features/parameters/store/generationSlice';
import ProgressBar from 'features/system/components/ProgressBar';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { useCallback } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
@ -43,38 +44,55 @@ export default function InvokeButton(props: InvokeButton) {
);
return (
<Box style={{ flexGrow: 4 }}>
{iconButton ? (
<IAIIconButton
aria-label={t('parameters.invoke')}
type="submit"
icon={<FaPlay />}
isDisabled={!isReady}
onClick={handleInvoke}
flexGrow={1}
w="100%"
tooltip={t('parameters.invoke')}
tooltipProps={{ placement: 'bottom' }}
colorScheme="accent"
id="invoke-button"
{...rest}
/>
) : (
<IAIButton
aria-label={t('parameters.invoke')}
type="submit"
isDisabled={!isReady}
onClick={handleInvoke}
flexGrow={1}
w="100%"
colorScheme="accent"
id="invoke-button"
fontWeight={700}
{...rest}
>
Invoke
</IAIButton>
)}
<Box style={{ flexGrow: 4 }} position="relative">
<Box style={{ position: 'relative' }}>
{!isReady && (
<Box
style={{
position: 'absolute',
bottom: '0',
left: '0',
right: '0',
height: '100%',
overflow: 'clip',
borderRadius: 4,
}}
>
<ProgressBar />
</Box>
)}
{iconButton ? (
<IAIIconButton
aria-label={t('parameters.invoke')}
type="submit"
icon={<FaPlay />}
isDisabled={!isReady}
onClick={handleInvoke}
flexGrow={1}
w="100%"
tooltip={t('parameters.invoke')}
tooltipProps={{ placement: 'bottom' }}
colorScheme="accent"
id="invoke-button"
{...rest}
/>
) : (
<IAIButton
aria-label={t('parameters.invoke')}
type="submit"
isDisabled={!isReady}
onClick={handleInvoke}
flexGrow={1}
w="100%"
colorScheme="accent"
id="invoke-button"
fontWeight={700}
{...rest}
>
Invoke
</IAIButton>
)}
</Box>
</Box>
);
}

View File

@ -5,7 +5,6 @@ import { SystemState } from 'features/system/store/systemSlice';
import { isEqual } from 'lodash-es';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { PROGRESS_BAR_THICKNESS } from 'theme/util/constants';
import { systemSelector } from '../store/systemSelectors';
const progressBarSelector = createSelector(
@ -35,7 +34,7 @@ const ProgressBar = () => {
value={value}
aria-label={t('accessibility.invokeProgressBar')}
isIndeterminate={isProcessing && !currentStatusHasSteps}
height={PROGRESS_BAR_THICKNESS}
height="full"
/>
);
};

View File

@ -20,7 +20,7 @@ const invokeAIFilledTrack = defineStyle((_props) => ({
const invokeAITrack = defineStyle((_props) => {
return {
bg: 'base.800',
bg: 'none',
};
});