From 54d362afe7fefca27a769708eb03b8e340968400 Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Tue, 19 Nov 2024 15:43:56 -0600
Subject: [PATCH 1/2] feat(ui): change reset canvas button to new session menu
---
invokeai/frontend/web/public/locales/en.json | 2 +-
.../components/Toolbar/CanvasToolbar.tsx | 4 +--
.../CanvasToolbarNewSessionMenuButton.tsx | 35 +++++++++++++++++++
.../CanvasToolbarResetCanvasButton.tsx | 30 ----------------
4 files changed, 38 insertions(+), 33 deletions(-)
create mode 100644 invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarNewSessionMenuButton.tsx
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarResetCanvasButton.tsx
diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json
index 4ac3e2f199d..c885af9afe5 100644
--- a/invokeai/frontend/web/public/locales/en.json
+++ b/invokeai/frontend/web/public/locales/en.json
@@ -1676,7 +1676,7 @@
"mergingLayers": "Merging layers",
"clearHistory": "Clear History",
"bboxOverlay": "Show Bbox Overlay",
- "resetCanvas": "Reset Canvas",
+ "newSession": "New Session",
"clearCaches": "Clear Caches",
"recalculateRects": "Recalculate Rects",
"clipToBbox": "Clip Strokes to Bbox",
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbar.tsx b/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbar.tsx
index e8dcf7bb263..c2c4b5451f8 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbar.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbar.tsx
@@ -4,8 +4,8 @@ import { CanvasSettingsPopover } from 'features/controlLayers/components/Setting
import { ToolColorPicker } from 'features/controlLayers/components/Tool/ToolFillColorPicker';
import { ToolSettings } from 'features/controlLayers/components/Tool/ToolSettings';
import { CanvasToolbarFitBboxToLayersButton } from 'features/controlLayers/components/Toolbar/CanvasToolbarFitBboxToLayersButton';
+import { CanvasToolbarNewSessionMenuButton } from 'features/controlLayers/components/Toolbar/CanvasToolbarNewSessionMenuButton';
import { CanvasToolbarRedoButton } from 'features/controlLayers/components/Toolbar/CanvasToolbarRedoButton';
-import { CanvasToolbarResetCanvasButton } from 'features/controlLayers/components/Toolbar/CanvasToolbarResetCanvasButton';
import { CanvasToolbarResetViewButton } from 'features/controlLayers/components/Toolbar/CanvasToolbarResetViewButton';
import { CanvasToolbarSaveToGalleryButton } from 'features/controlLayers/components/Toolbar/CanvasToolbarSaveToGalleryButton';
import { CanvasToolbarScale } from 'features/controlLayers/components/Toolbar/CanvasToolbarScale';
@@ -43,7 +43,7 @@ export const CanvasToolbar = memo(() => {
-
+
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarNewSessionMenuButton.tsx b/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarNewSessionMenuButton.tsx
new file mode 100644
index 00000000000..efc87d3ff01
--- /dev/null
+++ b/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarNewSessionMenuButton.tsx
@@ -0,0 +1,35 @@
+import { IconButton, Menu, MenuButton, MenuItem, MenuList } from '@invoke-ai/ui-library';
+import {
+ useNewCanvasSession,
+ useNewGallerySession,
+} from 'features/controlLayers/components/NewSessionConfirmationAlertDialog';
+import { memo } from 'react';
+import { useTranslation } from 'react-i18next';
+import { PiFilePlusBold, PiImageBold, PiPaintBrushBold } from 'react-icons/pi';
+
+export const CanvasToolbarNewSessionMenuButton = memo(() => {
+ const { t } = useTranslation();
+ const { newGallerySessionWithDialog } = useNewGallerySession();
+ const { newCanvasSessionWithDialog } = useNewCanvasSession();
+ return (
+
+ );
+});
+
+CanvasToolbarNewSessionMenuButton.displayName = 'CanvasToolbarNewSessionMenuButton';
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarResetCanvasButton.tsx b/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarResetCanvasButton.tsx
deleted file mode 100644
index 08e9326c69a..00000000000
--- a/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarResetCanvasButton.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { IconButton } from '@invoke-ai/ui-library';
-import { useAppDispatch } from 'app/store/storeHooks';
-import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
-import { canvasReset } from 'features/controlLayers/store/actions';
-import { memo, useCallback } from 'react';
-import { useTranslation } from 'react-i18next';
-import { PiEmptyBold } from 'react-icons/pi';
-
-export const CanvasToolbarResetCanvasButton = memo(() => {
- const { t } = useTranslation();
- const dispatch = useAppDispatch();
- const canvasManager = useCanvasManager();
- const onClick = useCallback(() => {
- dispatch(canvasReset());
- canvasManager.stage.fitLayersToStage();
- }, [canvasManager.stage, dispatch]);
- return (
- }
- variant="link"
- alignSelf="stretch"
- />
- );
-});
-
-CanvasToolbarResetCanvasButton.displayName = 'CanvasToolbarResetCanvasButton';
From f1e7ee92a31c76c46dcac25d8fdc5723c1eccf93 Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Tue, 19 Nov 2024 15:49:09 -0600
Subject: [PATCH 2/2] feat(ui): add actions for reset canvas layers /
generation settings to session menus
---
invokeai/frontend/web/public/locales/en.json | 2 +
.../common/components/SessionMenuItems.tsx | 42 +++++++++++++++++++
.../CanvasToolbarNewSessionMenuButton.tsx | 18 ++------
.../controlLayers/store/paramsSlice.ts | 30 +++++++------
.../components/QueueActionsMenuButton.tsx | 25 ++---------
5 files changed, 68 insertions(+), 49 deletions(-)
create mode 100644 invokeai/frontend/web/src/common/components/SessionMenuItems.tsx
diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json
index c885af9afe5..8b679897138 100644
--- a/invokeai/frontend/web/public/locales/en.json
+++ b/invokeai/frontend/web/public/locales/en.json
@@ -1787,6 +1787,8 @@
"newGallerySessionDesc": "This will clear the canvas and all settings except for your model selection. Generations will be sent to the gallery.",
"newCanvasSession": "New Canvas Session",
"newCanvasSessionDesc": "This will clear the canvas and all settings except for your model selection. Generations will be staged on the canvas.",
+ "resetCanvasLayers": "Reset Canvas Layers",
+ "resetGenerationSettings": "Reset Generation Settings",
"replaceCurrent": "Replace Current",
"controlLayerEmptyState": "Upload an image, drag an image from the gallery onto this layer, or draw on the canvas to get started.",
"controlMode": {
diff --git a/invokeai/frontend/web/src/common/components/SessionMenuItems.tsx b/invokeai/frontend/web/src/common/components/SessionMenuItems.tsx
new file mode 100644
index 00000000000..0f931b17c44
--- /dev/null
+++ b/invokeai/frontend/web/src/common/components/SessionMenuItems.tsx
@@ -0,0 +1,42 @@
+import { MenuItem } from '@invoke-ai/ui-library';
+import { useAppDispatch } from 'app/store/storeHooks';
+import {
+ useNewCanvasSession,
+ useNewGallerySession,
+} from 'features/controlLayers/components/NewSessionConfirmationAlertDialog';
+import { canvasReset } from 'features/controlLayers/store/actions';
+import { paramsReset } from 'features/controlLayers/store/paramsSlice';
+import { memo, useCallback } from 'react';
+import { useTranslation } from 'react-i18next';
+import { PiArrowsCounterClockwiseBold, PiFilePlusBold } from 'react-icons/pi';
+
+export const SessionMenuItems = memo(() => {
+ const { t } = useTranslation();
+ const dispatch = useAppDispatch();
+ const { newGallerySessionWithDialog } = useNewGallerySession();
+ const { newCanvasSessionWithDialog } = useNewCanvasSession();
+ const resetCanvasLayers = useCallback(() => {
+ dispatch(canvasReset());
+ }, [dispatch]);
+ const resetGenerationSettings = useCallback(() => {
+ dispatch(paramsReset());
+ }, [dispatch]);
+ return (
+ <>
+ } onClick={newGallerySessionWithDialog}>
+ {t('controlLayers.newGallerySession')}
+
+ } onClick={newCanvasSessionWithDialog}>
+ {t('controlLayers.newCanvasSession')}
+
+ } onClick={resetCanvasLayers}>
+ {t('controlLayers.resetCanvasLayers')}
+
+ } onClick={resetGenerationSettings}>
+ {t('controlLayers.resetGenerationSettings')}
+
+ >
+ );
+});
+
+SessionMenuItems.displayName = 'SessionMenuItems';
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarNewSessionMenuButton.tsx b/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarNewSessionMenuButton.tsx
index efc87d3ff01..a55c768f9fe 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarNewSessionMenuButton.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbarNewSessionMenuButton.tsx
@@ -1,16 +1,11 @@
-import { IconButton, Menu, MenuButton, MenuItem, MenuList } from '@invoke-ai/ui-library';
-import {
- useNewCanvasSession,
- useNewGallerySession,
-} from 'features/controlLayers/components/NewSessionConfirmationAlertDialog';
+import { IconButton, Menu, MenuButton, MenuList } from '@invoke-ai/ui-library';
+import { SessionMenuItems } from 'common/components/SessionMenuItems';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
-import { PiFilePlusBold, PiImageBold, PiPaintBrushBold } from 'react-icons/pi';
+import { PiFilePlusBold } from 'react-icons/pi';
export const CanvasToolbarNewSessionMenuButton = memo(() => {
const { t } = useTranslation();
- const { newGallerySessionWithDialog } = useNewGallerySession();
- const { newCanvasSessionWithDialog } = useNewCanvasSession();
return (
);
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.ts
index f70dc697d3a..582419a247e 100644
--- a/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.ts
@@ -273,24 +273,27 @@ export const paramsSlice = createSlice({
setCanvasCoherenceMinDenoise: (state, action: PayloadAction) => {
state.canvasCoherenceMinDenoise = action.payload;
},
+ paramsReset: (state) => resetState(state),
},
extraReducers(builder) {
- builder.addMatcher(newSessionRequested, (state) => {
- // When a new session is requested, we need to keep the current model selections, plus dependent state
- // like VAE precision. Everything else gets reset to default.
- const newState = deepClone(initialState);
- newState.model = state.model;
- newState.vae = state.vae;
- newState.fluxVAE = state.fluxVAE;
- newState.vaePrecision = state.vaePrecision;
- newState.t5EncoderModel = state.t5EncoderModel;
- newState.clipEmbedModel = state.clipEmbedModel;
- newState.refinerModel = state.refinerModel;
- return newState;
- });
+ builder.addMatcher(newSessionRequested, (state) => resetState(state));
},
});
+const resetState = (state: ParamsState): ParamsState => {
+ // When a new session is requested, we need to keep the current model selections, plus dependent state
+ // like VAE precision. Everything else gets reset to default.
+ const newState = deepClone(initialState);
+ newState.model = state.model;
+ newState.vae = state.vae;
+ newState.fluxVAE = state.fluxVAE;
+ newState.vaePrecision = state.vaePrecision;
+ newState.t5EncoderModel = state.t5EncoderModel;
+ newState.clipEmbedModel = state.clipEmbedModel;
+ newState.refinerModel = state.refinerModel;
+ return newState;
+};
+
export const {
setInfillMethod,
setInfillTileSize,
@@ -334,6 +337,7 @@ export const {
setRefinerNegativeAestheticScore,
setRefinerStart,
modelChanged,
+ paramsReset,
} = paramsSlice.actions;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
diff --git a/invokeai/frontend/web/src/features/queue/components/QueueActionsMenuButton.tsx b/invokeai/frontend/web/src/features/queue/components/QueueActionsMenuButton.tsx
index 1ae76eec4b7..e4ed61b5653 100644
--- a/invokeai/frontend/web/src/features/queue/components/QueueActionsMenuButton.tsx
+++ b/invokeai/frontend/web/src/features/queue/components/QueueActionsMenuButton.tsx
@@ -1,9 +1,6 @@
import { IconButton, Menu, MenuButton, MenuGroup, MenuItem, MenuList } from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks';
-import {
- useNewCanvasSession,
- useNewGallerySession,
-} from 'features/controlLayers/components/NewSessionConfirmationAlertDialog';
+import { SessionMenuItems } from 'common/components/SessionMenuItems';
import { useClearQueue } from 'features/queue/components/ClearQueueConfirmationAlertDialog';
import { QueueCountBadge } from 'features/queue/components/QueueCountBadge';
import { usePauseProcessor } from 'features/queue/hooks/usePauseProcessor';
@@ -12,16 +9,7 @@ import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { setActiveTab } from 'features/ui/store/uiSlice';
import { memo, useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
-import {
- PiImageBold,
- PiListBold,
- PiPaintBrushBold,
- PiPauseFill,
- PiPlayFill,
- PiQueueBold,
- PiTrashSimpleBold,
- PiXBold,
-} from 'react-icons/pi';
+import { PiListBold, PiPauseFill, PiPlayFill, PiQueueBold, PiTrashSimpleBold, PiXBold } from 'react-icons/pi';
export const QueueActionsMenuButton = memo(() => {
const ref = useRef(null);
@@ -29,8 +17,6 @@ export const QueueActionsMenuButton = memo(() => {
const { t } = useTranslation();
const isPauseEnabled = useFeatureStatus('pauseQueue');
const isResumeEnabled = useFeatureStatus('resumeQueue');
- const { newGallerySessionWithDialog } = useNewGallerySession();
- const { newCanvasSessionWithDialog } = useNewCanvasSession();
const clearQueue = useClearQueue();
const {
resumeProcessor,
@@ -52,12 +38,7 @@ export const QueueActionsMenuButton = memo(() => {
} />
- } onClick={newGallerySessionWithDialog}>
- {t('controlLayers.newGallerySession')}
-
- } onClick={newCanvasSessionWithDialog}>
- {t('controlLayers.newCanvasSession')}
-
+