mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): memoize everything nodes
This commit is contained in:
parent
4901911c1a
commit
43addc1548
@ -1,7 +1,7 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import 'reactflow/dist/style.css';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import {
|
||||
Tooltip,
|
||||
Menu,
|
||||
@ -21,7 +21,7 @@ import { makeToast } from 'features/system/hooks/useToastWatcher';
|
||||
import { IAIIconButton } from 'exports';
|
||||
import { AnyInvocationType } from 'services/events/types';
|
||||
|
||||
export const AddNodeMenu = () => {
|
||||
const AddNodeMenu = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const invocationTemplates = useAppSelector(
|
||||
@ -67,3 +67,5 @@ export const AddNodeMenu = () => {
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(AddNodeMenu);
|
||||
|
@ -2,8 +2,9 @@ import 'reactflow/dist/style.css';
|
||||
import { Tooltip, Badge, HStack } from '@chakra-ui/react';
|
||||
import { map } from 'lodash';
|
||||
import { FIELDS } from '../types/constants';
|
||||
import { memo } from 'react';
|
||||
|
||||
export const FieldTypeLegend = () => {
|
||||
const FieldTypeLegend = () => {
|
||||
return (
|
||||
<HStack>
|
||||
{map(FIELDS, ({ title, description, color }, key) => (
|
||||
@ -16,3 +17,5 @@ export const FieldTypeLegend = () => {
|
||||
</HStack>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(FieldTypeLegend);
|
||||
|
@ -1,15 +1,12 @@
|
||||
import {
|
||||
Background,
|
||||
Controls,
|
||||
MiniMap,
|
||||
OnConnect,
|
||||
OnEdgesChange,
|
||||
OnNodesChange,
|
||||
ReactFlow,
|
||||
ConnectionLineType,
|
||||
OnConnectStart,
|
||||
OnConnectEnd,
|
||||
Panel,
|
||||
} from 'reactflow';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import { RootState } from 'app/store';
|
||||
@ -20,16 +17,8 @@ import {
|
||||
edgesChanged,
|
||||
nodesChanged,
|
||||
} from '../store/nodesSlice';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import { InvocationComponent } from './InvocationComponent';
|
||||
import { AddNodeMenu } from './AddNodeMenu';
|
||||
import { FieldTypeLegend } from './FieldTypeLegend';
|
||||
import { Button } from '@chakra-ui/react';
|
||||
import { nodesGraphBuilt } from 'services/thunks/session';
|
||||
import { IAIIconButton } from 'exports';
|
||||
import { InfoIcon } from '@chakra-ui/icons';
|
||||
import { ViewportControls } from './ViewportControls';
|
||||
import NodeGraphOverlay from './NodeGraphOverlay';
|
||||
import TopLeftPanel from './panels/TopLeftPanel';
|
||||
import TopRightPanel from './panels/TopRightPanel';
|
||||
import TopCenterPanel from './panels/TopCenterPanel';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Flex, Heading, Tooltip, Icon } from '@chakra-ui/react';
|
||||
import { InvocationTemplate } from 'features/nodes/types/types';
|
||||
import { MutableRefObject } from 'react';
|
||||
import { memo, MutableRefObject } from 'react';
|
||||
import { FaInfoCircle } from 'react-icons/fa';
|
||||
|
||||
interface IAINodeHeaderProps {
|
||||
@ -8,7 +8,7 @@ interface IAINodeHeaderProps {
|
||||
template: InvocationTemplate;
|
||||
}
|
||||
|
||||
export default function IAINodeHeader(props: IAINodeHeaderProps) {
|
||||
const IAINodeHeader = (props: IAINodeHeaderProps) => {
|
||||
const { nodeId, template } = props;
|
||||
return (
|
||||
<Flex
|
||||
@ -34,4 +34,6 @@ export default function IAINodeHeader(props: IAINodeHeaderProps) {
|
||||
</Tooltip>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default memo(IAINodeHeader);
|
||||
|
@ -19,7 +19,7 @@ import {
|
||||
} from '@chakra-ui/react';
|
||||
import FieldHandle from '../FieldHandle';
|
||||
import { useIsValidConnection } from 'features/nodes/hooks/useIsValidConnection';
|
||||
import { InputFieldComponent } from '../InputFieldComponent';
|
||||
import InputFieldComponent from '../InputFieldComponent';
|
||||
import { FaInfoCircle } from 'react-icons/fa';
|
||||
import { HANDLE_TOOLTIP_OPEN_DELAY } from 'features/nodes/types/constants';
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { memo } from 'react';
|
||||
import { NodeResizeControl, NodeResizerProps } from 'reactflow';
|
||||
|
||||
export default function IAINodeResizer(props: NodeResizerProps) {
|
||||
const IAINodeResizer = (props: NodeResizerProps) => {
|
||||
const { ...rest } = props;
|
||||
return (
|
||||
<NodeResizeControl
|
||||
@ -17,4 +18,6 @@ export default function IAINodeResizer(props: NodeResizerProps) {
|
||||
{...rest}
|
||||
></NodeResizeControl>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default memo(IAINodeResizer);
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
import { InputFieldTemplate, InputFieldValue } from '../types/types';
|
||||
import { ArrayInputFieldComponent } from './fields/ArrayInputFieldComponent';
|
||||
import { BooleanInputFieldComponent } from './fields/BooleanInputFieldComponent';
|
||||
import { EnumInputFieldComponent } from './fields/EnumInputFieldComponent';
|
||||
import { ImageInputFieldComponent } from './fields/ImageInputFieldComponent';
|
||||
import { LatentsInputFieldComponent } from './fields/LatentsInputFieldComponent';
|
||||
import { ModelInputFieldComponent } from './fields/ModelInputFieldComponent';
|
||||
import { NumberInputFieldComponent } from './fields/NumberInputFieldComponent';
|
||||
import { StringInputFieldComponent } from './fields/StringInputFieldComponent';
|
||||
import ArrayInputFieldComponent from './fields/ArrayInputFieldComponent';
|
||||
import BooleanInputFieldComponent from './fields/BooleanInputFieldComponent';
|
||||
import EnumInputFieldComponent from './fields/EnumInputFieldComponent';
|
||||
import ImageInputFieldComponent from './fields/ImageInputFieldComponent';
|
||||
import LatentsInputFieldComponent from './fields/LatentsInputFieldComponent';
|
||||
import ModelInputFieldComponent from './fields/ModelInputFieldComponent';
|
||||
import NumberInputFieldComponent from './fields/NumberInputFieldComponent';
|
||||
import StringInputFieldComponent from './fields/StringInputFieldComponent';
|
||||
|
||||
type InputFieldComponentProps = {
|
||||
nodeId: string;
|
||||
@ -16,7 +17,7 @@ type InputFieldComponentProps = {
|
||||
};
|
||||
|
||||
// build an individual input element based on the schema
|
||||
export const InputFieldComponent = (props: InputFieldComponentProps) => {
|
||||
const InputFieldComponent = (props: InputFieldComponentProps) => {
|
||||
const { nodeId, field, template } = props;
|
||||
const { type, value } = field;
|
||||
|
||||
@ -105,3 +106,5 @@ export const InputFieldComponent = (props: InputFieldComponentProps) => {
|
||||
|
||||
return <Box p={2}>Unknown field type: {type}</Box>;
|
||||
};
|
||||
|
||||
export default memo(InputFieldComponent);
|
||||
|
@ -1,14 +1,12 @@
|
||||
import { NodeProps, NodeResizeControl } from 'reactflow';
|
||||
import { NodeProps } from 'reactflow';
|
||||
import { Box, Flex, Icon, useToken } from '@chakra-ui/react';
|
||||
import { FaExclamationCircle } from 'react-icons/fa';
|
||||
import { InvocationTemplate, InvocationValue } from '../types/types';
|
||||
|
||||
import { memo, PropsWithChildren, useMemo, useRef } from 'react';
|
||||
import { useGetInvocationTemplate } from '../hooks/useInvocationTemplate';
|
||||
import { memo, PropsWithChildren, useMemo } from 'react';
|
||||
import IAINodeOutputs from './IAINode/IAINodeOutputs';
|
||||
import IAINodeInputs from './IAINode/IAINodeInputs';
|
||||
import IAINodeHeader from './IAINode/IAINodeHeader';
|
||||
import { IoResize } from 'react-icons/io5';
|
||||
import IAINodeResizer from './IAINode/IAINodeResizer';
|
||||
import { RootState } from 'app/store';
|
||||
import { AnyInvocationType } from 'services/events/types';
|
||||
|
@ -3,6 +3,7 @@ import { Box } from '@chakra-ui/react';
|
||||
import { ReactFlowProvider } from 'reactflow';
|
||||
|
||||
import { Flow } from './Flow';
|
||||
import { memo } from 'react';
|
||||
|
||||
const NodeEditor = () => {
|
||||
return (
|
||||
@ -22,4 +23,4 @@ const NodeEditor = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default NodeEditor;
|
||||
export default memo(NodeEditor);
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppSelector } from 'app/storeHooks';
|
||||
import { memo } from 'react';
|
||||
import { buildNodesGraph } from '../util/nodesGraphBuilder/buildNodesGraph';
|
||||
|
||||
export default function NodeGraphOverlay() {
|
||||
const NodeGraphOverlay = () => {
|
||||
const state = useAppSelector((state: RootState) => state);
|
||||
const graph = buildNodesGraph(state);
|
||||
|
||||
@ -14,7 +15,6 @@ export default function NodeGraphOverlay() {
|
||||
position="absolute"
|
||||
top={10}
|
||||
right={2}
|
||||
userSelect="none"
|
||||
opacity={0.7}
|
||||
background="base.800"
|
||||
p={2}
|
||||
@ -25,4 +25,6 @@ export default function NodeGraphOverlay() {
|
||||
{JSON.stringify(graph, null, 2)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default memo(NodeGraphOverlay);
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { ButtonGroup } from '@chakra-ui/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import { IAIIconButton } from 'exports';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { FaCode, FaExpand, FaMinus, FaPlus } from 'react-icons/fa';
|
||||
import { useReactFlow } from 'reactflow';
|
||||
import { shouldShowGraphOverlayChanged } from '../store/nodesSlice';
|
||||
|
||||
export const ViewportControls = () => {
|
||||
const ViewportControls = () => {
|
||||
const { zoomIn, zoomOut, fitView } = useReactFlow();
|
||||
const dispatch = useAppDispatch();
|
||||
const shouldShowGraphOverlay = useAppSelector(
|
||||
@ -55,3 +55,5 @@ export const ViewportControls = () => {
|
||||
</ButtonGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(ViewportControls);
|
||||
|
@ -2,13 +2,16 @@ import {
|
||||
ArrayInputFieldTemplate,
|
||||
ArrayInputFieldValue,
|
||||
} from 'features/nodes/types/types';
|
||||
import { FaImage, FaList } from 'react-icons/fa';
|
||||
import { memo } from 'react';
|
||||
import { FaList } from 'react-icons/fa';
|
||||
import { FieldComponentProps } from './types';
|
||||
|
||||
export const ArrayInputFieldComponent = (
|
||||
const ArrayInputFieldComponent = (
|
||||
props: FieldComponentProps<ArrayInputFieldValue, ArrayInputFieldTemplate>
|
||||
) => {
|
||||
const { nodeId, field } = props;
|
||||
|
||||
return <FaList />;
|
||||
};
|
||||
|
||||
export default memo(ArrayInputFieldComponent);
|
||||
|
@ -5,10 +5,10 @@ import {
|
||||
BooleanInputFieldTemplate,
|
||||
BooleanInputFieldValue,
|
||||
} from 'features/nodes/types/types';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { ChangeEvent, memo } from 'react';
|
||||
import { FieldComponentProps } from './types';
|
||||
|
||||
export const BooleanInputFieldComponent = (
|
||||
const BooleanInputFieldComponent = (
|
||||
props: FieldComponentProps<BooleanInputFieldValue, BooleanInputFieldTemplate>
|
||||
) => {
|
||||
const { nodeId, field } = props;
|
||||
@ -29,3 +29,5 @@ export const BooleanInputFieldComponent = (
|
||||
<Switch onChange={handleValueChanged} isChecked={field.value}></Switch>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(BooleanInputFieldComponent);
|
||||
|
@ -5,10 +5,10 @@ import {
|
||||
EnumInputFieldTemplate,
|
||||
EnumInputFieldValue,
|
||||
} from 'features/nodes/types/types';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { ChangeEvent, memo } from 'react';
|
||||
import { FieldComponentProps } from './types';
|
||||
|
||||
export const EnumInputFieldComponent = (
|
||||
const EnumInputFieldComponent = (
|
||||
props: FieldComponentProps<EnumInputFieldValue, EnumInputFieldTemplate>
|
||||
) => {
|
||||
const { nodeId, field, template } = props;
|
||||
@ -33,3 +33,5 @@ export const EnumInputFieldComponent = (
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(EnumInputFieldComponent);
|
||||
|
@ -9,12 +9,12 @@ import {
|
||||
ImageInputFieldTemplate,
|
||||
ImageInputFieldValue,
|
||||
} from 'features/nodes/types/types';
|
||||
import { DragEvent, useCallback, useState } from 'react';
|
||||
import { DragEvent, memo, useCallback, useState } from 'react';
|
||||
import { FaImage } from 'react-icons/fa';
|
||||
import { ImageType } from 'services/api';
|
||||
import { FieldComponentProps } from './types';
|
||||
|
||||
export const ImageInputFieldComponent = (
|
||||
const ImageInputFieldComponent = (
|
||||
props: FieldComponentProps<ImageInputFieldValue, ImageInputFieldTemplate>
|
||||
) => {
|
||||
const { nodeId, field } = props;
|
||||
@ -62,3 +62,5 @@ export const ImageInputFieldComponent = (
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(ImageInputFieldComponent);
|
||||
|
@ -2,12 +2,15 @@ import {
|
||||
LatentsInputFieldTemplate,
|
||||
LatentsInputFieldValue,
|
||||
} from 'features/nodes/types/types';
|
||||
import { memo } from 'react';
|
||||
import { FieldComponentProps } from './types';
|
||||
|
||||
export const LatentsInputFieldComponent = (
|
||||
const LatentsInputFieldComponent = (
|
||||
props: FieldComponentProps<LatentsInputFieldValue, LatentsInputFieldTemplate>
|
||||
) => {
|
||||
const { nodeId, field } = props;
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default memo(LatentsInputFieldComponent);
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
selectModelsIds,
|
||||
} from 'features/system/store/modelSlice';
|
||||
import { isEqual, map } from 'lodash';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { ChangeEvent, memo } from 'react';
|
||||
import { FieldComponentProps } from './types';
|
||||
|
||||
const availableModelsSelector = createSelector(
|
||||
@ -28,7 +28,7 @@ const availableModelsSelector = createSelector(
|
||||
}
|
||||
);
|
||||
|
||||
export const ModelInputFieldComponent = (
|
||||
const ModelInputFieldComponent = (
|
||||
props: FieldComponentProps<ModelInputFieldValue, ModelInputFieldTemplate>
|
||||
) => {
|
||||
const { nodeId, field } = props;
|
||||
@ -55,3 +55,5 @@ export const ModelInputFieldComponent = (
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(ModelInputFieldComponent);
|
||||
|
@ -13,9 +13,10 @@ import {
|
||||
IntegerInputFieldTemplate,
|
||||
IntegerInputFieldValue,
|
||||
} from 'features/nodes/types/types';
|
||||
import { memo } from 'react';
|
||||
import { FieldComponentProps } from './types';
|
||||
|
||||
export const NumberInputFieldComponent = (
|
||||
const NumberInputFieldComponent = (
|
||||
props: FieldComponentProps<
|
||||
IntegerInputFieldValue | FloatInputFieldValue,
|
||||
IntegerInputFieldTemplate | FloatInputFieldTemplate
|
||||
@ -39,3 +40,5 @@ export const NumberInputFieldComponent = (
|
||||
</NumberInput>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(NumberInputFieldComponent);
|
||||
|
@ -5,10 +5,10 @@ import {
|
||||
StringInputFieldTemplate,
|
||||
StringInputFieldValue,
|
||||
} from 'features/nodes/types/types';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { ChangeEvent, memo } from 'react';
|
||||
import { FieldComponentProps } from './types';
|
||||
|
||||
export const StringInputFieldComponent = (
|
||||
const StringInputFieldComponent = (
|
||||
props: FieldComponentProps<StringInputFieldValue, StringInputFieldTemplate>
|
||||
) => {
|
||||
const { nodeId, field } = props;
|
||||
@ -27,3 +27,5 @@ export const StringInputFieldComponent = (
|
||||
|
||||
return <Input onChange={handleValueChanged} value={field.value}></Input>;
|
||||
};
|
||||
|
||||
export default memo(StringInputFieldComponent);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { memo } from 'react';
|
||||
import { Panel } from 'reactflow';
|
||||
import { ViewportControls } from '../ViewportControls';
|
||||
import ViewportControls from '../ViewportControls';
|
||||
|
||||
const BottomLeftPanel = () => (
|
||||
<Panel position="bottom-left">
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { memo } from 'react';
|
||||
import { Panel } from 'reactflow';
|
||||
import { AddNodeMenu } from '../AddNodeMenu';
|
||||
import AddNodeMenu from '../AddNodeMenu';
|
||||
|
||||
const TopLeftPanel = () => (
|
||||
<Panel position="top-left">
|
||||
|
@ -2,7 +2,7 @@ import { RootState } from 'app/store';
|
||||
import { useAppSelector } from 'app/storeHooks';
|
||||
import { memo } from 'react';
|
||||
import { Panel } from 'reactflow';
|
||||
import { FieldTypeLegend } from '../FieldTypeLegend';
|
||||
import FieldTypeLegend from '../FieldTypeLegend';
|
||||
import NodeGraphOverlay from '../NodeGraphOverlay';
|
||||
|
||||
const TopRightPanel = () => {
|
||||
|
Loading…
Reference in New Issue
Block a user