mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): rerender mitigation sweep
This commit is contained in:
parent
5d8728c7ef
commit
ca1cc0e2c2
@ -28,11 +28,13 @@ import { useGlobalHotkeys } from 'common/hooks/useGlobalHotkeys';
|
|||||||
import { configChanged } from 'features/system/store/configSlice';
|
import { configChanged } from 'features/system/store/configSlice';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
|
|
||||||
|
const DEFAULT_CONFIG = {};
|
||||||
|
|
||||||
interface Props extends PropsWithChildren {
|
interface Props extends PropsWithChildren {
|
||||||
config?: PartialAppConfig;
|
config?: PartialAppConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
const App = ({ config = {}, children }: Props) => {
|
const App = ({ config = DEFAULT_CONFIG, children }: Props) => {
|
||||||
useToastWatcher();
|
useToastWatcher();
|
||||||
useGlobalHotkeys();
|
useGlobalHotkeys();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Flex, Image, Spinner } from '@chakra-ui/react';
|
import { Flex, Image, Spinner } from '@chakra-ui/react';
|
||||||
import InvokeAILogoImage from 'assets/images/logo.png';
|
import InvokeAILogoImage from 'assets/images/logo.png';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
// This component loads before the theme so we cannot use theme tokens here
|
// This component loads before the theme so we cannot use theme tokens here
|
||||||
|
|
||||||
@ -29,4 +30,4 @@ const Loading = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Loading;
|
export default memo(Loading);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { RootState } from 'app/store/store';
|
import { RootState } from 'app/store/store';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { useCallback } from 'react';
|
||||||
import { OpenAPI } from 'services/api';
|
import { OpenAPI } from 'services/api';
|
||||||
|
|
||||||
export const getUrlAlt = (url: string, shouldTransformUrls: boolean) => {
|
export const getUrlAlt = (url: string, shouldTransformUrls: boolean) => {
|
||||||
@ -15,14 +16,19 @@ export const useGetUrl = () => {
|
|||||||
(state: RootState) => state.config.shouldTransformUrls
|
(state: RootState) => state.config.shouldTransformUrls
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
const getUrl = useCallback(
|
||||||
shouldTransformUrls,
|
(url?: string) => {
|
||||||
getUrl: (url?: string) => {
|
|
||||||
if (OpenAPI.BASE && shouldTransformUrls) {
|
if (OpenAPI.BASE && shouldTransformUrls) {
|
||||||
return [OpenAPI.BASE, url].join('/');
|
return [OpenAPI.BASE, url].join('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
},
|
},
|
||||||
|
[shouldTransformUrls]
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
shouldTransformUrls,
|
||||||
|
getUrl,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -163,16 +163,16 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const setBothPrompts = useSetBothPrompts();
|
const setBothPrompts = useSetBothPrompts();
|
||||||
|
|
||||||
const handleClickUseAsInitialImage = () => {
|
const handleClickUseAsInitialImage = useCallback(() => {
|
||||||
if (!image) return;
|
if (!image) return;
|
||||||
if (isLightboxOpen) dispatch(setIsLightboxOpen(false));
|
if (isLightboxOpen) dispatch(setIsLightboxOpen(false));
|
||||||
dispatch(initialImageSelected(image.name));
|
dispatch(initialImageSelected(image.name));
|
||||||
// dispatch(setInitialImage(currentImage));
|
// dispatch(setInitialImage(currentImage));
|
||||||
|
|
||||||
// dispatch(setActiveTab('img2img'));
|
// dispatch(setActiveTab('img2img'));
|
||||||
};
|
}, [dispatch, image, isLightboxOpen]);
|
||||||
|
|
||||||
const handleCopyImage = async () => {
|
const handleCopyImage = useCallback(async () => {
|
||||||
if (!image?.url) {
|
if (!image?.url) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -194,9 +194,9 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
duration: 2500,
|
duration: 2500,
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
};
|
}, [getUrl, t, image?.url, toast]);
|
||||||
|
|
||||||
const handleCopyImageLink = () => {
|
const handleCopyImageLink = useCallback(() => {
|
||||||
const url = image
|
const url = image
|
||||||
? shouldTransformUrls
|
? shouldTransformUrls
|
||||||
? getUrl(image.url)
|
? getUrl(image.url)
|
||||||
@ -215,7 +215,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
}, [toast, shouldTransformUrls, getUrl, t, image]);
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
'shift+i',
|
'shift+i',
|
||||||
@ -241,11 +241,11 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
[image]
|
[image]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handlePreviewVisibility = () => {
|
const handlePreviewVisibility = useCallback(() => {
|
||||||
dispatch(setShouldHidePreview(!shouldHidePreview));
|
dispatch(setShouldHidePreview(!shouldHidePreview));
|
||||||
};
|
}, [dispatch, shouldHidePreview]);
|
||||||
|
|
||||||
const handleClickUseAllParameters = () => {
|
const handleClickUseAllParameters = useCallback(() => {
|
||||||
if (!image) return;
|
if (!image) return;
|
||||||
// selectedImage.metadata &&
|
// selectedImage.metadata &&
|
||||||
// dispatch(setAllParameters(selectedImage.metadata));
|
// dispatch(setAllParameters(selectedImage.metadata));
|
||||||
@ -254,7 +254,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
// } else if (selectedImage.metadata?.image.type === 'txt2img') {
|
// } else if (selectedImage.metadata?.image.type === 'txt2img') {
|
||||||
// dispatch(setActiveTab('txt2img'));
|
// dispatch(setActiveTab('txt2img'));
|
||||||
// }
|
// }
|
||||||
};
|
}, [image]);
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
'a',
|
'a',
|
||||||
@ -338,9 +338,9 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
[image]
|
[image]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleClickUpscale = () => {
|
const handleClickUpscale = useCallback(() => {
|
||||||
// selectedImage && dispatch(runESRGAN(selectedImage));
|
// selectedImage && dispatch(runESRGAN(selectedImage));
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
'Shift+U',
|
'Shift+U',
|
||||||
@ -369,9 +369,9 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleClickFixFaces = () => {
|
const handleClickFixFaces = useCallback(() => {
|
||||||
// selectedImage && dispatch(runFacetool(selectedImage));
|
// selectedImage && dispatch(runFacetool(selectedImage));
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
'Shift+R',
|
'Shift+R',
|
||||||
@ -401,10 +401,12 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleClickShowImageDetails = () =>
|
const handleClickShowImageDetails = useCallback(
|
||||||
dispatch(setShouldShowImageDetails(!shouldShowImageDetails));
|
() => dispatch(setShouldShowImageDetails(!shouldShowImageDetails)),
|
||||||
|
[dispatch, shouldShowImageDetails]
|
||||||
|
);
|
||||||
|
|
||||||
const handleSendToCanvas = () => {
|
const handleSendToCanvas = useCallback(() => {
|
||||||
if (!image) return;
|
if (!image) return;
|
||||||
if (isLightboxOpen) dispatch(setIsLightboxOpen(false));
|
if (isLightboxOpen) dispatch(setIsLightboxOpen(false));
|
||||||
|
|
||||||
@ -421,7 +423,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
duration: 2500,
|
duration: 2500,
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
};
|
}, [image, isLightboxOpen, dispatch, activeTabName, toast, t]);
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
'i',
|
'i',
|
||||||
@ -440,19 +442,19 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
[image, shouldShowImageDetails]
|
[image, shouldShowImageDetails]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleInitiateDelete = () => {
|
const handleDelete = useCallback(() => {
|
||||||
|
if (canDeleteImage && image) {
|
||||||
|
dispatch(imageDeleted({ imageType: image.type, imageName: image.name }));
|
||||||
|
}
|
||||||
|
}, [image, canDeleteImage, dispatch]);
|
||||||
|
|
||||||
|
const handleInitiateDelete = useCallback(() => {
|
||||||
if (shouldConfirmOnDelete) {
|
if (shouldConfirmOnDelete) {
|
||||||
onDeleteDialogOpen();
|
onDeleteDialogOpen();
|
||||||
} else {
|
} else {
|
||||||
handleDelete();
|
handleDelete();
|
||||||
}
|
}
|
||||||
};
|
}, [shouldConfirmOnDelete, onDeleteDialogOpen, handleDelete]);
|
||||||
|
|
||||||
const handleDelete = () => {
|
|
||||||
if (canDeleteImage && image) {
|
|
||||||
dispatch(imageDeleted({ imageType: image.type, imageName: image.name }));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useHotkeys('delete', handleInitiateDelete, [
|
useHotkeys('delete', handleInitiateDelete, [
|
||||||
image,
|
image,
|
||||||
@ -461,9 +463,9 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
isProcessing,
|
isProcessing,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handleLightBox = () => {
|
const handleLightBox = useCallback(() => {
|
||||||
dispatch(setIsLightboxOpen(!isLightboxOpen));
|
dispatch(setIsLightboxOpen(!isLightboxOpen));
|
||||||
};
|
}, [dispatch, isLightboxOpen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -11,6 +11,7 @@ import CurrentImageFallback from './CurrentImageFallback';
|
|||||||
import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer';
|
import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer';
|
||||||
import NextPrevImageButtons from './NextPrevImageButtons';
|
import NextPrevImageButtons from './NextPrevImageButtons';
|
||||||
import CurrentImageHidden from './CurrentImageHidden';
|
import CurrentImageHidden from './CurrentImageHidden';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
export const imagesSelector = createSelector(
|
export const imagesSelector = createSelector(
|
||||||
[uiSelector, selectedImageSelector, systemSelector],
|
[uiSelector, selectedImageSelector, systemSelector],
|
||||||
@ -50,7 +51,7 @@ export const imagesSelector = createSelector(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export default function CurrentImagePreview() {
|
const CurrentImagePreview = () => {
|
||||||
const { shouldShowImageDetails, imageToDisplay, shouldHidePreview } =
|
const { shouldShowImageDetails, imageToDisplay, shouldHidePreview } =
|
||||||
useAppSelector(imagesSelector);
|
useAppSelector(imagesSelector);
|
||||||
const { getUrl } = useGetUrl();
|
const { getUrl } = useGetUrl();
|
||||||
@ -115,4 +116,6 @@ export default function CurrentImagePreview() {
|
|||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default memo(CurrentImagePreview);
|
||||||
|
@ -28,6 +28,7 @@ import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvas
|
|||||||
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
|
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
|
||||||
import useResolution from 'common/hooks/useResolution';
|
import useResolution from 'common/hooks/useResolution';
|
||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
const GALLERY_TAB_WIDTHS: Record<
|
const GALLERY_TAB_WIDTHS: Record<
|
||||||
InvokeTabName,
|
InvokeTabName,
|
||||||
@ -72,7 +73,7 @@ const galleryPanelSelector = createSelector(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export default function ImageGalleryPanel() {
|
export const ImageGalleryPanel = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const {
|
const {
|
||||||
shouldPinGallery,
|
shouldPinGallery,
|
||||||
@ -232,4 +233,6 @@ export default function ImageGalleryPanel() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return renderImageGallery();
|
return renderImageGallery();
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default memo(ImageGalleryPanel);
|
||||||
|
@ -6,14 +6,12 @@ import IAIIconButton, {
|
|||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
import {
|
import {
|
||||||
SystemState,
|
SystemState,
|
||||||
setCancelAfter,
|
|
||||||
setCancelType,
|
|
||||||
cancelScheduled,
|
cancelScheduled,
|
||||||
cancelTypeChanged,
|
cancelTypeChanged,
|
||||||
CancelType,
|
CancelType,
|
||||||
} from 'features/system/store/systemSlice';
|
} from 'features/system/store/systemSlice';
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
import { useEffect, useCallback, memo } from 'react';
|
import { useCallback, memo } from 'react';
|
||||||
import {
|
import {
|
||||||
ButtonSpinner,
|
ButtonSpinner,
|
||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
@ -27,16 +25,9 @@ import {
|
|||||||
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import { MdCancel, MdCancelScheduleSend } from 'react-icons/md';
|
||||||
MdArrowDropDown,
|
|
||||||
MdArrowDropUp,
|
|
||||||
MdCancel,
|
|
||||||
MdCancelScheduleSend,
|
|
||||||
} from 'react-icons/md';
|
|
||||||
|
|
||||||
import IAISimpleMenu from 'common/components/IAISimpleMenu';
|
|
||||||
import { sessionCanceled } from 'services/thunks/session';
|
import { sessionCanceled } from 'services/thunks/session';
|
||||||
import { FaChevronDown } from 'react-icons/fa';
|
|
||||||
import { BiChevronDown } from 'react-icons/bi';
|
import { BiChevronDown } from 'react-icons/bi';
|
||||||
|
|
||||||
const cancelButtonSelector = createSelector(
|
const cancelButtonSelector = createSelector(
|
||||||
@ -48,8 +39,6 @@ const cancelButtonSelector = createSelector(
|
|||||||
isCancelable: system.isCancelable,
|
isCancelable: system.isCancelable,
|
||||||
currentIteration: system.currentIteration,
|
currentIteration: system.currentIteration,
|
||||||
totalIterations: system.totalIterations,
|
totalIterations: system.totalIterations,
|
||||||
// cancelType: system.cancelOptions.cancelType,
|
|
||||||
// cancelAfter: system.cancelOptions.cancelAfter,
|
|
||||||
sessionId: system.sessionId,
|
sessionId: system.sessionId,
|
||||||
cancelType: system.cancelType,
|
cancelType: system.cancelType,
|
||||||
isCancelScheduled: system.isCancelScheduled,
|
isCancelScheduled: system.isCancelScheduled,
|
||||||
@ -75,11 +64,8 @@ const CancelButton = (
|
|||||||
isProcessing,
|
isProcessing,
|
||||||
isConnected,
|
isConnected,
|
||||||
isCancelable,
|
isCancelable,
|
||||||
currentIteration,
|
|
||||||
totalIterations,
|
|
||||||
cancelType,
|
cancelType,
|
||||||
isCancelScheduled,
|
isCancelScheduled,
|
||||||
// cancelAfter,
|
|
||||||
sessionId,
|
sessionId,
|
||||||
} = useAppSelector(cancelButtonSelector);
|
} = useAppSelector(cancelButtonSelector);
|
||||||
|
|
||||||
@ -105,7 +91,6 @@ const CancelButton = (
|
|||||||
},
|
},
|
||||||
[dispatch]
|
[dispatch]
|
||||||
);
|
);
|
||||||
// const isCancelScheduled = cancelAfter === null ? false : true;
|
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
'shift+x',
|
'shift+x',
|
||||||
@ -117,23 +102,6 @@ const CancelButton = (
|
|||||||
[isConnected, isProcessing, isCancelable]
|
[isConnected, isProcessing, isCancelable]
|
||||||
);
|
);
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// if (cancelAfter !== null && cancelAfter < currentIteration) {
|
|
||||||
// handleClickCancel();
|
|
||||||
// }
|
|
||||||
// }, [cancelAfter, currentIteration, handleClickCancel]);
|
|
||||||
|
|
||||||
// const cancelMenuItems = [
|
|
||||||
// {
|
|
||||||
// item: t('parameters.cancel.immediate'),
|
|
||||||
// onClick: () => dispatch(cancelTypeChanged('immediate')),
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// item: t('parameters.cancel.schedule'),
|
|
||||||
// onClick: () => dispatch(cancelTypeChanged('scheduled')),
|
|
||||||
// },
|
|
||||||
// ];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ButtonGroup isAttached width={btnGroupWidth}>
|
<ButtonGroup isAttached width={btnGroupWidth}>
|
||||||
{cancelType === 'immediate' ? (
|
{cancelType === 'immediate' ? (
|
||||||
|
@ -4,23 +4,27 @@ import * as InvokeAI from 'app/types/invokeai';
|
|||||||
import promptToString from 'common/util/promptToString';
|
import promptToString from 'common/util/promptToString';
|
||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
import { setNegativePrompt, setPrompt } from '../store/generationSlice';
|
import { setNegativePrompt, setPrompt } from '../store/generationSlice';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
// TECHDEBT: We have two metadata prompt formats and need to handle recalling either of them.
|
// TECHDEBT: We have two metadata prompt formats and need to handle recalling either of them.
|
||||||
// This hook provides a function to do that.
|
// This hook provides a function to do that.
|
||||||
const useSetBothPrompts = () => {
|
const useSetBothPrompts = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
return (inputPrompt: InvokeAI.Prompt) => {
|
return useCallback(
|
||||||
const promptString =
|
(inputPrompt: InvokeAI.Prompt) => {
|
||||||
typeof inputPrompt === 'string'
|
const promptString =
|
||||||
? inputPrompt
|
typeof inputPrompt === 'string'
|
||||||
: promptToString(inputPrompt);
|
? inputPrompt
|
||||||
|
: promptToString(inputPrompt);
|
||||||
|
|
||||||
const [prompt, negativePrompt] = getPromptAndNegative(promptString);
|
const [prompt, negativePrompt] = getPromptAndNegative(promptString);
|
||||||
|
|
||||||
dispatch(setPrompt(prompt));
|
dispatch(setPrompt(prompt));
|
||||||
dispatch(setNegativePrompt(negativePrompt));
|
dispatch(setNegativePrompt(negativePrompt));
|
||||||
};
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useSetBothPrompts;
|
export default useSetBothPrompts;
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from 'features/system/store/systemSlice';
|
} from 'features/system/store/systemSlice';
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
import { Resizable } from 're-resizable';
|
import { Resizable } from 're-resizable';
|
||||||
import { useLayoutEffect, useRef, useState } from 'react';
|
import { memo, useLayoutEffect, useRef, useState } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaAngleDoubleDown, FaCode, FaMinus } from 'react-icons/fa';
|
import { FaAngleDoubleDown, FaCode, FaMinus } from 'react-icons/fa';
|
||||||
@ -194,4 +194,4 @@ const Console = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Console;
|
export default memo(Console);
|
||||||
|
@ -3,6 +3,7 @@ import { createSelector } from '@reduxjs/toolkit';
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
import { SystemState } from 'features/system/store/systemSlice';
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PROGRESS_BAR_THICKNESS } from 'theme/util/constants';
|
import { PROGRESS_BAR_THICKNESS } from 'theme/util/constants';
|
||||||
import { systemSelector } from '../store/systemSelectors';
|
import { systemSelector } from '../store/systemSelectors';
|
||||||
@ -40,4 +41,4 @@ const ProgressBar = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProgressBar;
|
export default memo(ProgressBar);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Flex, Grid } from '@chakra-ui/react';
|
import { Flex, Grid } from '@chakra-ui/react';
|
||||||
import { useState } from 'react';
|
import { memo, useState } from 'react';
|
||||||
import ModelSelect from './ModelSelect';
|
import ModelSelect from './ModelSelect';
|
||||||
import StatusIndicator from './StatusIndicator';
|
import StatusIndicator from './StatusIndicator';
|
||||||
|
|
||||||
@ -65,5 +65,4 @@ const SiteHeader = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
SiteHeader.displayName = 'SiteHeader';
|
export default memo(SiteHeader);
|
||||||
export default SiteHeader;
|
|
||||||
|
@ -17,7 +17,7 @@ const itemsToDenylist: (keyof SystemState)[] = [
|
|||||||
'totalSteps',
|
'totalSteps',
|
||||||
'openModel',
|
'openModel',
|
||||||
'isCancelScheduled',
|
'isCancelScheduled',
|
||||||
'sessionId',
|
// 'sessionId',
|
||||||
'progressImage',
|
'progressImage',
|
||||||
'wereModelsReceived',
|
'wereModelsReceived',
|
||||||
'wasSchemaParsed',
|
'wasSchemaParsed',
|
||||||
|
@ -89,18 +89,6 @@ export interface SystemState
|
|||||||
* Array of node IDs that we want to handle when events received
|
* Array of node IDs that we want to handle when events received
|
||||||
*/
|
*/
|
||||||
subscribedNodeIds: string[];
|
subscribedNodeIds: string[];
|
||||||
// /**
|
|
||||||
// * Whether or not URLs should be transformed to use a different host
|
|
||||||
// */
|
|
||||||
// shouldTransformUrls: boolean;
|
|
||||||
// /**
|
|
||||||
// * Array of disabled tabs
|
|
||||||
// */
|
|
||||||
// disabledTabs: InvokeTabName[];
|
|
||||||
// /**
|
|
||||||
// * Array of disabled features
|
|
||||||
// */
|
|
||||||
// disabledFeatures: InvokeAI.AppFeature[];
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the available models were received
|
* Whether or not the available models were received
|
||||||
*/
|
*/
|
||||||
@ -358,27 +346,6 @@ export const systemSlice = createSlice({
|
|||||||
subscribedNodeIdsSet: (state, action: PayloadAction<string[]>) => {
|
subscribedNodeIdsSet: (state, action: PayloadAction<string[]>) => {
|
||||||
state.subscribedNodeIds = action.payload;
|
state.subscribedNodeIds = action.payload;
|
||||||
},
|
},
|
||||||
// /**
|
|
||||||
// * `shouldTransformUrls` was changed
|
|
||||||
// */
|
|
||||||
// shouldTransformUrlsChanged: (state, action: PayloadAction<boolean>) => {
|
|
||||||
// state.shouldTransformUrls = action.payload;
|
|
||||||
// },
|
|
||||||
// /**
|
|
||||||
// * `disabledTabs` was changed
|
|
||||||
// */
|
|
||||||
// disabledTabsChanged: (state, action: PayloadAction<InvokeTabName[]>) => {
|
|
||||||
// state.disabledTabs = action.payload;
|
|
||||||
// },
|
|
||||||
// /**
|
|
||||||
// * `disabledFeatures` was changed
|
|
||||||
// */
|
|
||||||
// disabledFeaturesChanged: (
|
|
||||||
// state,
|
|
||||||
// action: PayloadAction<InvokeAI.AppFeature[]>
|
|
||||||
// ) => {
|
|
||||||
// state.disabledFeatures = action.payload;
|
|
||||||
// },
|
|
||||||
},
|
},
|
||||||
extraReducers(builder) {
|
extraReducers(builder) {
|
||||||
/**
|
/**
|
||||||
@ -386,6 +353,7 @@ export const systemSlice = createSlice({
|
|||||||
*/
|
*/
|
||||||
builder.addCase(socketSubscribed, (state, action) => {
|
builder.addCase(socketSubscribed, (state, action) => {
|
||||||
state.sessionId = action.payload.sessionId;
|
state.sessionId = action.payload.sessionId;
|
||||||
|
console.log(`Subscribed to session ${action.payload.sessionId}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -594,9 +562,6 @@ export const {
|
|||||||
scheduledCancelAborted,
|
scheduledCancelAborted,
|
||||||
cancelTypeChanged,
|
cancelTypeChanged,
|
||||||
subscribedNodeIdsSet,
|
subscribedNodeIdsSet,
|
||||||
// shouldTransformUrlsChanged,
|
|
||||||
// disabledTabsChanged,
|
|
||||||
// disabledFeaturesChanged,
|
|
||||||
} = systemSlice.actions;
|
} = systemSlice.actions;
|
||||||
|
|
||||||
export default systemSlice.reducer;
|
export default systemSlice.reducer;
|
||||||
|
@ -7,6 +7,7 @@ import { setShouldShowGallery } from 'features/ui/store/uiSlice';
|
|||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
import { MdPhotoLibrary } from 'react-icons/md';
|
import { MdPhotoLibrary } from 'react-icons/md';
|
||||||
import { activeTabNameSelector, uiSelector } from '../store/uiSelectors';
|
import { activeTabNameSelector, uiSelector } from '../store/uiSelectors';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
const floatingGalleryButtonSelector = createSelector(
|
const floatingGalleryButtonSelector = createSelector(
|
||||||
[activeTabNameSelector, uiSelector],
|
[activeTabNameSelector, uiSelector],
|
||||||
@ -58,4 +59,4 @@ const FloatingGalleryButton = () => {
|
|||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FloatingGalleryButton;
|
export default memo(FloatingGalleryButton);
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
} from 'features/ui/store/uiSelectors';
|
} from 'features/ui/store/uiSelectors';
|
||||||
import { setShouldShowParametersPanel } from 'features/ui/store/uiSlice';
|
import { setShouldShowParametersPanel } from 'features/ui/store/uiSlice';
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { FaSlidersH } from 'react-icons/fa';
|
import { FaSlidersH } from 'react-icons/fa';
|
||||||
@ -94,4 +95,4 @@ const FloatingParametersPanelButtons = () => {
|
|||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FloatingParametersPanelButtons;
|
export default memo(FloatingParametersPanelButtons);
|
||||||
|
@ -14,7 +14,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|||||||
import { setIsLightboxOpen } from 'features/lightbox/store/lightboxSlice';
|
import { setIsLightboxOpen } from 'features/lightbox/store/lightboxSlice';
|
||||||
import { InvokeTabName } from 'features/ui/store/tabMap';
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import { setActiveTab, togglePanels } from 'features/ui/store/uiSlice';
|
import { setActiveTab, togglePanels } from 'features/ui/store/uiSlice';
|
||||||
import { ReactNode, useMemo } from 'react';
|
import { memo, ReactNode, useMemo } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { MdDeviceHub, MdGridOn } from 'react-icons/md';
|
import { MdDeviceHub, MdGridOn } from 'react-icons/md';
|
||||||
import { activeTabIndexSelector } from '../store/uiSelectors';
|
import { activeTabIndexSelector } from '../store/uiSelectors';
|
||||||
@ -24,10 +24,10 @@ import { ResourceKey } from 'i18next';
|
|||||||
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
||||||
import NodeEditor from 'features/nodes/components/NodeEditor';
|
import NodeEditor from 'features/nodes/components/NodeEditor';
|
||||||
import GenerateWorkspace from './tabs/Generate/GenerateWorkspace';
|
import GenerateWorkspace from './tabs/Generate/GenerateWorkspace';
|
||||||
import { FaImage } from 'react-icons/fa';
|
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { BsLightningChargeFill, BsLightningFill } from 'react-icons/bs';
|
import { BsLightningChargeFill } from 'react-icons/bs';
|
||||||
import { configSelector } from 'features/system/store/configSelectors';
|
import { configSelector } from 'features/system/store/configSelectors';
|
||||||
|
import { isEqual } from 'lodash';
|
||||||
|
|
||||||
export interface InvokeTabInfo {
|
export interface InvokeTabInfo {
|
||||||
id: InvokeTabName;
|
id: InvokeTabName;
|
||||||
@ -35,10 +35,6 @@ export interface InvokeTabInfo {
|
|||||||
workarea: ReactNode;
|
workarea: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabIconStyles: ChakraProps['sx'] = {
|
|
||||||
boxSize: 6,
|
|
||||||
};
|
|
||||||
|
|
||||||
const tabs: InvokeTabInfo[] = [
|
const tabs: InvokeTabInfo[] = [
|
||||||
{
|
{
|
||||||
id: 'generate',
|
id: 'generate',
|
||||||
@ -57,13 +53,19 @@ const tabs: InvokeTabInfo[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const enabledTabsSelector = createSelector(configSelector, (config) => {
|
const enabledTabsSelector = createSelector(
|
||||||
const { disabledTabs } = config;
|
configSelector,
|
||||||
|
(config) => {
|
||||||
|
const { disabledTabs } = config;
|
||||||
|
|
||||||
return tabs.filter((tab) => !disabledTabs.includes(tab.id));
|
return tabs.filter((tab) => !disabledTabs.includes(tab.id));
|
||||||
});
|
},
|
||||||
|
{
|
||||||
|
memoizeOptions: { resultEqualityCheck: isEqual },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default function InvokeTabs() {
|
const InvokeTabs = () => {
|
||||||
const activeTab = useAppSelector(activeTabIndexSelector);
|
const activeTab = useAppSelector(activeTabIndexSelector);
|
||||||
const enabledTabs = useAppSelector(enabledTabsSelector);
|
const enabledTabs = useAppSelector(enabledTabsSelector);
|
||||||
const isLightBoxOpen = useAppSelector(
|
const isLightBoxOpen = useAppSelector(
|
||||||
@ -160,4 +162,6 @@ export default function InvokeTabs() {
|
|||||||
<TabPanels>{tabPanels}</TabPanels>
|
<TabPanels>{tabPanels}</TabPanels>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default memo(InvokeTabs);
|
||||||
|
Loading…
Reference in New Issue
Block a user