From 265996d230f4727d1f58c3e75cdc847ddac6497b Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Mon, 10 Jul 2023 11:21:56 +1000
Subject: [PATCH 1/4] feat(ui): memoize ImageContextMenu selector
Without the selector itself being memoized, the gallery was rerendering on every progress image.
---
.../gallery/components/ImageContextMenu.tsx | 75 +++++++++----------
1 file changed, 35 insertions(+), 40 deletions(-)
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu.tsx
index 1e5f95ab0d..64b1d349d8 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu.tsx
@@ -1,49 +1,32 @@
-import { MenuItem, MenuList } from '@chakra-ui/react';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import { memo, useCallback, useContext } from 'react';
-import {
- FaExpand,
- FaFolder,
- FaFolderPlus,
- FaShare,
- FaTrash,
-} from 'react-icons/fa';
-import { ContextMenu, ContextMenuProps } from 'chakra-ui-contextmenu';
-import {
- resizeAndScaleCanvas,
- setInitialCanvasImage,
-} from 'features/canvas/store/canvasSlice';
-import { setActiveTab } from 'features/ui/store/uiSlice';
-import { useTranslation } from 'react-i18next';
import { ExternalLinkIcon } from '@chakra-ui/icons';
-import { IoArrowUndoCircleOutline } from 'react-icons/io5';
+import { MenuItem, MenuList } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
-import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
-import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters';
-import { initialImageSelected } from 'features/parameters/store/actions';
-import { sentImageToCanvas, sentImageToImg2Img } from '../store/actions';
import { useAppToaster } from 'app/components/Toaster';
-import { AddImageToBoardContext } from '../../../app/contexts/AddImageToBoardContext';
-import { useRemoveImageFromBoardMutation } from 'services/api/endpoints/boardImages';
-import { ImageDTO } from 'services/api/types';
-import { RootState, stateSelector } from 'app/store/store';
+import { stateSelector } from 'app/store/store';
+import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
+import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
+import { ContextMenu, ContextMenuProps } from 'chakra-ui-contextmenu';
import {
imagesAddedToBatch,
selectionAddedToBatch,
} from 'features/batch/store/batchSlice';
-import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
+import {
+ resizeAndScaleCanvas,
+ setInitialCanvasImage,
+} from 'features/canvas/store/canvasSlice';
import { imageToDeleteSelected } from 'features/imageDeletion/store/imageDeletionSlice';
-
-const selector = createSelector(
- [stateSelector, (state: RootState, imageDTO: ImageDTO) => imageDTO],
- ({ gallery, batch }, imageDTO) => {
- const selectionCount = gallery.selection.length;
- const isInBatch = batch.imageNames.includes(imageDTO.image_name);
-
- return { selectionCount, isInBatch };
- },
- defaultSelectorOptions
-);
+import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters';
+import { initialImageSelected } from 'features/parameters/store/actions';
+import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
+import { setActiveTab } from 'features/ui/store/uiSlice';
+import { memo, useCallback, useContext, useMemo } from 'react';
+import { useTranslation } from 'react-i18next';
+import { FaExpand, FaFolder, FaShare, FaTrash } from 'react-icons/fa';
+import { IoArrowUndoCircleOutline } from 'react-icons/io5';
+import { useRemoveImageFromBoardMutation } from 'services/api/endpoints/boardImages';
+import { ImageDTO } from 'services/api/types';
+import { AddImageToBoardContext } from '../../../app/contexts/AddImageToBoardContext';
+import { sentImageToCanvas, sentImageToImg2Img } from '../store/actions';
type Props = {
image: ImageDTO;
@@ -51,9 +34,21 @@ type Props = {
};
const ImageContextMenu = ({ image, children }: Props) => {
- const { selectionCount, isInBatch } = useAppSelector((state) =>
- selector(state, image)
+ const selector = useMemo(
+ () =>
+ createSelector(
+ [stateSelector],
+ ({ gallery, batch }) => {
+ const selectionCount = gallery.selection.length;
+ const isInBatch = batch.imageNames.includes(image.image_name);
+
+ return { selectionCount, isInBatch };
+ },
+ defaultSelectorOptions
+ ),
+ [image.image_name]
);
+ const { selectionCount, isInBatch } = useAppSelector(selector);
const dispatch = useAppDispatch();
const { t } = useTranslation();
From a7b8109ac28d13bfc62d0246b2c07f139dc95358 Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Mon, 10 Jul 2023 11:22:34 +1000
Subject: [PATCH 2/4] feat(ui): memoize NextPrevImageButtons component
This was rerendering on every progress image, now it doesn't
---
.../src/features/gallery/components/NextPrevImageButtons.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/invokeai/frontend/web/src/features/gallery/components/NextPrevImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/NextPrevImageButtons.tsx
index 4177db9a1b..3fcdd54cc9 100644
--- a/invokeai/frontend/web/src/features/gallery/components/NextPrevImageButtons.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/NextPrevImageButtons.tsx
@@ -8,7 +8,7 @@ import {
selectImagesById,
} from 'features/gallery/store/gallerySlice';
import { clamp, isEqual } from 'lodash-es';
-import { useCallback, useState } from 'react';
+import { memo, useCallback, useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
import { FaAngleDoubleRight, FaAngleLeft, FaAngleRight } from 'react-icons/fa';
@@ -227,4 +227,4 @@ const NextPrevImageButtons = () => {
);
};
-export default NextPrevImageButtons;
+export default memo(NextPrevImageButtons);
From 1c45d18e6d1065dc875e98a6e510ddc51d098a4c Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Mon, 10 Jul 2023 11:23:13 +1000
Subject: [PATCH 3/4] fix(ui): correctly set disabled on invoke button during
generation
It wasn't disabled when it should have been, looked clickable during generation.
---
.../parameters/components/ProcessButtons/InvokeButton.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/invokeai/frontend/web/src/features/parameters/components/ProcessButtons/InvokeButton.tsx b/invokeai/frontend/web/src/features/parameters/components/ProcessButtons/InvokeButton.tsx
index e2338e2575..2e399647d8 100644
--- a/invokeai/frontend/web/src/features/parameters/components/ProcessButtons/InvokeButton.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/ProcessButtons/InvokeButton.tsx
@@ -78,7 +78,7 @@ export default function InvokeButton(props: InvokeButton) {
aria-label={t('parameters.invoke')}
type="submit"
icon={}
- isDisabled={!isReady}
+ isDisabled={!isReady || isProcessing}
onClick={handleInvoke}
tooltip={t('parameters.invoke')}
tooltipProps={{ placement: 'top' }}
@@ -95,7 +95,7 @@ export default function InvokeButton(props: InvokeButton) {
Date: Mon, 10 Jul 2023 11:30:35 +1000
Subject: [PATCH 4/4] fix(nodes): remove `board_id` column from `images` table
This is extraneous; the `board_images` table holds image-board relationships.
---
invokeai/app/services/image_record_storage.py | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/invokeai/app/services/image_record_storage.py b/invokeai/app/services/image_record_storage.py
index 5e5996ae76..014006eb7a 100644
--- a/invokeai/app/services/image_record_storage.py
+++ b/invokeai/app/services/image_record_storage.py
@@ -1,22 +1,16 @@
+import sqlite3
+import threading
from abc import ABC, abstractmethod
from datetime import datetime
from typing import Generic, Optional, TypeVar, cast
-import sqlite3
-import threading
from pydantic import BaseModel, Field
from pydantic.generics import GenericModel
+from invokeai.app.models.image import ImageCategory, ResourceOrigin
from invokeai.app.models.metadata import ImageMetadata
-from invokeai.app.models.image import (
- ImageCategory,
- ResourceOrigin,
-)
from invokeai.app.services.models.image_record import (
- ImageRecord,
- ImageRecordChanges,
- deserialize_image_record,
-)
+ ImageRecord, ImageRecordChanges, deserialize_image_record)
T = TypeVar("T", bound=BaseModel)
@@ -162,7 +156,6 @@ class SqliteImageRecordStorage(ImageRecordStorageBase):
node_id TEXT,
metadata TEXT,
is_intermediate BOOLEAN DEFAULT FALSE,
- board_id TEXT,
created_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')),
-- Updated via trigger
updated_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')),