mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): memoize all components
This commit is contained in:
parent
5c305b1eeb
commit
fbff22c94b
@ -1,7 +1,7 @@
|
||||
import { Flex, Heading, Link, Text, useToast } from '@chakra-ui/react';
|
||||
import IAIButton from 'common/components/IAIButton';
|
||||
import newGithubIssueUrl from 'new-github-issue-url';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { FaCopy, FaExternalLinkAlt } from 'react-icons/fa';
|
||||
import { FaArrowRotateLeft } from 'react-icons/fa6';
|
||||
import { serializeError } from 'serialize-error';
|
||||
@ -94,4 +94,4 @@ const AppErrorBoundaryFallback = ({ error, resetErrorBoundary }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default AppErrorBoundaryFallback;
|
||||
export default memo(AppErrorBoundaryFallback);
|
||||
|
@ -3,7 +3,7 @@ import {
|
||||
createLocalStorageManager,
|
||||
extendTheme,
|
||||
} from '@chakra-ui/react';
|
||||
import { ReactNode, useEffect, useMemo } from 'react';
|
||||
import { ReactNode, memo, useEffect, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { theme as invokeAITheme } from 'theme/theme';
|
||||
|
||||
@ -46,4 +46,4 @@ function ThemeLocaleProvider({ children }: ThemeLocaleProviderProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export default ThemeLocaleProvider;
|
||||
export default memo(ThemeLocaleProvider);
|
||||
|
@ -3,7 +3,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { toastQueueSelector } from 'features/system/store/systemSelectors';
|
||||
import { addToast, clearToastQueue } from 'features/system/store/systemSlice';
|
||||
import { MakeToastArg, makeToast } from 'features/system/util/makeToast';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { memo, useCallback, useEffect } from 'react';
|
||||
|
||||
/**
|
||||
* Logical component. Watches the toast queue and makes toasts when the queue is not empty.
|
||||
@ -44,4 +44,4 @@ export const useAppToaster = () => {
|
||||
return toaster;
|
||||
};
|
||||
|
||||
export default Toaster;
|
||||
export default memo(Toaster);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Box, Flex, Icon } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
import { FaExclamation } from 'react-icons/fa';
|
||||
|
||||
const IAIErrorLoadingImageFallback = () => {
|
||||
@ -39,4 +40,4 @@ const IAIErrorLoadingImageFallback = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAIErrorLoadingImageFallback;
|
||||
export default memo(IAIErrorLoadingImageFallback);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Box, Skeleton } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
|
||||
const IAIFillSkeleton = () => {
|
||||
return (
|
||||
@ -27,4 +28,4 @@ const IAIFillSkeleton = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAIFillSkeleton;
|
||||
export default memo(IAIFillSkeleton);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Badge, Flex } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
import { ImageDTO } from 'services/api/types';
|
||||
|
||||
type ImageMetadataOverlayProps = {
|
||||
@ -26,4 +27,4 @@ const ImageMetadataOverlay = ({ imageDTO }: ImageMetadataOverlayProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageMetadataOverlay;
|
||||
export default memo(ImageMetadataOverlay);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Box, Flex, Heading } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
|
||||
type ImageUploadOverlayProps = {
|
||||
@ -87,4 +88,4 @@ const ImageUploadOverlay = (props: ImageUploadOverlayProps) => {
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
export default ImageUploadOverlay;
|
||||
export default memo(ImageUploadOverlay);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Flex, Icon } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
import { FaImage } from 'react-icons/fa';
|
||||
|
||||
const SelectImagePlaceholder = () => {
|
||||
@ -19,4 +20,4 @@ const SelectImagePlaceholder = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectImagePlaceholder;
|
||||
export default memo(SelectImagePlaceholder);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
|
||||
type Props = {
|
||||
isSelected: boolean;
|
||||
@ -40,4 +41,4 @@ const SelectionOverlay = ({ isSelected, isHovered }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectionOverlay;
|
||||
export default memo(SelectionOverlay);
|
||||
|
@ -5,6 +5,7 @@ import { clearCanvasHistory } from 'features/canvas/store/canvasSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaTrash } from 'react-icons/fa';
|
||||
import { isStagingSelector } from '../store/canvasSelectors';
|
||||
import { memo } from 'react';
|
||||
|
||||
const ClearCanvasHistoryButtonModal = () => {
|
||||
const isStaging = useAppSelector(isStagingSelector);
|
||||
@ -28,4 +29,4 @@ const ClearCanvasHistoryButtonModal = () => {
|
||||
</IAIAlertDialog>
|
||||
);
|
||||
};
|
||||
export default ClearCanvasHistoryButtonModal;
|
||||
export default memo(ClearCanvasHistoryButtonModal);
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
import Konva from 'konva';
|
||||
import { KonvaEventObject } from 'konva/lib/Node';
|
||||
import { Vector2d } from 'konva/lib/types';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { memo, useCallback, useRef } from 'react';
|
||||
import { Layer, Stage } from 'react-konva';
|
||||
import useCanvasDragMove from '../hooks/useCanvasDragMove';
|
||||
import useCanvasHotkeys from '../hooks/useCanvasHotkeys';
|
||||
@ -220,4 +220,4 @@ const IAICanvas = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvas;
|
||||
export default memo(IAICanvas);
|
||||
|
@ -4,6 +4,7 @@ import { isEqual } from 'lodash-es';
|
||||
|
||||
import { Group, Rect } from 'react-konva';
|
||||
import { canvasSelector } from '../store/canvasSelectors';
|
||||
import { memo } from 'react';
|
||||
|
||||
const selector = createSelector(
|
||||
canvasSelector,
|
||||
@ -67,4 +68,4 @@ const IAICanvasBoundingBoxOverlay = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasBoundingBoxOverlay;
|
||||
export default memo(IAICanvasBoundingBoxOverlay);
|
||||
|
@ -6,7 +6,7 @@ import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||
import { isEqual, range } from 'lodash-es';
|
||||
|
||||
import { ReactNode, useCallback, useLayoutEffect, useState } from 'react';
|
||||
import { ReactNode, memo, useCallback, useLayoutEffect, useState } from 'react';
|
||||
import { Group, Line as KonvaLine } from 'react-konva';
|
||||
|
||||
const selector = createSelector(
|
||||
@ -117,4 +117,4 @@ const IAICanvasGrid = () => {
|
||||
return <Group>{gridLines}</Group>;
|
||||
};
|
||||
|
||||
export default IAICanvasGrid;
|
||||
export default memo(IAICanvasGrid);
|
||||
|
@ -4,6 +4,7 @@ import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||
import useImage from 'use-image';
|
||||
import { CanvasImage } from '../store/canvasTypes';
|
||||
import { $authToken } from 'services/api/client';
|
||||
import { memo } from 'react';
|
||||
|
||||
type IAICanvasImageProps = {
|
||||
canvasImage: CanvasImage;
|
||||
@ -25,4 +26,4 @@ const IAICanvasImage = (props: IAICanvasImageProps) => {
|
||||
return <Image x={x} y={y} image={image} listening={false} />;
|
||||
};
|
||||
|
||||
export default IAICanvasImage;
|
||||
export default memo(IAICanvasImage);
|
||||
|
@ -4,7 +4,7 @@ import { systemSelector } from 'features/system/store/systemSelectors';
|
||||
import { ImageConfig } from 'konva/lib/shapes/Image';
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
import { Image as KonvaImage } from 'react-konva';
|
||||
import { canvasSelector } from '../store/canvasSelectors';
|
||||
|
||||
@ -66,4 +66,4 @@ const IAICanvasIntermediateImage = (props: Props) => {
|
||||
) : null;
|
||||
};
|
||||
|
||||
export default IAICanvasIntermediateImage;
|
||||
export default memo(IAICanvasIntermediateImage);
|
||||
|
@ -7,7 +7,7 @@ import { Rect } from 'react-konva';
|
||||
import { rgbaColorToString } from 'features/canvas/util/colorToString';
|
||||
import Konva from 'konva';
|
||||
import { isNumber } from 'lodash-es';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
export const canvasMaskCompositerSelector = createSelector(
|
||||
canvasSelector,
|
||||
@ -172,4 +172,4 @@ const IAICanvasMaskCompositer = (props: IAICanvasMaskCompositerProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasMaskCompositer;
|
||||
export default memo(IAICanvasMaskCompositer);
|
||||
|
@ -6,6 +6,7 @@ import { isEqual } from 'lodash-es';
|
||||
|
||||
import { Group, Line } from 'react-konva';
|
||||
import { isCanvasMaskLine } from '../store/canvasTypes';
|
||||
import { memo } from 'react';
|
||||
|
||||
export const canvasLinesSelector = createSelector(
|
||||
[canvasSelector],
|
||||
@ -52,4 +53,4 @@ const IAICanvasLines = (props: InpaintingCanvasLinesProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasLines;
|
||||
export default memo(IAICanvasLines);
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
isCanvasFillRect,
|
||||
} from '../store/canvasTypes';
|
||||
import IAICanvasImage from './IAICanvasImage';
|
||||
import { memo } from 'react';
|
||||
|
||||
const selector = createSelector(
|
||||
[canvasSelector],
|
||||
@ -101,4 +102,4 @@ const IAICanvasObjectRenderer = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasObjectRenderer;
|
||||
export default memo(IAICanvasObjectRenderer);
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
setDoesCanvasNeedScaling,
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import { useLayoutEffect, useRef } from 'react';
|
||||
import { memo, useLayoutEffect, useRef } from 'react';
|
||||
|
||||
const canvasResizerSelector = createSelector(
|
||||
canvasSelector,
|
||||
@ -86,4 +86,4 @@ const IAICanvasResizer = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasResizer;
|
||||
export default memo(IAICanvasResizer);
|
||||
|
@ -6,6 +6,7 @@ import { isEqual } from 'lodash-es';
|
||||
|
||||
import { Group, Rect } from 'react-konva';
|
||||
import IAICanvasImage from './IAICanvasImage';
|
||||
import { memo } from 'react';
|
||||
|
||||
const selector = createSelector(
|
||||
[canvasSelector],
|
||||
@ -88,4 +89,4 @@ const IAICanvasStagingArea = (props: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasStagingArea;
|
||||
export default memo(IAICanvasStagingArea);
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@ -207,4 +207,4 @@ const IAICanvasStagingAreaToolbar = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasStagingAreaToolbar;
|
||||
export default memo(IAICanvasStagingAreaToolbar);
|
||||
|
@ -7,6 +7,7 @@ import { isEqual } from 'lodash-es';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import roundToHundreth from '../util/roundToHundreth';
|
||||
import IAICanvasStatusTextCursorPos from './IAICanvasStatusText/IAICanvasStatusTextCursorPos';
|
||||
import { memo } from 'react';
|
||||
|
||||
const warningColor = 'var(--invokeai-colors-warning-500)';
|
||||
|
||||
@ -162,4 +163,4 @@ const IAICanvasStatusText = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasStatusText;
|
||||
export default memo(IAICanvasStatusText);
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
COLOR_PICKER_SIZE,
|
||||
COLOR_PICKER_STROKE_RADIUS,
|
||||
} from '../util/constants';
|
||||
import { memo } from 'react';
|
||||
|
||||
const canvasBrushPreviewSelector = createSelector(
|
||||
canvasSelector,
|
||||
@ -206,4 +207,4 @@ const IAICanvasToolPreview = (props: GroupConfig) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasToolPreview;
|
||||
export default memo(IAICanvasToolPreview);
|
||||
|
@ -19,7 +19,7 @@ import { KonvaEventObject } from 'konva/lib/Node';
|
||||
import { Vector2d } from 'konva/lib/types';
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { Group, Rect, Transformer } from 'react-konva';
|
||||
|
||||
@ -313,4 +313,4 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasBoundingBox;
|
||||
export default memo(IAICanvasBoundingBox);
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { rgbaColorToString } from 'features/canvas/util/colorToString';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { memo } from 'react';
|
||||
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -150,4 +151,4 @@ const IAICanvasMaskOptions = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasMaskOptions;
|
||||
export default memo(IAICanvasMaskOptions);
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
||||
import { ChangeEvent } from 'react';
|
||||
import { ChangeEvent, memo } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaWrench } from 'react-icons/fa';
|
||||
@ -163,4 +163,4 @@ const IAICanvasSettingsButtonPopover = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasSettingsButtonPopover;
|
||||
export default memo(IAICanvasSettingsButtonPopover);
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||
import { clamp, isEqual } from 'lodash-es';
|
||||
import { memo } from 'react';
|
||||
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -252,4 +253,4 @@ const IAICanvasToolChooserOptions = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasToolChooserOptions;
|
||||
export default memo(IAICanvasToolChooserOptions);
|
||||
|
@ -48,6 +48,7 @@ import IAICanvasRedoButton from './IAICanvasRedoButton';
|
||||
import IAICanvasSettingsButtonPopover from './IAICanvasSettingsButtonPopover';
|
||||
import IAICanvasToolChooserOptions from './IAICanvasToolChooserOptions';
|
||||
import IAICanvasUndoButton from './IAICanvasUndoButton';
|
||||
import { memo } from 'react';
|
||||
|
||||
export const selector = createSelector(
|
||||
[systemSelector, canvasSelector, isStagingSelector],
|
||||
@ -309,4 +310,4 @@ const IAICanvasToolbar = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default IAICanvasToolbar;
|
||||
export default memo(IAICanvasToolbar);
|
||||
|
@ -4,7 +4,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAISwitch from 'common/components/IAISwitch';
|
||||
import { isControlNetEnabledToggled } from 'features/controlNet/store/controlNetSlice';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
|
||||
const selector = createSelector(
|
||||
stateSelector,
|
||||
@ -36,4 +36,4 @@ const ParamControlNetFeatureToggle = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamControlNetFeatureToggle;
|
||||
export default memo(ParamControlNetFeatureToggle);
|
||||
|
@ -8,6 +8,7 @@ import ParamDynamicPromptsCombinatorial from './ParamDynamicPromptsCombinatorial
|
||||
import ParamDynamicPromptsToggle from './ParamDynamicPromptsEnabled';
|
||||
import ParamDynamicPromptsMaxPrompts from './ParamDynamicPromptsMaxPrompts';
|
||||
import { useFeatureStatus } from '../../system/hooks/useFeatureStatus';
|
||||
import { memo } from 'react';
|
||||
|
||||
const selector = createSelector(
|
||||
stateSelector,
|
||||
@ -40,4 +41,4 @@ const ParamDynamicPromptsCollapse = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamDynamicPromptsCollapse;
|
||||
export default memo(ParamDynamicPromptsCollapse);
|
||||
|
@ -3,7 +3,7 @@ import { stateSelector } from 'app/store/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAISwitch from 'common/components/IAISwitch';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { combinatorialToggled } from '../store/dynamicPromptsSlice';
|
||||
|
||||
const selector = createSelector(
|
||||
@ -34,4 +34,4 @@ const ParamDynamicPromptsCombinatorial = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamDynamicPromptsCombinatorial;
|
||||
export default memo(ParamDynamicPromptsCombinatorial);
|
||||
|
@ -3,7 +3,7 @@ import { stateSelector } from 'app/store/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAISwitch from 'common/components/IAISwitch';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { isEnabledToggled } from '../store/dynamicPromptsSlice';
|
||||
|
||||
const selector = createSelector(
|
||||
@ -33,4 +33,4 @@ const ParamDynamicPromptsToggle = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamDynamicPromptsToggle;
|
||||
export default memo(ParamDynamicPromptsToggle);
|
||||
|
@ -3,7 +3,7 @@ import { stateSelector } from 'app/store/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import {
|
||||
maxPromptsChanged,
|
||||
maxPromptsReset,
|
||||
@ -60,4 +60,4 @@ const ParamDynamicPromptsMaxPrompts = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamDynamicPromptsMaxPrompts;
|
||||
export default memo(ParamDynamicPromptsMaxPrompts);
|
||||
|
@ -13,7 +13,7 @@ import IAIMantineSearchableSelect from 'common/components/IAIMantineSearchableSe
|
||||
import IAIMantineSelectItemWithTooltip from 'common/components/IAIMantineSelectItemWithTooltip';
|
||||
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
|
||||
import { forEach } from 'lodash-es';
|
||||
import { PropsWithChildren, useCallback, useMemo, useRef } from 'react';
|
||||
import { PropsWithChildren, memo, useCallback, useMemo, useRef } from 'react';
|
||||
import { useGetTextualInversionModelsQuery } from 'services/api/endpoints/models';
|
||||
import { PARAMETERS_PANEL_WIDTH } from 'theme/util/constants';
|
||||
|
||||
@ -140,4 +140,4 @@ const ParamEmbeddingPopover = (props: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamEmbeddingPopover;
|
||||
export default memo(ParamEmbeddingPopover);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Badge, Flex } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
|
||||
const AutoAddIcon = () => {
|
||||
return (
|
||||
@ -20,4 +21,4 @@ const AutoAddIcon = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default AutoAddIcon;
|
||||
export default memo(AutoAddIcon);
|
||||
|
@ -6,7 +6,7 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAIMantineSearchableSelect from 'common/components/IAIMantineSearchableSelect';
|
||||
import IAIMantineSelectItemWithTooltip from 'common/components/IAIMantineSelectItemWithTooltip';
|
||||
import { autoAddBoardIdChanged } from 'features/gallery/store/gallerySlice';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { memo, useCallback, useRef } from 'react';
|
||||
import { useListAllBoardsQuery } from 'services/api/endpoints/boards';
|
||||
|
||||
const selector = createSelector(
|
||||
@ -81,4 +81,4 @@ const BoardAutoAddSelect = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default BoardAutoAddSelect;
|
||||
export default memo(BoardAutoAddSelect);
|
||||
|
@ -23,71 +23,72 @@ type Props = {
|
||||
setBoardToDelete?: (board?: BoardDTO) => void;
|
||||
};
|
||||
|
||||
const BoardContextMenu = memo(
|
||||
({ board, board_id, setBoardToDelete, children }: Props) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const BoardContextMenu = ({
|
||||
board,
|
||||
board_id,
|
||||
setBoardToDelete,
|
||||
children,
|
||||
}: Props) => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const selector = useMemo(
|
||||
() =>
|
||||
createSelector(stateSelector, ({ gallery, system }) => {
|
||||
const isAutoAdd = gallery.autoAddBoardId === board_id;
|
||||
const isProcessing = system.isProcessing;
|
||||
const autoAssignBoardOnClick = gallery.autoAssignBoardOnClick;
|
||||
return { isAutoAdd, isProcessing, autoAssignBoardOnClick };
|
||||
}),
|
||||
[board_id]
|
||||
);
|
||||
const selector = useMemo(
|
||||
() =>
|
||||
createSelector(stateSelector, ({ gallery, system }) => {
|
||||
const isAutoAdd = gallery.autoAddBoardId === board_id;
|
||||
const isProcessing = system.isProcessing;
|
||||
const autoAssignBoardOnClick = gallery.autoAssignBoardOnClick;
|
||||
return { isAutoAdd, isProcessing, autoAssignBoardOnClick };
|
||||
}),
|
||||
[board_id]
|
||||
);
|
||||
|
||||
const { isAutoAdd, isProcessing, autoAssignBoardOnClick } =
|
||||
useAppSelector(selector);
|
||||
const boardName = useBoardName(board_id);
|
||||
const { isAutoAdd, isProcessing, autoAssignBoardOnClick } =
|
||||
useAppSelector(selector);
|
||||
const boardName = useBoardName(board_id);
|
||||
|
||||
const handleSetAutoAdd = useCallback(() => {
|
||||
dispatch(autoAddBoardIdChanged(board_id));
|
||||
}, [board_id, dispatch]);
|
||||
const handleSetAutoAdd = useCallback(() => {
|
||||
dispatch(autoAddBoardIdChanged(board_id));
|
||||
}, [board_id, dispatch]);
|
||||
|
||||
const skipEvent = useCallback((e: MouseEvent<HTMLDivElement>) => {
|
||||
e.preventDefault();
|
||||
}, []);
|
||||
const skipEvent = useCallback((e: MouseEvent<HTMLDivElement>) => {
|
||||
e.preventDefault();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<IAIContextMenu<HTMLDivElement>
|
||||
menuProps={{ size: 'sm', isLazy: true }}
|
||||
menuButtonProps={{
|
||||
bg: 'transparent',
|
||||
_hover: { bg: 'transparent' },
|
||||
}}
|
||||
renderMenu={() => (
|
||||
<MenuList
|
||||
sx={{ visibility: 'visible !important' }}
|
||||
motionProps={menuListMotionProps}
|
||||
onContextMenu={skipEvent}
|
||||
>
|
||||
<MenuGroup title={boardName}>
|
||||
<MenuItem
|
||||
icon={<FaPlus />}
|
||||
isDisabled={isAutoAdd || isProcessing || autoAssignBoardOnClick}
|
||||
onClick={handleSetAutoAdd}
|
||||
>
|
||||
Auto-add to this Board
|
||||
</MenuItem>
|
||||
{!board && <NoBoardContextMenuItems />}
|
||||
{board && (
|
||||
<GalleryBoardContextMenuItems
|
||||
board={board}
|
||||
setBoardToDelete={setBoardToDelete}
|
||||
/>
|
||||
)}
|
||||
</MenuGroup>
|
||||
</MenuList>
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</IAIContextMenu>
|
||||
);
|
||||
}
|
||||
);
|
||||
return (
|
||||
<IAIContextMenu<HTMLDivElement>
|
||||
menuProps={{ size: 'sm', isLazy: true }}
|
||||
menuButtonProps={{
|
||||
bg: 'transparent',
|
||||
_hover: { bg: 'transparent' },
|
||||
}}
|
||||
renderMenu={() => (
|
||||
<MenuList
|
||||
sx={{ visibility: 'visible !important' }}
|
||||
motionProps={menuListMotionProps}
|
||||
onContextMenu={skipEvent}
|
||||
>
|
||||
<MenuGroup title={boardName}>
|
||||
<MenuItem
|
||||
icon={<FaPlus />}
|
||||
isDisabled={isAutoAdd || isProcessing || autoAssignBoardOnClick}
|
||||
onClick={handleSetAutoAdd}
|
||||
>
|
||||
Auto-add to this Board
|
||||
</MenuItem>
|
||||
{!board && <NoBoardContextMenuItems />}
|
||||
{board && (
|
||||
<GalleryBoardContextMenuItems
|
||||
board={board}
|
||||
setBoardToDelete={setBoardToDelete}
|
||||
/>
|
||||
)}
|
||||
</MenuGroup>
|
||||
</MenuList>
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</IAIContextMenu>
|
||||
);
|
||||
};
|
||||
|
||||
BoardContextMenu.displayName = 'HoverableBoard';
|
||||
|
||||
export default BoardContextMenu;
|
||||
export default memo(BoardContextMenu);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { FaPlus } from 'react-icons/fa';
|
||||
import { useCreateBoardMutation } from 'services/api/endpoints/boards';
|
||||
|
||||
@ -24,4 +24,4 @@ const AddBoardButton = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default AddBoardButton;
|
||||
export default memo(AddBoardButton);
|
||||
|
@ -39,187 +39,188 @@ interface GalleryBoardProps {
|
||||
setBoardToDelete: (board?: BoardDTO) => void;
|
||||
}
|
||||
|
||||
const GalleryBoard = memo(
|
||||
({ board, isSelected, setBoardToDelete }: GalleryBoardProps) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const selector = useMemo(
|
||||
() =>
|
||||
createSelector(
|
||||
stateSelector,
|
||||
({ gallery, system }) => {
|
||||
const isSelectedForAutoAdd =
|
||||
board.board_id === gallery.autoAddBoardId;
|
||||
const autoAssignBoardOnClick = gallery.autoAssignBoardOnClick;
|
||||
const isProcessing = system.isProcessing;
|
||||
const GalleryBoard = ({
|
||||
board,
|
||||
isSelected,
|
||||
setBoardToDelete,
|
||||
}: GalleryBoardProps) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const selector = useMemo(
|
||||
() =>
|
||||
createSelector(
|
||||
stateSelector,
|
||||
({ gallery, system }) => {
|
||||
const isSelectedForAutoAdd =
|
||||
board.board_id === gallery.autoAddBoardId;
|
||||
const autoAssignBoardOnClick = gallery.autoAssignBoardOnClick;
|
||||
const isProcessing = system.isProcessing;
|
||||
|
||||
return {
|
||||
isSelectedForAutoAdd,
|
||||
autoAssignBoardOnClick,
|
||||
isProcessing,
|
||||
};
|
||||
},
|
||||
defaultSelectorOptions
|
||||
),
|
||||
[board.board_id]
|
||||
);
|
||||
return {
|
||||
isSelectedForAutoAdd,
|
||||
autoAssignBoardOnClick,
|
||||
isProcessing,
|
||||
};
|
||||
},
|
||||
defaultSelectorOptions
|
||||
),
|
||||
[board.board_id]
|
||||
);
|
||||
|
||||
const { isSelectedForAutoAdd, autoAssignBoardOnClick, isProcessing } =
|
||||
useAppSelector(selector);
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const handleMouseOver = useCallback(() => {
|
||||
setIsHovered(true);
|
||||
}, []);
|
||||
const handleMouseOut = useCallback(() => {
|
||||
setIsHovered(false);
|
||||
}, []);
|
||||
const { isSelectedForAutoAdd, autoAssignBoardOnClick, isProcessing } =
|
||||
useAppSelector(selector);
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const handleMouseOver = useCallback(() => {
|
||||
setIsHovered(true);
|
||||
}, []);
|
||||
const handleMouseOut = useCallback(() => {
|
||||
setIsHovered(false);
|
||||
}, []);
|
||||
|
||||
const { data: imagesTotal } = useGetBoardImagesTotalQuery(board.board_id);
|
||||
const { data: assetsTotal } = useGetBoardAssetsTotalQuery(board.board_id);
|
||||
const tooltip = useMemo(() => {
|
||||
if (!imagesTotal || !assetsTotal) {
|
||||
return undefined;
|
||||
const { data: imagesTotal } = useGetBoardImagesTotalQuery(board.board_id);
|
||||
const { data: assetsTotal } = useGetBoardAssetsTotalQuery(board.board_id);
|
||||
const tooltip = useMemo(() => {
|
||||
if (!imagesTotal || !assetsTotal) {
|
||||
return undefined;
|
||||
}
|
||||
return `${imagesTotal} image${
|
||||
imagesTotal > 1 ? 's' : ''
|
||||
}, ${assetsTotal} asset${assetsTotal > 1 ? 's' : ''}`;
|
||||
}, [assetsTotal, imagesTotal]);
|
||||
|
||||
const { currentData: coverImage } = useGetImageDTOQuery(
|
||||
board.cover_image_name ?? skipToken
|
||||
);
|
||||
|
||||
const { board_name, board_id } = board;
|
||||
const [localBoardName, setLocalBoardName] = useState(board_name);
|
||||
|
||||
const handleSelectBoard = useCallback(() => {
|
||||
dispatch(boardIdSelected(board_id));
|
||||
if (autoAssignBoardOnClick && !isProcessing) {
|
||||
dispatch(autoAddBoardIdChanged(board_id));
|
||||
}
|
||||
}, [board_id, autoAssignBoardOnClick, isProcessing, dispatch]);
|
||||
|
||||
const [updateBoard, { isLoading: isUpdateBoardLoading }] =
|
||||
useUpdateBoardMutation();
|
||||
|
||||
const droppableData: AddToBoardDropData = useMemo(
|
||||
() => ({
|
||||
id: board_id,
|
||||
actionType: 'ADD_TO_BOARD',
|
||||
context: { boardId: board_id },
|
||||
}),
|
||||
[board_id]
|
||||
);
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
async (newBoardName: string) => {
|
||||
// empty strings are not allowed
|
||||
if (!newBoardName.trim()) {
|
||||
setLocalBoardName(board_name);
|
||||
return;
|
||||
}
|
||||
return `${imagesTotal} image${
|
||||
imagesTotal > 1 ? 's' : ''
|
||||
}, ${assetsTotal} asset${assetsTotal > 1 ? 's' : ''}`;
|
||||
}, [assetsTotal, imagesTotal]);
|
||||
|
||||
const { currentData: coverImage } = useGetImageDTOQuery(
|
||||
board.cover_image_name ?? skipToken
|
||||
);
|
||||
|
||||
const { board_name, board_id } = board;
|
||||
const [localBoardName, setLocalBoardName] = useState(board_name);
|
||||
|
||||
const handleSelectBoard = useCallback(() => {
|
||||
dispatch(boardIdSelected(board_id));
|
||||
if (autoAssignBoardOnClick && !isProcessing) {
|
||||
dispatch(autoAddBoardIdChanged(board_id));
|
||||
// don't updated the board name if it hasn't changed
|
||||
if (newBoardName === board_name) {
|
||||
return;
|
||||
}
|
||||
}, [board_id, autoAssignBoardOnClick, isProcessing, dispatch]);
|
||||
|
||||
const [updateBoard, { isLoading: isUpdateBoardLoading }] =
|
||||
useUpdateBoardMutation();
|
||||
try {
|
||||
const { board_name } = await updateBoard({
|
||||
board_id,
|
||||
changes: { board_name: newBoardName },
|
||||
}).unwrap();
|
||||
|
||||
const droppableData: AddToBoardDropData = useMemo(
|
||||
() => ({
|
||||
id: board_id,
|
||||
actionType: 'ADD_TO_BOARD',
|
||||
context: { boardId: board_id },
|
||||
}),
|
||||
[board_id]
|
||||
);
|
||||
// update local state
|
||||
setLocalBoardName(board_name);
|
||||
} catch {
|
||||
// revert on error
|
||||
setLocalBoardName(board_name);
|
||||
}
|
||||
},
|
||||
[board_id, board_name, updateBoard]
|
||||
);
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
async (newBoardName: string) => {
|
||||
// empty strings are not allowed
|
||||
if (!newBoardName.trim()) {
|
||||
setLocalBoardName(board_name);
|
||||
return;
|
||||
}
|
||||
const handleChange = useCallback((newBoardName: string) => {
|
||||
setLocalBoardName(newBoardName);
|
||||
}, []);
|
||||
|
||||
// don't updated the board name if it hasn't changed
|
||||
if (newBoardName === board_name) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { board_name } = await updateBoard({
|
||||
board_id,
|
||||
changes: { board_name: newBoardName },
|
||||
}).unwrap();
|
||||
|
||||
// update local state
|
||||
setLocalBoardName(board_name);
|
||||
} catch {
|
||||
// revert on error
|
||||
setLocalBoardName(board_name);
|
||||
}
|
||||
},
|
||||
[board_id, board_name, updateBoard]
|
||||
);
|
||||
|
||||
const handleChange = useCallback((newBoardName: string) => {
|
||||
setLocalBoardName(newBoardName);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{ w: 'full', h: 'full', touchAction: 'none', userSelect: 'none' }}
|
||||
return (
|
||||
<Box sx={{ w: 'full', h: 'full', touchAction: 'none', userSelect: 'none' }}>
|
||||
<Flex
|
||||
onMouseOver={handleMouseOver}
|
||||
onMouseOut={handleMouseOut}
|
||||
sx={{
|
||||
position: 'relative',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
aspectRatio: '1/1',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
onMouseOver={handleMouseOver}
|
||||
onMouseOut={handleMouseOut}
|
||||
sx={{
|
||||
position: 'relative',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
aspectRatio: '1/1',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
}}
|
||||
<BoardContextMenu
|
||||
board={board}
|
||||
board_id={board_id}
|
||||
setBoardToDelete={setBoardToDelete}
|
||||
>
|
||||
<BoardContextMenu
|
||||
board={board}
|
||||
board_id={board_id}
|
||||
setBoardToDelete={setBoardToDelete}
|
||||
>
|
||||
{(ref) => (
|
||||
<Tooltip label={tooltip} openDelay={1000} hasArrow>
|
||||
<Flex
|
||||
ref={ref}
|
||||
onClick={handleSelectBoard}
|
||||
sx={{
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
position: 'relative',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: 'base',
|
||||
cursor: 'pointer',
|
||||
bg: 'base.200',
|
||||
_dark: {
|
||||
bg: 'base.800',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{coverImage?.thumbnail_url ? (
|
||||
<Image
|
||||
src={coverImage?.thumbnail_url}
|
||||
draggable={false}
|
||||
{(ref) => (
|
||||
<Tooltip label={tooltip} openDelay={1000} hasArrow>
|
||||
<Flex
|
||||
ref={ref}
|
||||
onClick={handleSelectBoard}
|
||||
sx={{
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
position: 'relative',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: 'base',
|
||||
cursor: 'pointer',
|
||||
bg: 'base.200',
|
||||
_dark: {
|
||||
bg: 'base.800',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{coverImage?.thumbnail_url ? (
|
||||
<Image
|
||||
src={coverImage?.thumbnail_url}
|
||||
draggable={false}
|
||||
sx={{
|
||||
objectFit: 'cover',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
maxH: 'full',
|
||||
borderRadius: 'base',
|
||||
borderBottomRadius: 'lg',
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Flex
|
||||
sx={{
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
boxSize={12}
|
||||
as={FaUser}
|
||||
sx={{
|
||||
objectFit: 'cover',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
maxH: 'full',
|
||||
borderRadius: 'base',
|
||||
borderBottomRadius: 'lg',
|
||||
mt: -6,
|
||||
opacity: 0.7,
|
||||
color: 'base.500',
|
||||
_dark: {
|
||||
color: 'base.500',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Flex
|
||||
sx={{
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
boxSize={12}
|
||||
as={FaUser}
|
||||
sx={{
|
||||
mt: -6,
|
||||
opacity: 0.7,
|
||||
color: 'base.500',
|
||||
_dark: {
|
||||
color: 'base.500',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
{/* <Flex
|
||||
</Flex>
|
||||
)}
|
||||
{/* <Flex
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
insetInlineEnd: 0,
|
||||
@ -231,80 +232,77 @@ const GalleryBoard = memo(
|
||||
{totalImages}/{totalAssets}
|
||||
</Badge>
|
||||
</Flex> */}
|
||||
{isSelectedForAutoAdd && <AutoAddIcon />}
|
||||
<SelectionOverlay
|
||||
isSelected={isSelected}
|
||||
isHovered={isHovered}
|
||||
/>
|
||||
<Flex
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
p: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
w: 'full',
|
||||
maxW: 'full',
|
||||
borderBottomRadius: 'base',
|
||||
bg: isSelected ? 'accent.400' : 'base.500',
|
||||
{isSelectedForAutoAdd && <AutoAddIcon />}
|
||||
<SelectionOverlay
|
||||
isSelected={isSelected}
|
||||
isHovered={isHovered}
|
||||
/>
|
||||
<Flex
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
p: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
w: 'full',
|
||||
maxW: 'full',
|
||||
borderBottomRadius: 'base',
|
||||
bg: isSelected ? 'accent.400' : 'base.500',
|
||||
color: isSelected ? 'base.50' : 'base.100',
|
||||
_dark: {
|
||||
bg: isSelected ? 'accent.500' : 'base.600',
|
||||
color: isSelected ? 'base.50' : 'base.100',
|
||||
_dark: {
|
||||
bg: isSelected ? 'accent.500' : 'base.600',
|
||||
color: isSelected ? 'base.50' : 'base.100',
|
||||
},
|
||||
lineHeight: 'short',
|
||||
fontSize: 'xs',
|
||||
},
|
||||
lineHeight: 'short',
|
||||
fontSize: 'xs',
|
||||
}}
|
||||
>
|
||||
<Editable
|
||||
value={localBoardName}
|
||||
isDisabled={isUpdateBoardLoading}
|
||||
submitOnBlur={true}
|
||||
onChange={handleChange}
|
||||
onSubmit={handleSubmit}
|
||||
sx={{
|
||||
w: 'full',
|
||||
}}
|
||||
>
|
||||
<Editable
|
||||
value={localBoardName}
|
||||
isDisabled={isUpdateBoardLoading}
|
||||
submitOnBlur={true}
|
||||
onChange={handleChange}
|
||||
onSubmit={handleSubmit}
|
||||
<EditablePreview
|
||||
sx={{
|
||||
w: 'full',
|
||||
p: 0,
|
||||
fontWeight: isSelected ? 700 : 500,
|
||||
textAlign: 'center',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
>
|
||||
<EditablePreview
|
||||
sx={{
|
||||
noOfLines={1}
|
||||
/>
|
||||
<EditableInput
|
||||
sx={{
|
||||
p: 0,
|
||||
_focusVisible: {
|
||||
p: 0,
|
||||
fontWeight: isSelected ? 700 : 500,
|
||||
textAlign: 'center',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
noOfLines={1}
|
||||
/>
|
||||
<EditableInput
|
||||
sx={{
|
||||
p: 0,
|
||||
_focusVisible: {
|
||||
p: 0,
|
||||
textAlign: 'center',
|
||||
// get rid of the edit border
|
||||
boxShadow: 'none',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Editable>
|
||||
</Flex>
|
||||
|
||||
<IAIDroppable
|
||||
data={droppableData}
|
||||
dropLabel={<Text fontSize="md">Move</Text>}
|
||||
/>
|
||||
// get rid of the edit border
|
||||
boxShadow: 'none',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Editable>
|
||||
</Flex>
|
||||
</Tooltip>
|
||||
)}
|
||||
</BoardContextMenu>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
GalleryBoard.displayName = 'HoverableBoard';
|
||||
<IAIDroppable
|
||||
data={droppableData}
|
||||
dropLabel={<Text fontSize="md">Move</Text>}
|
||||
/>
|
||||
</Flex>
|
||||
</Tooltip>
|
||||
)}
|
||||
</BoardContextMenu>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default GalleryBoard;
|
||||
export default memo(GalleryBoard);
|
||||
|
@ -3,7 +3,7 @@ import IAIDroppable from 'common/components/IAIDroppable';
|
||||
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
|
||||
import { TypesafeDroppableData } from 'features/dnd/types';
|
||||
import { BoardId } from 'features/gallery/store/types';
|
||||
import { ReactNode } from 'react';
|
||||
import { ReactNode, memo } from 'react';
|
||||
import BoardContextMenu from '../BoardContextMenu';
|
||||
|
||||
type GenericBoardProps = {
|
||||
@ -105,4 +105,4 @@ const GenericBoard = (props: GenericBoardProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default GenericBoard;
|
||||
export default memo(GenericBoard);
|
||||
|
@ -156,4 +156,4 @@ const NoBoardBoard = memo(({ isSelected }: Props) => {
|
||||
|
||||
NoBoardBoard.displayName = 'HoverableBoard';
|
||||
|
||||
export default NoBoardBoard;
|
||||
export default memo(NoBoardBoard);
|
||||
|
@ -26,7 +26,7 @@ import {
|
||||
setShouldShowImageDetails,
|
||||
setShouldShowProgressInViewer,
|
||||
} from 'features/ui/store/uiSlice';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@ -323,4 +323,4 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default CurrentImageButtons;
|
||||
export default memo(CurrentImageButtons);
|
||||
|
@ -2,6 +2,7 @@ import { Flex } from '@chakra-ui/react';
|
||||
|
||||
import CurrentImageButtons from './CurrentImageButtons';
|
||||
import CurrentImagePreview from './CurrentImagePreview';
|
||||
import { memo } from 'react';
|
||||
|
||||
const CurrentImageDisplay = () => {
|
||||
return (
|
||||
@ -22,4 +23,4 @@ const CurrentImageDisplay = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default CurrentImageDisplay;
|
||||
export default memo(CurrentImageDisplay);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
import { FaEyeSlash } from 'react-icons/fa';
|
||||
|
||||
const CurrentImageHidden = () => {
|
||||
@ -18,4 +19,4 @@ const CurrentImageHidden = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default CurrentImageHidden;
|
||||
export default memo(CurrentImageHidden);
|
||||
|
@ -5,6 +5,7 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
||||
import { togglePinGalleryPanel } from 'features/ui/store/uiSlice';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { BsPinAngle, BsPinAngleFill } from 'react-icons/bs';
|
||||
|
||||
@ -41,4 +42,4 @@ const GalleryPinButton = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default GalleryPinButton;
|
||||
export default memo(GalleryPinButton);
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
setGalleryImageMinimumWidth,
|
||||
shouldAutoSwitchChanged,
|
||||
} from 'features/gallery/store/gallerySlice';
|
||||
import { ChangeEvent, useCallback } from 'react';
|
||||
import { ChangeEvent, memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaWrench } from 'react-icons/fa';
|
||||
import BoardAutoAddSelect from './Boards/BoardAutoAddSelect';
|
||||
@ -101,4 +101,4 @@ const GallerySettingsPopover = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default GallerySettingsPopover;
|
||||
export default memo(GallerySettingsPopover);
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
isModalOpenChanged,
|
||||
} from 'features/changeBoardModal/store/slice';
|
||||
import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { FaFolder, FaTrash } from 'react-icons/fa';
|
||||
import { MdStar, MdStarBorder } from 'react-icons/md';
|
||||
import {
|
||||
@ -74,4 +74,4 @@ const MultipleSelectionMenuItems = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default MultipleSelectionMenuItems;
|
||||
export default memo(MultipleSelectionMenuItems);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Flex, Spinner, SpinnerProps } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
|
||||
type ImageFallbackSpinnerProps = SpinnerProps;
|
||||
|
||||
@ -23,4 +24,4 @@ const ImageFallbackSpinner = (props: ImageFallbackSpinnerProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageFallbackSpinner;
|
||||
export default memo(ImageFallbackSpinner);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Box, FlexProps, forwardRef } from '@chakra-ui/react';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { PropsWithChildren, memo } from 'react';
|
||||
|
||||
type ItemContainerProps = PropsWithChildren & FlexProps;
|
||||
const ItemContainer = forwardRef((props: ItemContainerProps, ref) => (
|
||||
@ -8,4 +8,4 @@ const ItemContainer = forwardRef((props: ItemContainerProps, ref) => (
|
||||
</Box>
|
||||
));
|
||||
|
||||
export default ItemContainer;
|
||||
export default memo(ItemContainer);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { FlexProps, Grid, forwardRef } from '@chakra-ui/react';
|
||||
import { RootState } from 'app/store/store';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { PropsWithChildren, memo } from 'react';
|
||||
|
||||
type ListContainerProps = PropsWithChildren & FlexProps;
|
||||
const ListContainer = forwardRef((props: ListContainerProps, ref) => {
|
||||
@ -23,4 +23,4 @@ const ListContainer = forwardRef((props: ListContainerProps, ref) => {
|
||||
);
|
||||
});
|
||||
|
||||
export default ListContainer;
|
||||
export default memo(ListContainer);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Box, Flex, IconButton, Tooltip } from '@chakra-ui/react';
|
||||
import { isString } from 'lodash-es';
|
||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { FaCopy, FaSave } from 'react-icons/fa';
|
||||
|
||||
type Props = {
|
||||
@ -93,4 +93,4 @@ const DataViewer = (props: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default DataViewer;
|
||||
export default memo(DataViewer);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { UnsafeImageMetadata } from 'services/api/types';
|
||||
import ImageMetadataItem from './ImageMetadataItem';
|
||||
|
||||
@ -206,4 +206,4 @@ const ImageMetadataActions = (props: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageMetadataActions;
|
||||
export default memo(ImageMetadataActions);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { ExternalLinkIcon } from '@chakra-ui/icons';
|
||||
import { Flex, IconButton, Link, Text, Tooltip } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaCopy } from 'react-icons/fa';
|
||||
import { IoArrowUndoCircleOutline } from 'react-icons/io5';
|
||||
@ -74,4 +75,4 @@ const ImageMetadataItem = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageMetadataItem;
|
||||
export default memo(ImageMetadataItem);
|
||||
|
@ -5,6 +5,7 @@ import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import { map } from 'lodash-es';
|
||||
import ParamLora from './ParamLora';
|
||||
import { memo } from 'react';
|
||||
|
||||
const selector = createSelector(
|
||||
stateSelector,
|
||||
@ -29,4 +30,4 @@ const ParamLoraList = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamLoraList;
|
||||
export default memo(ParamLoraList);
|
||||
|
@ -9,7 +9,7 @@ import IAIMantineSelectItemWithTooltip from 'common/components/IAIMantineSelectI
|
||||
import { loraAdded } from 'features/lora/store/loraSlice';
|
||||
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
|
||||
import { forEach } from 'lodash-es';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useGetLoRAModelsQuery } from 'services/api/endpoints/models';
|
||||
|
||||
const selector = createSelector(
|
||||
@ -102,4 +102,4 @@ const ParamLoRASelect = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamLoRASelect;
|
||||
export default memo(ParamLoRASelect);
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
isInputFieldValue,
|
||||
} from 'features/nodes/types/types';
|
||||
import { startCase } from 'lodash-es';
|
||||
import { useMemo } from 'react';
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
interface Props {
|
||||
nodeId: string;
|
||||
@ -51,4 +51,4 @@ const FieldTooltipContent = ({ nodeId, fieldName, kind }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default FieldTooltipContent;
|
||||
export default memo(FieldTooltipContent);
|
||||
|
@ -139,7 +139,7 @@ const InputField = ({ nodeId, fieldName }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default InputField;
|
||||
export default memo(InputField);
|
||||
|
||||
type InputFieldWrapperProps = PropsWithChildren<{
|
||||
shouldDim: boolean;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { PropsWithChildren, memo } from 'react';
|
||||
|
||||
const ScrollableContent = (props: PropsWithChildren) => {
|
||||
return (
|
||||
@ -42,4 +42,4 @@ const ScrollableContent = (props: PropsWithChildren) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ScrollableContent;
|
||||
export default memo(ScrollableContent);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { useCanvasGenerationMode } from 'features/canvas/hooks/useCanvasGenerationMode';
|
||||
import { memo } from 'react';
|
||||
|
||||
const GENERATION_MODE_NAME_MAP = {
|
||||
txt2img: 'Text to Image',
|
||||
@ -18,4 +19,4 @@ const GenerationModeStatusText = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default GenerationModeStatusText;
|
||||
export default memo(GenerationModeStatusText);
|
||||
|
@ -5,7 +5,7 @@ import IAITextarea from 'common/components/IAITextarea';
|
||||
import AddEmbeddingButton from 'features/embedding/components/AddEmbeddingButton';
|
||||
import ParamEmbeddingPopover from 'features/embedding/components/ParamEmbeddingPopover';
|
||||
import { setNegativePrompt } from 'features/parameters/store/generationSlice';
|
||||
import { ChangeEvent, KeyboardEvent, useCallback, useRef } from 'react';
|
||||
import { ChangeEvent, KeyboardEvent, memo, useCallback, useRef } from 'react';
|
||||
import { flushSync } from 'react-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus';
|
||||
@ -109,4 +109,4 @@ const ParamNegativeConditioning = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamNegativeConditioning;
|
||||
export default memo(ParamNegativeConditioning);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Box, FormControl, useDisclosure } from '@chakra-ui/react';
|
||||
import { stateSelector } from 'app/store/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { ChangeEvent, KeyboardEvent, useCallback, useRef } from 'react';
|
||||
import { ChangeEvent, KeyboardEvent, memo, useCallback, useRef } from 'react';
|
||||
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import {
|
||||
@ -159,4 +159,4 @@ const ParamPositiveConditioning = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamPositiveConditioning;
|
||||
export default memo(ParamPositiveConditioning);
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
TypesafeDraggableData,
|
||||
TypesafeDroppableData,
|
||||
} from 'features/dnd/types';
|
||||
import { useMemo } from 'react';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||
|
||||
const selector = createSelector(
|
||||
@ -64,4 +64,4 @@ const InitialImage = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default InitialImage;
|
||||
export default memo(InitialImage);
|
||||
|
@ -6,7 +6,7 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
|
||||
import { clearInitialImage } from 'features/parameters/store/generationSlice';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { FaUndo, FaUpload } from 'react-icons/fa';
|
||||
import InitialImage from './InitialImage';
|
||||
import { PostUploadAction } from 'services/api/types';
|
||||
@ -95,4 +95,4 @@ const InitialImageDisplay = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default InitialImageDisplay;
|
||||
export default memo(InitialImageDisplay);
|
||||
|
@ -5,7 +5,7 @@ import IAIButton from 'common/components/IAIButton';
|
||||
import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import IAIPopover from 'common/components/IAIPopover';
|
||||
import { selectIsBusy } from 'features/system/store/systemSelectors';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaExpandArrowsAlt } from 'react-icons/fa';
|
||||
import { ImageDTO } from 'services/api/types';
|
||||
@ -59,4 +59,4 @@ const ParamUpscalePopover = (props: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamUpscalePopover;
|
||||
export default memo(ParamUpscalePopover);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import CancelButton from './CancelButton';
|
||||
import InvokeButton from './InvokeButton';
|
||||
import { memo } from 'react';
|
||||
|
||||
/**
|
||||
* Buttons to start and cancel image generation.
|
||||
@ -14,4 +15,4 @@ const ProcessButtons = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ProcessButtons;
|
||||
export default memo(ProcessButtons);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Box, FormControl, useDisclosure } from '@chakra-ui/react';
|
||||
import { stateSelector } from 'app/store/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { ChangeEvent, KeyboardEvent, useCallback, useRef } from 'react';
|
||||
import { ChangeEvent, KeyboardEvent, memo, useCallback, useRef } from 'react';
|
||||
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { clampSymmetrySteps } from 'features/parameters/store/generationSlice';
|
||||
@ -167,4 +167,4 @@ const ParamSDXLNegativeStyleConditioning = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamSDXLNegativeStyleConditioning;
|
||||
export default memo(ParamSDXLNegativeStyleConditioning);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Box, FormControl, useDisclosure } from '@chakra-ui/react';
|
||||
import { stateSelector } from 'app/store/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { ChangeEvent, KeyboardEvent, useCallback, useRef } from 'react';
|
||||
import { ChangeEvent, KeyboardEvent, memo, useCallback, useRef } from 'react';
|
||||
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { clampSymmetrySteps } from 'features/parameters/store/generationSlice';
|
||||
@ -166,4 +166,4 @@ const ParamSDXLPositiveStyleConditioning = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamSDXLPositiveStyleConditioning;
|
||||
export default memo(ParamSDXLPositiveStyleConditioning);
|
||||
|
@ -12,6 +12,7 @@ import ParamSDXLRefinerScheduler from './SDXLRefiner/ParamSDXLRefinerScheduler';
|
||||
import ParamSDXLRefinerStart from './SDXLRefiner/ParamSDXLRefinerStart';
|
||||
import ParamSDXLRefinerSteps from './SDXLRefiner/ParamSDXLRefinerSteps';
|
||||
import ParamUseSDXLRefiner from './SDXLRefiner/ParamUseSDXLRefiner';
|
||||
import { memo } from 'react';
|
||||
|
||||
const selector = createSelector(
|
||||
stateSelector,
|
||||
@ -47,4 +48,4 @@ const ParamSDXLRefinerCollapse = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ParamSDXLRefinerCollapse;
|
||||
export default memo(ParamSDXLRefinerCollapse);
|
||||
|
@ -6,6 +6,7 @@ import ProcessButtons from 'features/parameters/components/ProcessButtons/Proces
|
||||
import ParamSDXLPromptArea from './ParamSDXLPromptArea';
|
||||
import ParamSDXLRefinerCollapse from './ParamSDXLRefinerCollapse';
|
||||
import SDXLImageToImageTabCoreParameters from './SDXLImageToImageTabCoreParameters';
|
||||
import { memo } from 'react';
|
||||
|
||||
const SDXLImageToImageTabParameters = () => {
|
||||
return (
|
||||
@ -22,4 +23,4 @@ const SDXLImageToImageTabParameters = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SDXLImageToImageTabParameters;
|
||||
export default memo(SDXLImageToImageTabParameters);
|
||||
|
@ -6,6 +6,7 @@ import ProcessButtons from 'features/parameters/components/ProcessButtons/Proces
|
||||
import TextToImageTabCoreParameters from 'features/ui/components/tabs/TextToImage/TextToImageTabCoreParameters';
|
||||
import ParamSDXLPromptArea from './ParamSDXLPromptArea';
|
||||
import ParamSDXLRefinerCollapse from './ParamSDXLRefinerCollapse';
|
||||
import { memo } from 'react';
|
||||
|
||||
const SDXLTextToImageTabParameters = () => {
|
||||
return (
|
||||
@ -22,4 +23,4 @@ const SDXLTextToImageTabParameters = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SDXLTextToImageTabParameters;
|
||||
export default memo(SDXLTextToImageTabParameters);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Flex, Image, Text } from '@chakra-ui/react';
|
||||
import InvokeAILogoImage from 'assets/images/logo.png';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { useRef } from 'react';
|
||||
import { memo, useRef } from 'react';
|
||||
import { useHoverDirty } from 'react-use';
|
||||
import { useGetAppVersionQuery } from 'services/api/endpoints/appInfo';
|
||||
|
||||
@ -66,4 +66,4 @@ const InvokeAILogoComponent = ({ showVersion = true }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default InvokeAILogoComponent;
|
||||
export default memo(InvokeAILogoComponent);
|
||||
|
@ -39,6 +39,7 @@ import {
|
||||
ChangeEvent,
|
||||
ReactElement,
|
||||
cloneElement,
|
||||
memo,
|
||||
useCallback,
|
||||
useEffect,
|
||||
} from 'react';
|
||||
@ -398,4 +399,4 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsModal;
|
||||
export default memo(SettingsModal);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { PropsWithChildren, memo } from 'react';
|
||||
|
||||
const StyledFlex = (props: PropsWithChildren) => {
|
||||
return (
|
||||
@ -20,4 +20,4 @@ const StyledFlex = (props: PropsWithChildren) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default StyledFlex;
|
||||
export default memo(StyledFlex);
|
||||
|
@ -4,7 +4,7 @@ import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { ResourceKey } from 'i18next';
|
||||
import { useMemo, useRef } from 'react';
|
||||
import { memo, useMemo, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaCircle } from 'react-icons/fa';
|
||||
import { useHoverDirty } from 'react-use';
|
||||
@ -125,4 +125,4 @@ const StatusIndicator = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default StatusIndicator;
|
||||
export default memo(StatusIndicator);
|
||||
|
@ -6,6 +6,7 @@ import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvas
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { BsPinAngle, BsPinAngleFill } from 'react-icons/bs';
|
||||
import { setShouldPinParametersPanel } from '../store/uiSlice';
|
||||
import { memo } from 'react';
|
||||
|
||||
type PinParametersPanelButtonProps = Omit<IAIIconButtonProps, 'aria-label'>;
|
||||
|
||||
@ -55,4 +56,4 @@ const PinParametersPanelButton = (props: PinParametersPanelButtonProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default PinParametersPanelButton;
|
||||
export default memo(PinParametersPanelButton);
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
ResizeCallback,
|
||||
ResizeStartCallback,
|
||||
} from 're-resizable';
|
||||
import { ReactNode, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { ReactNode, memo, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { LangDirection } from './types';
|
||||
import {
|
||||
getHandleEnables,
|
||||
@ -193,4 +193,4 @@ const ResizableDrawer = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default ResizableDrawer;
|
||||
export default memo(ResizableDrawer);
|
||||
|
@ -9,6 +9,7 @@ import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Sym
|
||||
import ParamPromptArea from 'features/parameters/components/Parameters/Prompt/ParamPromptArea';
|
||||
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
|
||||
import ImageToImageTabCoreParameters from './ImageToImageTabCoreParameters';
|
||||
import { memo } from 'react';
|
||||
|
||||
const ImageToImageTabParameters = () => {
|
||||
return (
|
||||
@ -28,4 +29,4 @@ const ImageToImageTabParameters = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageToImageTabParameters;
|
||||
export default memo(ImageToImageTabParameters);
|
||||
|
@ -3,7 +3,7 @@ import { EntityState } from '@reduxjs/toolkit';
|
||||
import IAIButton from 'common/components/IAIButton';
|
||||
import IAIInput from 'common/components/IAIInput';
|
||||
import { forEach } from 'lodash-es';
|
||||
import type { ChangeEvent, PropsWithChildren } from 'react';
|
||||
import { ChangeEvent, PropsWithChildren, memo } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ALL_BASE_MODELS } from 'services/api/constants';
|
||||
@ -232,7 +232,7 @@ const ModelList = (props: ModelListProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ModelList;
|
||||
export default memo(ModelList);
|
||||
|
||||
const modelsFilter = <
|
||||
T extends
|
||||
@ -266,7 +266,7 @@ const modelsFilter = <
|
||||
return filteredModels;
|
||||
};
|
||||
|
||||
const StyledModelContainer = (props: PropsWithChildren) => {
|
||||
const StyledModelContainer = memo((props: PropsWithChildren) => {
|
||||
return (
|
||||
<Flex
|
||||
flexDirection="column"
|
||||
@ -283,7 +283,9 @@ const StyledModelContainer = (props: PropsWithChildren) => {
|
||||
{props.children}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
StyledModelContainer.displayName = 'StyledModelContainer';
|
||||
|
||||
type ModelListWrapperProps = {
|
||||
title: string;
|
||||
@ -294,7 +296,7 @@ type ModelListWrapperProps = {
|
||||
selected: ModelListProps;
|
||||
};
|
||||
|
||||
function ModelListWrapper(props: ModelListWrapperProps) {
|
||||
const ModelListWrapper = memo((props: ModelListWrapperProps) => {
|
||||
const { title, modelList, selected } = props;
|
||||
return (
|
||||
<StyledModelContainer>
|
||||
@ -313,23 +315,29 @@ function ModelListWrapper(props: ModelListWrapperProps) {
|
||||
</Flex>
|
||||
</StyledModelContainer>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
function FetchingModelsLoader({ loadingMessage }: { loadingMessage?: string }) {
|
||||
return (
|
||||
<StyledModelContainer>
|
||||
<Flex
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
flexDirection="column"
|
||||
p={4}
|
||||
gap={8}
|
||||
>
|
||||
<Spinner />
|
||||
<Text variant="subtext">
|
||||
{loadingMessage ? loadingMessage : 'Fetching...'}
|
||||
</Text>
|
||||
</Flex>
|
||||
</StyledModelContainer>
|
||||
);
|
||||
}
|
||||
ModelListWrapper.displayName = 'ModelListWrapper';
|
||||
|
||||
const FetchingModelsLoader = memo(
|
||||
({ loadingMessage }: { loadingMessage?: string }) => {
|
||||
return (
|
||||
<StyledModelContainer>
|
||||
<Flex
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
flexDirection="column"
|
||||
p={4}
|
||||
gap={8}
|
||||
>
|
||||
<Spinner />
|
||||
<Text variant="subtext">
|
||||
{loadingMessage ? loadingMessage : 'Fetching...'}
|
||||
</Text>
|
||||
</Flex>
|
||||
</StyledModelContainer>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
FetchingModelsLoader.displayName = 'FetchingModelsLoader';
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import CurrentImageDisplay from 'features/gallery/components/CurrentImage/CurrentImageDisplay';
|
||||
import { memo } from 'react';
|
||||
|
||||
const TextToImageTabMain = () => {
|
||||
return (
|
||||
@ -25,4 +26,4 @@ const TextToImageTabMain = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default TextToImageTabMain;
|
||||
export default memo(TextToImageTabMain);
|
||||
|
@ -9,6 +9,7 @@ import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Sym
|
||||
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
|
||||
import ParamPromptArea from '../../../../parameters/components/Parameters/Prompt/ParamPromptArea';
|
||||
import TextToImageTabCoreParameters from './TextToImageTabCoreParameters';
|
||||
import { memo } from 'react';
|
||||
|
||||
const TextToImageTabParameters = () => {
|
||||
return (
|
||||
@ -28,4 +29,4 @@ const TextToImageTabParameters = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default TextToImageTabParameters;
|
||||
export default memo(TextToImageTabParameters);
|
||||
|
@ -18,6 +18,7 @@ import { FaWrench } from 'react-icons/fa';
|
||||
import ClearCanvasHistoryButtonModal from 'features/canvas/components/ClearCanvasHistoryButtonModal';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { memo } from 'react';
|
||||
|
||||
export const canvasControlsSelector = createSelector(
|
||||
[canvasSelector],
|
||||
@ -109,4 +110,4 @@ const UnifiedCanvasSettings = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default UnifiedCanvasSettings;
|
||||
export default memo(UnifiedCanvasSettings);
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { memo } from 'react';
|
||||
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -161,4 +162,4 @@ const UnifiedCanvasToolSelect = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default UnifiedCanvasToolSelect;
|
||||
export default memo(UnifiedCanvasToolSelect);
|
||||
|
@ -14,6 +14,7 @@ import UnifiedCanvasResetCanvas from './UnifiedCanvasToolbar/UnifiedCanvasResetC
|
||||
import UnifiedCanvasResetView from './UnifiedCanvasToolbar/UnifiedCanvasResetView';
|
||||
import UnifiedCanvasSaveToGallery from './UnifiedCanvasToolbar/UnifiedCanvasSaveToGallery';
|
||||
import UnifiedCanvasToolSelect from './UnifiedCanvasToolbar/UnifiedCanvasToolSelect';
|
||||
import { memo } from 'react';
|
||||
|
||||
const UnifiedCanvasToolbarBeta = () => {
|
||||
return (
|
||||
@ -51,4 +52,4 @@ const UnifiedCanvasToolbarBeta = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default UnifiedCanvasToolbarBeta;
|
||||
export default memo(UnifiedCanvasToolbarBeta);
|
||||
|
@ -10,6 +10,7 @@ import ParamSeamPaintingCollapse from 'features/parameters/components/Parameters
|
||||
import ParamPromptArea from 'features/parameters/components/Parameters/Prompt/ParamPromptArea';
|
||||
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
|
||||
import UnifiedCanvasCoreParameters from './UnifiedCanvasCoreParameters';
|
||||
import { memo } from 'react';
|
||||
|
||||
const UnifiedCanvasParameters = () => {
|
||||
return (
|
||||
@ -30,4 +31,4 @@ const UnifiedCanvasParameters = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default UnifiedCanvasParameters;
|
||||
export default memo(UnifiedCanvasParameters);
|
||||
|
Loading…
Reference in New Issue
Block a user