mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-02-17 18:55:18 -05:00
fixed merge conflicts
This commit is contained in:
@@ -1,40 +1,38 @@
|
||||
import { Progress } from '@chakra-ui/react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { stateSelector } from 'app/store/store';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { SystemState } from 'features/system/store/systemSlice';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { systemSelector } from '../store/systemSelectors';
|
||||
|
||||
import { useGetQueueStatusQuery } from 'services/api/endpoints/queue';
|
||||
const progressBarSelector = createSelector(
|
||||
systemSelector,
|
||||
(system: SystemState) => {
|
||||
stateSelector,
|
||||
({ system }) => {
|
||||
return {
|
||||
isProcessing: system.isProcessing,
|
||||
currentStep: system.currentStep,
|
||||
totalSteps: system.totalSteps,
|
||||
currentStatusHasSteps: system.currentStatusHasSteps,
|
||||
isConnected: system.isConnected,
|
||||
hasSteps: Boolean(system.denoiseProgress),
|
||||
value: (system.denoiseProgress?.percentage ?? 0) * 100,
|
||||
};
|
||||
},
|
||||
{
|
||||
memoizeOptions: { resultEqualityCheck: isEqual },
|
||||
}
|
||||
defaultSelectorOptions
|
||||
);
|
||||
|
||||
const ProgressBar = () => {
|
||||
const { t } = useTranslation();
|
||||
const { isProcessing, currentStep, totalSteps, currentStatusHasSteps } =
|
||||
useAppSelector(progressBarSelector);
|
||||
|
||||
const value = currentStep ? Math.round((currentStep * 100) / totalSteps) : 0;
|
||||
const { data: queueStatus } = useGetQueueStatusQuery();
|
||||
const { hasSteps, value, isConnected } = useAppSelector(progressBarSelector);
|
||||
|
||||
return (
|
||||
<Progress
|
||||
value={value}
|
||||
aria-label={t('accessibility.invokeProgressBar')}
|
||||
isIndeterminate={isProcessing && !currentStatusHasSteps}
|
||||
height="full"
|
||||
isIndeterminate={
|
||||
isConnected && Boolean(queueStatus?.queue.in_progress) && !hasSteps
|
||||
}
|
||||
h="full"
|
||||
w="full"
|
||||
borderRadius={2}
|
||||
colorScheme="accent"
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -49,13 +49,13 @@ import { useTranslation } from 'react-i18next';
|
||||
import { LogLevelName } from 'roarr';
|
||||
import { useGetAppConfigQuery } from 'services/api/endpoints/appInfo';
|
||||
import { useFeatureStatus } from '../../hooks/useFeatureStatus';
|
||||
import { LANGUAGES } from '../../store/constants';
|
||||
import { languageSelector } from '../../store/systemSelectors';
|
||||
import { languageChanged } from '../../store/systemSlice';
|
||||
import SettingSwitch from './SettingSwitch';
|
||||
import SettingsClearIntermediates from './SettingsClearIntermediates';
|
||||
import SettingsSchedulers from './SettingsSchedulers';
|
||||
import StyledFlex from './StyledFlex';
|
||||
import { LANGUAGES } from 'features/system/store/types';
|
||||
|
||||
const selector = createSelector(
|
||||
[stateSelector],
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Flex, Icon, Text } from '@chakra-ui/react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { stateSelector } from 'app/store/store';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
@@ -8,27 +9,17 @@ import { memo, useMemo, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaCircle } from 'react-icons/fa';
|
||||
import { useHoverDirty } from 'react-use';
|
||||
import { systemSelector } from '../store/systemSelectors';
|
||||
import { useGetQueueStatusQuery } from 'services/api/endpoints/queue';
|
||||
import { STATUS_TRANSLATION_KEYS } from '../store/types';
|
||||
|
||||
const statusIndicatorSelector = createSelector(
|
||||
systemSelector,
|
||||
(system) => {
|
||||
const {
|
||||
isConnected,
|
||||
isProcessing,
|
||||
statusTranslationKey,
|
||||
currentIteration,
|
||||
totalIterations,
|
||||
currentStatusHasSteps,
|
||||
} = system;
|
||||
stateSelector,
|
||||
({ system }) => {
|
||||
const { isConnected, status } = system;
|
||||
|
||||
return {
|
||||
isConnected,
|
||||
isProcessing,
|
||||
currentIteration,
|
||||
totalIterations,
|
||||
statusTranslationKey,
|
||||
currentStatusHasSteps,
|
||||
statusTranslationKey: STATUS_TRANSLATION_KEYS[status],
|
||||
};
|
||||
},
|
||||
defaultSelectorOptions
|
||||
@@ -47,35 +38,24 @@ const LIGHT_COLOR_MAP = {
|
||||
};
|
||||
|
||||
const StatusIndicator = () => {
|
||||
const {
|
||||
isConnected,
|
||||
isProcessing,
|
||||
currentIteration,
|
||||
totalIterations,
|
||||
statusTranslationKey,
|
||||
} = useAppSelector(statusIndicatorSelector);
|
||||
const { isConnected, statusTranslationKey } = useAppSelector(
|
||||
statusIndicatorSelector
|
||||
);
|
||||
const { t } = useTranslation();
|
||||
const ref = useRef(null);
|
||||
const { data: queueStatus } = useGetQueueStatusQuery();
|
||||
|
||||
const statusString = useMemo(() => {
|
||||
if (isProcessing) {
|
||||
const statusColor = useMemo(() => {
|
||||
if (!isConnected) {
|
||||
return 'error';
|
||||
}
|
||||
|
||||
if (queueStatus?.queue.in_progress) {
|
||||
return 'working';
|
||||
}
|
||||
|
||||
if (isConnected) {
|
||||
return 'ok';
|
||||
}
|
||||
|
||||
return 'error';
|
||||
}, [isProcessing, isConnected]);
|
||||
|
||||
const iterationsText = useMemo(() => {
|
||||
if (!(currentIteration && totalIterations)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return ` (${currentIteration}/${totalIterations})`;
|
||||
}, [currentIteration, totalIterations]);
|
||||
return 'ok';
|
||||
}, [queueStatus?.queue.in_progress, isConnected]);
|
||||
|
||||
const isHovered = useHoverDirty(ref);
|
||||
|
||||
@@ -103,12 +83,11 @@ const StatusIndicator = () => {
|
||||
fontWeight: '600',
|
||||
pb: '1px',
|
||||
userSelect: 'none',
|
||||
color: LIGHT_COLOR_MAP[statusString],
|
||||
_dark: { color: DARK_COLOR_MAP[statusString] },
|
||||
color: LIGHT_COLOR_MAP[statusColor],
|
||||
_dark: { color: DARK_COLOR_MAP[statusColor] },
|
||||
}}
|
||||
>
|
||||
{t(statusTranslationKey as ResourceKey)}
|
||||
{iterationsText}
|
||||
</Text>
|
||||
</motion.div>
|
||||
)}
|
||||
@@ -117,8 +96,8 @@ const StatusIndicator = () => {
|
||||
as={FaCircle}
|
||||
sx={{
|
||||
boxSize: '0.5rem',
|
||||
color: LIGHT_COLOR_MAP[statusString],
|
||||
_dark: { color: DARK_COLOR_MAP[statusString] },
|
||||
color: LIGHT_COLOR_MAP[statusColor],
|
||||
_dark: { color: DARK_COLOR_MAP[statusColor] },
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
|
||||
@@ -24,8 +24,8 @@ export const initialConfigState: AppConfig = {
|
||||
iterations: {
|
||||
initial: 1,
|
||||
min: 1,
|
||||
sliderMax: 20,
|
||||
inputMax: 9999,
|
||||
sliderMax: 1000,
|
||||
inputMax: 10000,
|
||||
fineStep: 1,
|
||||
coarseStep: 1,
|
||||
},
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import i18n from 'i18n';
|
||||
|
||||
export const LANGUAGES = {
|
||||
ar: i18n.t('common.langArabic', { lng: 'ar' }),
|
||||
nl: i18n.t('common.langDutch', { lng: 'nl' }),
|
||||
en: i18n.t('common.langEnglish', { lng: 'en' }),
|
||||
fr: i18n.t('common.langFrench', { lng: 'fr' }),
|
||||
de: i18n.t('common.langGerman', { lng: 'de' }),
|
||||
he: i18n.t('common.langHebrew', { lng: 'he' }),
|
||||
it: i18n.t('common.langItalian', { lng: 'it' }),
|
||||
ja: i18n.t('common.langJapanese', { lng: 'ja' }),
|
||||
ko: i18n.t('common.langKorean', { lng: 'ko' }),
|
||||
pl: i18n.t('common.langPolish', { lng: 'pl' }),
|
||||
pt_BR: i18n.t('common.langBrPortuguese', { lng: 'pt_BR' }),
|
||||
pt: i18n.t('common.langPortuguese', { lng: 'pt' }),
|
||||
ru: i18n.t('common.langRussian', { lng: 'ru' }),
|
||||
zh_CN: i18n.t('common.langSimplifiedChinese', { lng: 'zh_CN' }),
|
||||
es: i18n.t('common.langSpanish', { lng: 'es' }),
|
||||
uk: i18n.t('common.langUkranian', { lng: 'ua' }),
|
||||
};
|
||||
@@ -1,21 +1,7 @@
|
||||
import { SystemState } from './systemSlice';
|
||||
import { SystemState } from './types';
|
||||
|
||||
/**
|
||||
* System slice persist denylist
|
||||
*/
|
||||
export const systemPersistDenylist: (keyof SystemState)[] = [
|
||||
'currentIteration',
|
||||
'currentStep',
|
||||
'isCancelable',
|
||||
'isConnected',
|
||||
'isESRGANAvailable',
|
||||
'isGFPGANAvailable',
|
||||
'isProcessing',
|
||||
'totalIterations',
|
||||
'totalSteps',
|
||||
'isCancelScheduled',
|
||||
'progressImage',
|
||||
'wereModelsReceived',
|
||||
'isPersisted',
|
||||
'isUploading',
|
||||
'denoiseProgress',
|
||||
'status',
|
||||
];
|
||||
|
||||
@@ -1,21 +1,11 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { RootState } from 'app/store/store';
|
||||
import { stateSelector } from 'app/store/store';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
|
||||
export const systemSelector = (state: RootState) => state.system;
|
||||
|
||||
export const toastQueueSelector = (state: RootState) => state.system.toastQueue;
|
||||
|
||||
export const languageSelector = createSelector(
|
||||
systemSelector,
|
||||
(system) => system.language,
|
||||
stateSelector,
|
||||
({ system }) => system.language,
|
||||
defaultSelectorOptions
|
||||
);
|
||||
|
||||
export const isProcessingSelector = (state: RootState) =>
|
||||
state.system.isProcessing;
|
||||
|
||||
export const selectIsBusy = createSelector(
|
||||
(state: RootState) => state,
|
||||
(state) => state.system.isProcessing || !state.system.isConnected
|
||||
);
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import { UseToastOptions } from '@chakra-ui/react';
|
||||
import { PayloadAction, createSlice, isAnyOf } from '@reduxjs/toolkit';
|
||||
import { InvokeLogLevel } from 'app/logging/logger';
|
||||
import { userInvoked } from 'app/store/actions';
|
||||
import { t } from 'i18next';
|
||||
import { get, startCase, truncate, upperFirst } from 'lodash-es';
|
||||
import { LogLevelName } from 'roarr';
|
||||
import {
|
||||
isAnySessionRejected,
|
||||
sessionCanceled,
|
||||
} from 'services/api/thunks/session';
|
||||
import { isAnySessionRejected } from 'services/api/thunks/session';
|
||||
import {
|
||||
appSocketConnected,
|
||||
appSocketDisconnected,
|
||||
@@ -18,124 +13,39 @@ import {
|
||||
appSocketInvocationError,
|
||||
appSocketInvocationRetrievalError,
|
||||
appSocketInvocationStarted,
|
||||
appSocketModelLoadCompleted,
|
||||
appSocketModelLoadStarted,
|
||||
appSocketQueueItemStatusChanged,
|
||||
appSocketSessionRetrievalError,
|
||||
appSocketSubscribed,
|
||||
appSocketUnsubscribed,
|
||||
} from 'services/events/actions';
|
||||
import { ProgressImage } from 'services/events/types';
|
||||
import { calculateStepPercentage } from '../util/calculateStepPercentage';
|
||||
import { makeToast } from '../util/makeToast';
|
||||
import { LANGUAGES } from './constants';
|
||||
import { SystemState, LANGUAGES } from './types';
|
||||
import { zPydanticValidationError } from './zodSchemas';
|
||||
|
||||
export type CancelStrategy = 'immediate' | 'scheduled';
|
||||
|
||||
export interface SystemState {
|
||||
isGFPGANAvailable: boolean;
|
||||
isESRGANAvailable: boolean;
|
||||
isConnected: boolean;
|
||||
isProcessing: boolean;
|
||||
shouldConfirmOnDelete: boolean;
|
||||
currentStep: number;
|
||||
totalSteps: number;
|
||||
currentIteration: number;
|
||||
totalIterations: number;
|
||||
currentStatusHasSteps: boolean;
|
||||
isCancelable: boolean;
|
||||
enableImageDebugging: boolean;
|
||||
toastQueue: UseToastOptions[];
|
||||
/**
|
||||
* The current progress image
|
||||
*/
|
||||
progressImage: ProgressImage | null;
|
||||
/**
|
||||
* The current socket session id
|
||||
*/
|
||||
sessionId: string | null;
|
||||
/**
|
||||
* Cancel strategy
|
||||
*/
|
||||
cancelType: CancelStrategy;
|
||||
/**
|
||||
* Whether or not a scheduled cancelation is pending
|
||||
*/
|
||||
isCancelScheduled: boolean;
|
||||
/**
|
||||
* Array of node IDs that we want to handle when events received
|
||||
*/
|
||||
subscribedNodeIds: string[];
|
||||
/**
|
||||
* Whether or not the available models were received
|
||||
*/
|
||||
wereModelsReceived: boolean;
|
||||
/**
|
||||
* The console output logging level
|
||||
*/
|
||||
consoleLogLevel: InvokeLogLevel;
|
||||
shouldLogToConsole: boolean;
|
||||
// TODO: probably better to not store keys here, should just be a string that maps to the translation key
|
||||
statusTranslationKey: string;
|
||||
/**
|
||||
* When a session is canceled, its ID is stored here until a new session is created.
|
||||
*/
|
||||
canceledSession: string;
|
||||
isPersisted: boolean;
|
||||
shouldAntialiasProgressImage: boolean;
|
||||
language: keyof typeof LANGUAGES;
|
||||
isUploading: boolean;
|
||||
shouldUseNSFWChecker: boolean;
|
||||
shouldUseWatermarker: boolean;
|
||||
shouldDisableInformationalPopovers: boolean;
|
||||
}
|
||||
|
||||
export const initialSystemState: SystemState = {
|
||||
isConnected: false,
|
||||
isProcessing: false,
|
||||
isGFPGANAvailable: true,
|
||||
isESRGANAvailable: true,
|
||||
shouldConfirmOnDelete: true,
|
||||
currentStep: 0,
|
||||
totalSteps: 0,
|
||||
currentIteration: 0,
|
||||
totalIterations: 0,
|
||||
currentStatusHasSteps: false,
|
||||
isCancelable: true,
|
||||
enableImageDebugging: false,
|
||||
toastQueue: [],
|
||||
progressImage: null,
|
||||
denoiseProgress: null,
|
||||
shouldAntialiasProgressImage: false,
|
||||
sessionId: null,
|
||||
cancelType: 'immediate',
|
||||
isCancelScheduled: false,
|
||||
subscribedNodeIds: [],
|
||||
wereModelsReceived: false,
|
||||
consoleLogLevel: 'debug',
|
||||
shouldLogToConsole: true,
|
||||
statusTranslationKey: 'common.statusDisconnected',
|
||||
canceledSession: '',
|
||||
isPersisted: false,
|
||||
language: 'en',
|
||||
isUploading: false,
|
||||
shouldUseNSFWChecker: false,
|
||||
shouldUseWatermarker: false,
|
||||
shouldDisableInformationalPopovers: false,
|
||||
status: 'DISCONNECTED',
|
||||
};
|
||||
|
||||
export const systemSlice = createSlice({
|
||||
name: 'system',
|
||||
initialState: initialSystemState,
|
||||
reducers: {
|
||||
setIsProcessing: (state, action: PayloadAction<boolean>) => {
|
||||
state.isProcessing = action.payload;
|
||||
},
|
||||
setCurrentStatus: (state, action: PayloadAction<string>) => {
|
||||
state.statusTranslationKey = action.payload;
|
||||
},
|
||||
setShouldConfirmOnDelete: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldConfirmOnDelete = action.payload;
|
||||
},
|
||||
setIsCancelable: (state, action: PayloadAction<boolean>) => {
|
||||
state.isCancelable = action.payload;
|
||||
},
|
||||
setEnableImageDebugging: (state, action: PayloadAction<boolean>) => {
|
||||
state.enableImageDebugging = action.payload;
|
||||
},
|
||||
@@ -145,30 +55,6 @@ export const systemSlice = createSlice({
|
||||
clearToastQueue: (state) => {
|
||||
state.toastQueue = [];
|
||||
},
|
||||
/**
|
||||
* A cancel was scheduled
|
||||
*/
|
||||
cancelScheduled: (state) => {
|
||||
state.isCancelScheduled = true;
|
||||
},
|
||||
/**
|
||||
* The scheduled cancel was aborted
|
||||
*/
|
||||
scheduledCancelAborted: (state) => {
|
||||
state.isCancelScheduled = false;
|
||||
},
|
||||
/**
|
||||
* The cancel type was changed
|
||||
*/
|
||||
cancelTypeChanged: (state, action: PayloadAction<CancelStrategy>) => {
|
||||
state.cancelType = action.payload;
|
||||
},
|
||||
/**
|
||||
* The array of subscribed node ids was changed
|
||||
*/
|
||||
subscribedNodeIdsSet: (state, action: PayloadAction<string[]>) => {
|
||||
state.subscribedNodeIds = action.payload;
|
||||
},
|
||||
consoleLogLevelChanged: (state, action: PayloadAction<LogLevelName>) => {
|
||||
state.consoleLogLevel = action.payload;
|
||||
},
|
||||
@@ -181,15 +67,9 @@ export const systemSlice = createSlice({
|
||||
) => {
|
||||
state.shouldAntialiasProgressImage = action.payload;
|
||||
},
|
||||
isPersistedChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.isPersisted = action.payload;
|
||||
},
|
||||
languageChanged: (state, action: PayloadAction<keyof typeof LANGUAGES>) => {
|
||||
state.language = action.payload;
|
||||
},
|
||||
progressImageSet(state, action: PayloadAction<ProgressImage | null>) {
|
||||
state.progressImage = action.payload;
|
||||
},
|
||||
shouldUseNSFWCheckerChanged(state, action: PayloadAction<boolean>) {
|
||||
state.shouldUseNSFWChecker = action.payload;
|
||||
},
|
||||
@@ -204,34 +84,13 @@ export const systemSlice = createSlice({
|
||||
},
|
||||
},
|
||||
extraReducers(builder) {
|
||||
/**
|
||||
* Socket Subscribed
|
||||
*/
|
||||
builder.addCase(appSocketSubscribed, (state, action) => {
|
||||
state.sessionId = action.payload.sessionId;
|
||||
state.canceledSession = '';
|
||||
});
|
||||
|
||||
/**
|
||||
* Socket Unsubscribed
|
||||
*/
|
||||
builder.addCase(appSocketUnsubscribed, (state) => {
|
||||
state.sessionId = null;
|
||||
});
|
||||
|
||||
/**
|
||||
* Socket Connected
|
||||
*/
|
||||
builder.addCase(appSocketConnected, (state) => {
|
||||
state.isConnected = true;
|
||||
state.isCancelable = true;
|
||||
state.isProcessing = false;
|
||||
state.currentStatusHasSteps = false;
|
||||
state.currentStep = 0;
|
||||
state.totalSteps = 0;
|
||||
state.currentIteration = 0;
|
||||
state.totalIterations = 0;
|
||||
state.statusTranslationKey = 'common.statusConnected';
|
||||
state.denoiseProgress = null;
|
||||
state.status = 'CONNECTED';
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -239,106 +98,73 @@ export const systemSlice = createSlice({
|
||||
*/
|
||||
builder.addCase(appSocketDisconnected, (state) => {
|
||||
state.isConnected = false;
|
||||
state.isProcessing = false;
|
||||
state.isCancelable = true;
|
||||
state.currentStatusHasSteps = false;
|
||||
state.currentStep = 0;
|
||||
state.totalSteps = 0;
|
||||
// state.currentIteration = 0;
|
||||
// state.totalIterations = 0;
|
||||
state.statusTranslationKey = 'common.statusDisconnected';
|
||||
state.denoiseProgress = null;
|
||||
state.status = 'DISCONNECTED';
|
||||
});
|
||||
|
||||
/**
|
||||
* Invocation Started
|
||||
*/
|
||||
builder.addCase(appSocketInvocationStarted, (state) => {
|
||||
state.isCancelable = true;
|
||||
state.isProcessing = true;
|
||||
state.currentStatusHasSteps = false;
|
||||
state.currentStep = 0;
|
||||
state.totalSteps = 0;
|
||||
// state.currentIteration = 0;
|
||||
// state.totalIterations = 0;
|
||||
state.statusTranslationKey = 'common.statusGenerating';
|
||||
state.denoiseProgress = null;
|
||||
state.status = 'PROCESSING';
|
||||
});
|
||||
|
||||
/**
|
||||
* Generator Progress
|
||||
*/
|
||||
builder.addCase(appSocketGeneratorProgress, (state, action) => {
|
||||
const { step, total_steps, progress_image } = action.payload.data;
|
||||
const {
|
||||
step,
|
||||
total_steps,
|
||||
order,
|
||||
progress_image,
|
||||
graph_execution_state_id: session_id,
|
||||
} = action.payload.data;
|
||||
|
||||
state.isProcessing = true;
|
||||
state.isCancelable = true;
|
||||
// state.currentIteration = 0;
|
||||
// state.totalIterations = 0;
|
||||
state.currentStatusHasSteps = true;
|
||||
state.currentStep = step + 1; // TODO: step starts at -1, think this is a bug
|
||||
state.totalSteps = total_steps;
|
||||
state.progressImage = progress_image ?? null;
|
||||
state.statusTranslationKey = 'common.statusGenerating';
|
||||
state.denoiseProgress = {
|
||||
step,
|
||||
total_steps,
|
||||
order,
|
||||
percentage: calculateStepPercentage(step, total_steps, order),
|
||||
progress_image,
|
||||
session_id,
|
||||
};
|
||||
|
||||
state.status = 'PROCESSING';
|
||||
});
|
||||
|
||||
/**
|
||||
* Invocation Complete
|
||||
*/
|
||||
builder.addCase(appSocketInvocationComplete, (state, action) => {
|
||||
const { data } = action.payload;
|
||||
|
||||
// state.currentIteration = 0;
|
||||
// state.totalIterations = 0;
|
||||
state.currentStatusHasSteps = false;
|
||||
state.currentStep = 0;
|
||||
state.totalSteps = 0;
|
||||
state.statusTranslationKey = 'common.statusProcessingComplete';
|
||||
|
||||
if (state.canceledSession === data.graph_execution_state_id) {
|
||||
state.isProcessing = false;
|
||||
state.isCancelable = true;
|
||||
}
|
||||
builder.addCase(appSocketInvocationComplete, (state) => {
|
||||
state.denoiseProgress = null;
|
||||
state.status = 'CONNECTED';
|
||||
});
|
||||
|
||||
/**
|
||||
* Graph Execution State Complete
|
||||
*/
|
||||
builder.addCase(appSocketGraphExecutionStateComplete, (state) => {
|
||||
state.isProcessing = false;
|
||||
state.isCancelable = false;
|
||||
state.isCancelScheduled = false;
|
||||
state.currentStep = 0;
|
||||
state.totalSteps = 0;
|
||||
state.statusTranslationKey = 'common.statusConnected';
|
||||
state.progressImage = null;
|
||||
state.denoiseProgress = null;
|
||||
state.status = 'CONNECTED';
|
||||
});
|
||||
|
||||
/**
|
||||
* User Invoked
|
||||
*/
|
||||
|
||||
builder.addCase(userInvoked, (state) => {
|
||||
state.isProcessing = true;
|
||||
state.isCancelable = true;
|
||||
state.currentStatusHasSteps = false;
|
||||
state.statusTranslationKey = 'common.statusPreparing';
|
||||
builder.addCase(appSocketModelLoadStarted, (state) => {
|
||||
state.status = 'LOADING_MODEL';
|
||||
});
|
||||
|
||||
/**
|
||||
* Session Canceled - FULFILLED
|
||||
*/
|
||||
builder.addCase(sessionCanceled.fulfilled, (state, action) => {
|
||||
state.canceledSession = action.meta.arg.session_id;
|
||||
state.isProcessing = false;
|
||||
state.isCancelable = false;
|
||||
state.isCancelScheduled = false;
|
||||
state.currentStep = 0;
|
||||
state.totalSteps = 0;
|
||||
state.statusTranslationKey = 'common.statusConnected';
|
||||
state.progressImage = null;
|
||||
builder.addCase(appSocketModelLoadCompleted, (state) => {
|
||||
state.status = 'CONNECTED';
|
||||
});
|
||||
|
||||
state.toastQueue.push(
|
||||
makeToast({ title: t('toast.canceled'), status: 'warning' })
|
||||
);
|
||||
builder.addCase(appSocketQueueItemStatusChanged, (state, action) => {
|
||||
if (
|
||||
['completed', 'canceled', 'failed'].includes(action.payload.data.status)
|
||||
) {
|
||||
state.status = 'CONNECTED';
|
||||
state.denoiseProgress = null;
|
||||
}
|
||||
});
|
||||
|
||||
// *** Matchers - must be after all cases ***
|
||||
@@ -348,14 +174,6 @@ export const systemSlice = createSlice({
|
||||
* Session Created - REJECTED
|
||||
*/
|
||||
builder.addMatcher(isAnySessionRejected, (state, action) => {
|
||||
state.isProcessing = false;
|
||||
state.isCancelable = false;
|
||||
state.isCancelScheduled = false;
|
||||
state.currentStep = 0;
|
||||
state.totalSteps = 0;
|
||||
state.statusTranslationKey = 'common.statusConnected';
|
||||
state.progressImage = null;
|
||||
|
||||
let errorDescription = undefined;
|
||||
const duration = 5000;
|
||||
|
||||
@@ -399,16 +217,6 @@ export const systemSlice = createSlice({
|
||||
* Any server error
|
||||
*/
|
||||
builder.addMatcher(isAnyServerError, (state, action) => {
|
||||
state.isProcessing = false;
|
||||
state.isCancelable = true;
|
||||
// state.currentIteration = 0;
|
||||
// state.totalIterations = 0;
|
||||
state.currentStatusHasSteps = false;
|
||||
state.currentStep = 0;
|
||||
state.totalSteps = 0;
|
||||
state.statusTranslationKey = 'common.statusError';
|
||||
state.progressImage = null;
|
||||
|
||||
state.toastQueue.push(
|
||||
makeToast({
|
||||
title: t('toast.serverError'),
|
||||
@@ -421,23 +229,14 @@ export const systemSlice = createSlice({
|
||||
});
|
||||
|
||||
export const {
|
||||
setIsProcessing,
|
||||
setShouldConfirmOnDelete,
|
||||
setCurrentStatus,
|
||||
setIsCancelable,
|
||||
setEnableImageDebugging,
|
||||
addToast,
|
||||
clearToastQueue,
|
||||
cancelScheduled,
|
||||
scheduledCancelAborted,
|
||||
cancelTypeChanged,
|
||||
subscribedNodeIdsSet,
|
||||
consoleLogLevelChanged,
|
||||
shouldLogToConsoleChanged,
|
||||
isPersistedChanged,
|
||||
shouldAntialiasProgressImageChanged,
|
||||
languageChanged,
|
||||
progressImageSet,
|
||||
shouldUseNSFWCheckerChanged,
|
||||
shouldUseWatermarkerChanged,
|
||||
setShouldDisableInformationalPopovers,
|
||||
|
||||
63
invokeai/frontend/web/src/features/system/store/types.ts
Normal file
63
invokeai/frontend/web/src/features/system/store/types.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { UseToastOptions } from '@chakra-ui/react';
|
||||
import { InvokeLogLevel } from 'app/logging/logger';
|
||||
import i18n from 'i18n';
|
||||
import { ProgressImage } from 'services/events/types';
|
||||
|
||||
export type SystemStatus =
|
||||
| 'CONNECTED'
|
||||
| 'DISCONNECTED'
|
||||
| 'PROCESSING'
|
||||
| 'ERROR'
|
||||
| 'LOADING_MODEL';
|
||||
|
||||
export type DenoiseProgress = {
|
||||
session_id: string;
|
||||
progress_image: ProgressImage | null | undefined;
|
||||
step: number;
|
||||
total_steps: number;
|
||||
order: number;
|
||||
percentage: number;
|
||||
};
|
||||
|
||||
export interface SystemState {
|
||||
isConnected: boolean;
|
||||
shouldConfirmOnDelete: boolean;
|
||||
enableImageDebugging: boolean;
|
||||
toastQueue: UseToastOptions[];
|
||||
denoiseProgress: DenoiseProgress | null;
|
||||
consoleLogLevel: InvokeLogLevel;
|
||||
shouldLogToConsole: boolean;
|
||||
shouldAntialiasProgressImage: boolean;
|
||||
language: keyof typeof LANGUAGES;
|
||||
shouldUseNSFWChecker: boolean;
|
||||
shouldUseWatermarker: boolean;
|
||||
status: SystemStatus;
|
||||
shouldDisableInformationalPopovers: boolean;
|
||||
}
|
||||
|
||||
export const LANGUAGES = {
|
||||
ar: i18n.t('common.langArabic', { lng: 'ar' }),
|
||||
nl: i18n.t('common.langDutch', { lng: 'nl' }),
|
||||
en: i18n.t('common.langEnglish', { lng: 'en' }),
|
||||
fr: i18n.t('common.langFrench', { lng: 'fr' }),
|
||||
de: i18n.t('common.langGerman', { lng: 'de' }),
|
||||
he: i18n.t('common.langHebrew', { lng: 'he' }),
|
||||
it: i18n.t('common.langItalian', { lng: 'it' }),
|
||||
ja: i18n.t('common.langJapanese', { lng: 'ja' }),
|
||||
ko: i18n.t('common.langKorean', { lng: 'ko' }),
|
||||
pl: i18n.t('common.langPolish', { lng: 'pl' }),
|
||||
pt_BR: i18n.t('common.langBrPortuguese', { lng: 'pt_BR' }),
|
||||
pt: i18n.t('common.langPortuguese', { lng: 'pt' }),
|
||||
ru: i18n.t('common.langRussian', { lng: 'ru' }),
|
||||
zh_CN: i18n.t('common.langSimplifiedChinese', { lng: 'zh_CN' }),
|
||||
es: i18n.t('common.langSpanish', { lng: 'es' }),
|
||||
uk: i18n.t('common.langUkranian', { lng: 'ua' }),
|
||||
};
|
||||
|
||||
export const STATUS_TRANSLATION_KEYS: Record<SystemStatus, string> = {
|
||||
CONNECTED: 'common.statusConnected',
|
||||
DISCONNECTED: 'common.statusDisconnected',
|
||||
PROCESSING: 'common.statusProcessing',
|
||||
ERROR: 'common.statusError',
|
||||
LOADING_MODEL: 'common.statusLoadingModel',
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
export const calculateStepPercentage = (
|
||||
step: number,
|
||||
total_steps: number,
|
||||
order: number
|
||||
) => {
|
||||
if (total_steps === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// we add one extra to step so that the progress bar will be full when denoise completes
|
||||
|
||||
if (order === 2) {
|
||||
return Math.floor((step + 1 + 1) / 2) / Math.floor((total_steps + 1) / 2);
|
||||
}
|
||||
|
||||
return (step + 1 + 1) / (total_steps + 1);
|
||||
};
|
||||
Reference in New Issue
Block a user