mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
feat(ui): show last progress message & placeholder in generation progress panel
This commit is contained in:
@@ -1,19 +1,14 @@
|
||||
import { isImageField } from 'features/nodes/types/common';
|
||||
import { isCanvasOutputNodeId } from 'features/nodes/util/graph/graphBuilderUtils';
|
||||
import { round } from 'lodash-es';
|
||||
import type { S } from 'services/api/types';
|
||||
import { formatProgressMessage } from 'services/events/stores';
|
||||
import { objectEntries } from 'tsafe';
|
||||
|
||||
export const getProgressMessage = (data?: S['InvocationProgressEvent'] | null) => {
|
||||
if (!data) {
|
||||
return 'Generating';
|
||||
}
|
||||
|
||||
let message = data.message;
|
||||
if (data.percentage) {
|
||||
message += ` (${round(data.percentage * 100)}%)`;
|
||||
}
|
||||
return message;
|
||||
return formatProgressMessage(data);
|
||||
};
|
||||
|
||||
export const DROP_SHADOW = 'drop-shadow(0px 0px 4px rgb(0, 0, 0)) drop-shadow(0px 0px 4px rgba(0, 0, 0, 0.3))';
|
||||
|
||||
@@ -2,9 +2,12 @@ import { Flex } from '@invoke-ai/ui-library';
|
||||
import { ProgressImage } from 'features/gallery/components/ImageViewer/ProgressImage';
|
||||
import { memo } from 'react';
|
||||
|
||||
import { ProgressIndicator } from './ProgressIndicator';
|
||||
|
||||
export const GenerationProgressPanel = memo(() => (
|
||||
<Flex flexDir="column" w="full" h="full" overflow="hidden" p={2}>
|
||||
<Flex position="relative" flexDir="column" w="full" h="full" overflow="hidden" p={2}>
|
||||
<ProgressImage />
|
||||
<ProgressIndicator position="absolute" top={6} right={6} size={8} />
|
||||
</Flex>
|
||||
));
|
||||
GenerationProgressPanel.displayName = 'GenerationProgressPanel';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { SystemStyleObject } from '@invoke-ai/ui-library';
|
||||
import { Flex, Image } from '@invoke-ai/ui-library';
|
||||
import { Flex, Heading, Image } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
@@ -7,6 +7,7 @@ import { IAINoContentFallback } from 'common/components/IAIImageFallback';
|
||||
import { selectSystemSlice } from 'features/system/store/systemSlice';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { PiPulseBold } from 'react-icons/pi';
|
||||
import { useIsGenerationInProgress } from 'services/api/endpoints/queue';
|
||||
import { $lastProgressImage } from 'services/events/stores';
|
||||
|
||||
const selectShouldAntialiasProgressImage = createSelector(
|
||||
@@ -15,6 +16,7 @@ const selectShouldAntialiasProgressImage = createSelector(
|
||||
);
|
||||
|
||||
export const ProgressImage = memo(() => {
|
||||
const isGenerationInProgress = useIsGenerationInProgress();
|
||||
const progressImage = useStore($lastProgressImage);
|
||||
const shouldAntialiasProgressImage = useAppSelector(selectShouldAntialiasProgressImage);
|
||||
|
||||
@@ -25,7 +27,7 @@ export const ProgressImage = memo(() => {
|
||||
[shouldAntialiasProgressImage]
|
||||
);
|
||||
|
||||
if (!progressImage) {
|
||||
if (!isGenerationInProgress) {
|
||||
return (
|
||||
<Flex width="full" height="full" alignItems="center" justifyContent="center">
|
||||
<IAINoContentFallback icon={PiPulseBold} label="No Generation in Progress" />
|
||||
@@ -33,6 +35,14 @@ export const ProgressImage = memo(() => {
|
||||
);
|
||||
}
|
||||
|
||||
if (!progressImage) {
|
||||
return (
|
||||
<Flex width="full" height="full" alignItems="center" justifyContent="center" minW={0} minH={0}>
|
||||
<Heading>Waiting for Image</Heading>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Flex width="full" height="full" alignItems="center" justifyContent="center" minW={0} minH={0}>
|
||||
<Image
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { CircularProgressProps, SystemStyleObject } from '@invoke-ai/ui-library';
|
||||
import { CircularProgress, Tooltip } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { memo } from 'react';
|
||||
import { useIsGenerationInProgress } from 'services/api/endpoints/queue';
|
||||
import { $lastProgressEvent, formatProgressMessage } from 'services/events/stores';
|
||||
|
||||
const circleStyles: SystemStyleObject = {
|
||||
circle: {
|
||||
transitionProperty: 'none',
|
||||
transitionDuration: '0s',
|
||||
},
|
||||
};
|
||||
|
||||
export const ProgressIndicator = memo((props: CircularProgressProps) => {
|
||||
const isGenerationInProgress = useIsGenerationInProgress();
|
||||
const lastProgressEvent = useStore($lastProgressEvent);
|
||||
if (!isGenerationInProgress) {
|
||||
return null;
|
||||
}
|
||||
if (!lastProgressEvent) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Tooltip label={formatProgressMessage(lastProgressEvent)}>
|
||||
<CircularProgress
|
||||
size="14px"
|
||||
color="invokeBlue.500"
|
||||
thickness={14}
|
||||
isIndeterminate={!lastProgressEvent || lastProgressEvent.percentage === null}
|
||||
value={lastProgressEvent?.percentage ? lastProgressEvent.percentage * 100 : undefined}
|
||||
sx={circleStyles}
|
||||
{...props}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
});
|
||||
ProgressIndicator.displayName = 'ProgressMessage';
|
||||
@@ -396,3 +396,8 @@ export const selectCanvasQueueCounts = queueApi.endpoints.getQueueCountsByDestin
|
||||
export const enqueueMutationFixedCacheKeyOptions = {
|
||||
fixedCacheKey: 'enqueueBatch',
|
||||
} as const;
|
||||
|
||||
export const useIsGenerationInProgress = () => {
|
||||
const { data } = useGetQueueStatusQuery();
|
||||
return data && data.queue.in_progress > 0;
|
||||
};
|
||||
|
||||
@@ -21,10 +21,12 @@ export const $lastProgressMessage = computed($lastProgressEvent, (val) => {
|
||||
if (!val) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let message = val.message;
|
||||
if (val.percentage) {
|
||||
message += ` (${round(val.percentage * 100)}%)`;
|
||||
return formatProgressMessage(val);
|
||||
});
|
||||
export const formatProgressMessage = (data: S['InvocationProgressEvent']): string => {
|
||||
let message = data.message;
|
||||
if (data.percentage) {
|
||||
message += ` (${round(data.percentage * 100)}%)`;
|
||||
}
|
||||
return message;
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user