mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): remove Console and redux logging state
This commit is contained in:
parent
bffdede0fa
commit
6d6b986a66
@ -1,5 +1,4 @@
|
|||||||
import ImageUploader from 'common/components/ImageUploader';
|
import ImageUploader from 'common/components/ImageUploader';
|
||||||
import Console from 'features/system/components/Console';
|
|
||||||
import ProgressBar from 'features/system/components/ProgressBar';
|
import ProgressBar from 'features/system/components/ProgressBar';
|
||||||
import SiteHeader from 'features/system/components/SiteHeader';
|
import SiteHeader from 'features/system/components/SiteHeader';
|
||||||
import InvokeTabs from 'features/ui/components/InvokeTabs';
|
import InvokeTabs from 'features/ui/components/InvokeTabs';
|
||||||
@ -121,9 +120,6 @@ const App = ({ config = DEFAULT_CONFIG, children }: Props) => {
|
|||||||
<Portal>
|
<Portal>
|
||||||
<FloatingGalleryButton />
|
<FloatingGalleryButton />
|
||||||
</Portal>
|
</Portal>
|
||||||
<Portal>
|
|
||||||
<Console />
|
|
||||||
</Portal>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -12,7 +12,6 @@ import {
|
|||||||
removeImage,
|
removeImage,
|
||||||
} from 'features/gallery/store/gallerySlice';
|
} from 'features/gallery/store/gallerySlice';
|
||||||
import {
|
import {
|
||||||
addLogEntry,
|
|
||||||
generationRequested,
|
generationRequested,
|
||||||
modelChangeRequested,
|
modelChangeRequested,
|
||||||
modelConvertRequested,
|
modelConvertRequested,
|
||||||
|
@ -6,7 +6,6 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
import * as InvokeAI from 'app/types/invokeai';
|
import * as InvokeAI from 'app/types/invokeai';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
addLogEntry,
|
|
||||||
addToast,
|
addToast,
|
||||||
errorOccurred,
|
errorOccurred,
|
||||||
processingCanceled,
|
processingCanceled,
|
||||||
|
@ -1,197 +0,0 @@
|
|||||||
import { Flex, Text, Tooltip } from '@chakra-ui/react';
|
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
|
||||||
import {
|
|
||||||
errorSeen,
|
|
||||||
setShouldShowLogViewer,
|
|
||||||
SystemState,
|
|
||||||
} from 'features/system/store/systemSlice';
|
|
||||||
import { isEqual } from 'lodash-es';
|
|
||||||
import { Resizable } from 're-resizable';
|
|
||||||
import { memo, useLayoutEffect, useRef, useState } from 'react';
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { FaAngleDoubleDown, FaCode, FaMinus } from 'react-icons/fa';
|
|
||||||
import { systemSelector } from '../store/systemSelectors';
|
|
||||||
|
|
||||||
const logSelector = createSelector(
|
|
||||||
systemSelector,
|
|
||||||
(system: SystemState) => system.log,
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
// We don't need a deep equality check for this selector.
|
|
||||||
resultEqualityCheck: (a, b) => a.length === b.length,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const consoleSelector = createSelector(
|
|
||||||
systemSelector,
|
|
||||||
(system: SystemState) => {
|
|
||||||
return {
|
|
||||||
shouldShowLogViewer: system.shouldShowLogViewer,
|
|
||||||
hasError: system.hasError,
|
|
||||||
wasErrorSeen: system.wasErrorSeen,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basic log viewer, floats on bottom of page.
|
|
||||||
*/
|
|
||||||
const Console = () => {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const log = useAppSelector(logSelector);
|
|
||||||
const { shouldShowLogViewer, hasError, wasErrorSeen } =
|
|
||||||
useAppSelector(consoleSelector);
|
|
||||||
|
|
||||||
// Rudimentary autoscroll
|
|
||||||
const [shouldAutoscroll, setShouldAutoscroll] = useState<boolean>(true);
|
|
||||||
const viewerRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If autoscroll is on, scroll to the bottom when:
|
|
||||||
* - log updates
|
|
||||||
* - viewer is toggled
|
|
||||||
*
|
|
||||||
* Also scroll to the bottom whenever autoscroll is turned on.
|
|
||||||
*/
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
if (viewerRef.current !== null && shouldAutoscroll) {
|
|
||||||
viewerRef.current.scrollTop = viewerRef.current.scrollHeight;
|
|
||||||
}
|
|
||||||
}, [shouldAutoscroll, log, shouldShowLogViewer]);
|
|
||||||
|
|
||||||
const handleClickLogViewerToggle = () => {
|
|
||||||
dispatch(errorSeen());
|
|
||||||
dispatch(setShouldShowLogViewer(!shouldShowLogViewer));
|
|
||||||
};
|
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
'`',
|
|
||||||
() => {
|
|
||||||
dispatch(setShouldShowLogViewer(!shouldShowLogViewer));
|
|
||||||
},
|
|
||||||
[shouldShowLogViewer]
|
|
||||||
);
|
|
||||||
|
|
||||||
useHotkeys('esc', () => {
|
|
||||||
dispatch(setShouldShowLogViewer(false));
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleOnScroll = () => {
|
|
||||||
if (!viewerRef.current) return;
|
|
||||||
if (
|
|
||||||
shouldAutoscroll &&
|
|
||||||
viewerRef.current.scrollTop <
|
|
||||||
viewerRef.current.scrollHeight - viewerRef.current.clientHeight
|
|
||||||
) {
|
|
||||||
setShouldAutoscroll(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{shouldShowLogViewer && (
|
|
||||||
<Resizable
|
|
||||||
defaultSize={{
|
|
||||||
width: '100%',
|
|
||||||
height: 200,
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
position: 'fixed',
|
|
||||||
insetInlineStart: 0,
|
|
||||||
bottom: 0,
|
|
||||||
zIndex: 1,
|
|
||||||
}}
|
|
||||||
maxHeight="90vh"
|
|
||||||
>
|
|
||||||
<Flex
|
|
||||||
sx={{
|
|
||||||
flexDirection: 'column',
|
|
||||||
width: '100vw',
|
|
||||||
overflow: 'auto',
|
|
||||||
direction: 'column',
|
|
||||||
fontFamily: 'monospace',
|
|
||||||
pt: 0,
|
|
||||||
pr: 4,
|
|
||||||
pb: 4,
|
|
||||||
pl: 12,
|
|
||||||
borderTopWidth: 5,
|
|
||||||
bg: 'base.850',
|
|
||||||
borderColor: 'base.700',
|
|
||||||
zIndex: 2,
|
|
||||||
}}
|
|
||||||
ref={viewerRef}
|
|
||||||
onScroll={handleOnScroll}
|
|
||||||
>
|
|
||||||
{log.map((entry, i) => {
|
|
||||||
const { timestamp, message, level } = entry;
|
|
||||||
const colorScheme = level === 'info' ? 'base' : level;
|
|
||||||
return (
|
|
||||||
<Flex
|
|
||||||
key={i}
|
|
||||||
sx={{
|
|
||||||
gap: 2,
|
|
||||||
color: `${colorScheme}.300`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text fontWeight="600">{timestamp}:</Text>
|
|
||||||
<Text wordBreak="break-all">{message}</Text>
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Flex>
|
|
||||||
</Resizable>
|
|
||||||
)}
|
|
||||||
{shouldShowLogViewer && (
|
|
||||||
<Tooltip
|
|
||||||
hasArrow
|
|
||||||
label={shouldAutoscroll ? 'Autoscroll On' : 'Autoscroll Off'}
|
|
||||||
>
|
|
||||||
<IAIIconButton
|
|
||||||
size="sm"
|
|
||||||
aria-label={t('accessibility.toggleAutoscroll')}
|
|
||||||
icon={<FaAngleDoubleDown />}
|
|
||||||
onClick={() => setShouldAutoscroll(!shouldAutoscroll)}
|
|
||||||
isChecked={shouldAutoscroll}
|
|
||||||
sx={{
|
|
||||||
position: 'fixed',
|
|
||||||
insetInlineStart: 2,
|
|
||||||
bottom: 12,
|
|
||||||
zIndex: 1,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
<Tooltip
|
|
||||||
hasArrow
|
|
||||||
label={shouldShowLogViewer ? 'Hide Console' : 'Show Console'}
|
|
||||||
>
|
|
||||||
<IAIIconButton
|
|
||||||
size="sm"
|
|
||||||
aria-label={t('accessibility.toggleLogViewer')}
|
|
||||||
icon={shouldShowLogViewer ? <FaMinus /> : <FaCode />}
|
|
||||||
onClick={handleClickLogViewerToggle}
|
|
||||||
sx={{
|
|
||||||
position: 'fixed',
|
|
||||||
insetInlineStart: 2,
|
|
||||||
bottom: 2,
|
|
||||||
zIndex: 1,
|
|
||||||
}}
|
|
||||||
colorScheme={hasError || !wasErrorSeen ? 'error' : 'base'}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(Console);
|
|
@ -14,7 +14,6 @@ import {
|
|||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import i18n from 'i18n';
|
import i18n from 'i18n';
|
||||||
import { isImageOutput } from 'services/types/guards';
|
|
||||||
import { ProgressImage } from 'services/events/types';
|
import { ProgressImage } from 'services/events/types';
|
||||||
import { initialImageSelected } from 'features/parameters/store/generationSlice';
|
import { initialImageSelected } from 'features/parameters/store/generationSlice';
|
||||||
import { makeToast } from '../hooks/useToastWatcher';
|
import { makeToast } from '../hooks/useToastWatcher';
|
||||||
@ -22,7 +21,7 @@ import { sessionCanceled, sessionInvoked } from 'services/thunks/session';
|
|||||||
import { receivedModels } from 'services/thunks/model';
|
import { receivedModels } from 'services/thunks/model';
|
||||||
import { parsedOpenAPISchema } from 'features/nodes/store/nodesSlice';
|
import { parsedOpenAPISchema } from 'features/nodes/store/nodesSlice';
|
||||||
import { LogLevelName } from 'roarr';
|
import { LogLevelName } from 'roarr';
|
||||||
import { InvokeLogLevel, VALID_LOG_LEVELS } from 'app/logging/useLogger';
|
import { InvokeLogLevel } from 'app/logging/useLogger';
|
||||||
|
|
||||||
export type LogLevel = 'info' | 'warning' | 'error';
|
export type LogLevel = 'info' | 'warning' | 'error';
|
||||||
|
|
||||||
@ -44,7 +43,6 @@ export interface SystemState
|
|||||||
extends InvokeAI.SystemStatus,
|
extends InvokeAI.SystemStatus,
|
||||||
InvokeAI.SystemConfig {
|
InvokeAI.SystemConfig {
|
||||||
shouldDisplayInProgressType: InProgressImageType;
|
shouldDisplayInProgressType: InProgressImageType;
|
||||||
log: Array<LogEntry>;
|
|
||||||
shouldShowLogViewer: boolean;
|
shouldShowLogViewer: boolean;
|
||||||
isGFPGANAvailable: boolean;
|
isGFPGANAvailable: boolean;
|
||||||
isESRGANAvailable: boolean;
|
isESRGANAvailable: boolean;
|
||||||
@ -108,7 +106,6 @@ export interface SystemState
|
|||||||
const initialSystemState: SystemState = {
|
const initialSystemState: SystemState = {
|
||||||
isConnected: false,
|
isConnected: false,
|
||||||
isProcessing: false,
|
isProcessing: false,
|
||||||
log: [],
|
|
||||||
shouldShowLogViewer: false,
|
shouldShowLogViewer: false,
|
||||||
shouldDisplayInProgressType: 'latents',
|
shouldDisplayInProgressType: 'latents',
|
||||||
shouldDisplayGuides: true,
|
shouldDisplayGuides: true,
|
||||||
@ -150,9 +147,6 @@ const initialSystemState: SystemState = {
|
|||||||
cancelType: 'immediate',
|
cancelType: 'immediate',
|
||||||
isCancelScheduled: false,
|
isCancelScheduled: false,
|
||||||
subscribedNodeIds: [],
|
subscribedNodeIds: [],
|
||||||
// shouldTransformUrls: false,
|
|
||||||
// disabledTabs: [],
|
|
||||||
// disabledFeatures: [],
|
|
||||||
wereModelsReceived: false,
|
wereModelsReceived: false,
|
||||||
wasSchemaParsed: false,
|
wasSchemaParsed: false,
|
||||||
consoleLogLevel: 'info',
|
consoleLogLevel: 'info',
|
||||||
@ -196,25 +190,6 @@ export const systemSlice = createSlice({
|
|||||||
? i18n.t('common.statusConnected')
|
? i18n.t('common.statusConnected')
|
||||||
: i18n.t('common.statusDisconnected');
|
: i18n.t('common.statusDisconnected');
|
||||||
},
|
},
|
||||||
addLogEntry: (
|
|
||||||
state,
|
|
||||||
action: PayloadAction<{
|
|
||||||
timestamp: string;
|
|
||||||
message: string;
|
|
||||||
level?: LogLevel;
|
|
||||||
}>
|
|
||||||
) => {
|
|
||||||
const { timestamp, message, level } = action.payload;
|
|
||||||
const logLevel = level || 'info';
|
|
||||||
|
|
||||||
const entry: LogEntry = {
|
|
||||||
timestamp,
|
|
||||||
message,
|
|
||||||
level: logLevel,
|
|
||||||
};
|
|
||||||
|
|
||||||
state.log.push(entry);
|
|
||||||
},
|
|
||||||
setShouldShowLogViewer: (state, action: PayloadAction<boolean>) => {
|
setShouldShowLogViewer: (state, action: PayloadAction<boolean>) => {
|
||||||
state.shouldShowLogViewer = action.payload;
|
state.shouldShowLogViewer = action.payload;
|
||||||
},
|
},
|
||||||
@ -380,11 +355,6 @@ export const systemSlice = createSlice({
|
|||||||
|
|
||||||
state.isConnected = true;
|
state.isConnected = true;
|
||||||
state.currentStatus = i18n.t('common.statusConnected');
|
state.currentStatus = i18n.t('common.statusConnected');
|
||||||
state.log.push({
|
|
||||||
timestamp,
|
|
||||||
message: `Connected to server`,
|
|
||||||
level: 'error',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -395,11 +365,6 @@ export const systemSlice = createSlice({
|
|||||||
|
|
||||||
state.isConnected = false;
|
state.isConnected = false;
|
||||||
state.currentStatus = i18n.t('common.statusDisconnected');
|
state.currentStatus = i18n.t('common.statusDisconnected');
|
||||||
state.log.push({
|
|
||||||
timestamp,
|
|
||||||
message: `Disconnected from server`,
|
|
||||||
level: 'error',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -442,15 +407,6 @@ export const systemSlice = createSlice({
|
|||||||
state.totalSteps = 0;
|
state.totalSteps = 0;
|
||||||
state.progressImage = null;
|
state.progressImage = null;
|
||||||
state.currentStatus = i18n.t('common.statusProcessingComplete');
|
state.currentStatus = i18n.t('common.statusProcessingComplete');
|
||||||
|
|
||||||
// TODO: handle logging for other invocation types
|
|
||||||
if (isImageOutput(data.result)) {
|
|
||||||
state.log.push({
|
|
||||||
timestamp,
|
|
||||||
message: `Generated: ${data.result.image.image_name}`,
|
|
||||||
level: 'info',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -459,12 +415,6 @@ export const systemSlice = createSlice({
|
|||||||
builder.addCase(invocationError, (state, action) => {
|
builder.addCase(invocationError, (state, action) => {
|
||||||
const { data, timestamp } = action.payload;
|
const { data, timestamp } = action.payload;
|
||||||
|
|
||||||
state.log.push({
|
|
||||||
timestamp,
|
|
||||||
message: `Server error: ${data.error}`,
|
|
||||||
level: 'error',
|
|
||||||
});
|
|
||||||
|
|
||||||
state.wasErrorSeen = true;
|
state.wasErrorSeen = true;
|
||||||
state.progressImage = null;
|
state.progressImage = null;
|
||||||
state.isProcessing = false;
|
state.isProcessing = false;
|
||||||
@ -472,12 +422,6 @@ export const systemSlice = createSlice({
|
|||||||
state.toastQueue.push(
|
state.toastQueue.push(
|
||||||
makeToast({ title: i18n.t('toast.serverError'), status: 'error' })
|
makeToast({ title: i18n.t('toast.serverError'), status: 'error' })
|
||||||
);
|
);
|
||||||
|
|
||||||
state.log.push({
|
|
||||||
timestamp,
|
|
||||||
message: `Server error: ${data.error}`,
|
|
||||||
level: 'error',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -504,12 +448,6 @@ export const systemSlice = createSlice({
|
|||||||
state.toastQueue.push(
|
state.toastQueue.push(
|
||||||
makeToast({ title: i18n.t('toast.canceled'), status: 'warning' })
|
makeToast({ title: i18n.t('toast.canceled'), status: 'warning' })
|
||||||
);
|
);
|
||||||
|
|
||||||
state.log.push({
|
|
||||||
timestamp,
|
|
||||||
message: `Processing canceled`,
|
|
||||||
level: 'warning',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -538,7 +476,6 @@ export const systemSlice = createSlice({
|
|||||||
export const {
|
export const {
|
||||||
setShouldDisplayInProgressType,
|
setShouldDisplayInProgressType,
|
||||||
setIsProcessing,
|
setIsProcessing,
|
||||||
addLogEntry,
|
|
||||||
setShouldShowLogViewer,
|
setShouldShowLogViewer,
|
||||||
setIsConnected,
|
setIsConnected,
|
||||||
setSocketId,
|
setSocketId,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user