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 Console from 'features/system/components/Console';
|
||||
import ProgressBar from 'features/system/components/ProgressBar';
|
||||
import SiteHeader from 'features/system/components/SiteHeader';
|
||||
import InvokeTabs from 'features/ui/components/InvokeTabs';
|
||||
@ -121,9 +120,6 @@ const App = ({ config = DEFAULT_CONFIG, children }: Props) => {
|
||||
<Portal>
|
||||
<FloatingGalleryButton />
|
||||
</Portal>
|
||||
<Portal>
|
||||
<Console />
|
||||
</Portal>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
@ -12,7 +12,6 @@ import {
|
||||
removeImage,
|
||||
} from 'features/gallery/store/gallerySlice';
|
||||
import {
|
||||
addLogEntry,
|
||||
generationRequested,
|
||||
modelChangeRequested,
|
||||
modelConvertRequested,
|
||||
|
@ -6,7 +6,6 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
import * as InvokeAI from 'app/types/invokeai';
|
||||
|
||||
import {
|
||||
addLogEntry,
|
||||
addToast,
|
||||
errorOccurred,
|
||||
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';
|
||||
|
||||
import i18n from 'i18n';
|
||||
import { isImageOutput } from 'services/types/guards';
|
||||
import { ProgressImage } from 'services/events/types';
|
||||
import { initialImageSelected } from 'features/parameters/store/generationSlice';
|
||||
import { makeToast } from '../hooks/useToastWatcher';
|
||||
@ -22,7 +21,7 @@ import { sessionCanceled, sessionInvoked } from 'services/thunks/session';
|
||||
import { receivedModels } from 'services/thunks/model';
|
||||
import { parsedOpenAPISchema } from 'features/nodes/store/nodesSlice';
|
||||
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';
|
||||
|
||||
@ -44,7 +43,6 @@ export interface SystemState
|
||||
extends InvokeAI.SystemStatus,
|
||||
InvokeAI.SystemConfig {
|
||||
shouldDisplayInProgressType: InProgressImageType;
|
||||
log: Array<LogEntry>;
|
||||
shouldShowLogViewer: boolean;
|
||||
isGFPGANAvailable: boolean;
|
||||
isESRGANAvailable: boolean;
|
||||
@ -108,7 +106,6 @@ export interface SystemState
|
||||
const initialSystemState: SystemState = {
|
||||
isConnected: false,
|
||||
isProcessing: false,
|
||||
log: [],
|
||||
shouldShowLogViewer: false,
|
||||
shouldDisplayInProgressType: 'latents',
|
||||
shouldDisplayGuides: true,
|
||||
@ -150,9 +147,6 @@ const initialSystemState: SystemState = {
|
||||
cancelType: 'immediate',
|
||||
isCancelScheduled: false,
|
||||
subscribedNodeIds: [],
|
||||
// shouldTransformUrls: false,
|
||||
// disabledTabs: [],
|
||||
// disabledFeatures: [],
|
||||
wereModelsReceived: false,
|
||||
wasSchemaParsed: false,
|
||||
consoleLogLevel: 'info',
|
||||
@ -196,25 +190,6 @@ export const systemSlice = createSlice({
|
||||
? i18n.t('common.statusConnected')
|
||||
: 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>) => {
|
||||
state.shouldShowLogViewer = action.payload;
|
||||
},
|
||||
@ -380,11 +355,6 @@ export const systemSlice = createSlice({
|
||||
|
||||
state.isConnected = true;
|
||||
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.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.progressImage = null;
|
||||
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) => {
|
||||
const { data, timestamp } = action.payload;
|
||||
|
||||
state.log.push({
|
||||
timestamp,
|
||||
message: `Server error: ${data.error}`,
|
||||
level: 'error',
|
||||
});
|
||||
|
||||
state.wasErrorSeen = true;
|
||||
state.progressImage = null;
|
||||
state.isProcessing = false;
|
||||
@ -472,12 +422,6 @@ export const systemSlice = createSlice({
|
||||
state.toastQueue.push(
|
||||
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(
|
||||
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 {
|
||||
setShouldDisplayInProgressType,
|
||||
setIsProcessing,
|
||||
addLogEntry,
|
||||
setShouldShowLogViewer,
|
||||
setIsConnected,
|
||||
setSocketId,
|
||||
|
Loading…
Reference in New Issue
Block a user