feat(ui): add new gallery/canvas session buttons to queue actions menu

A new "session" just means to reset most settings to default values, excluding model.

There are a few things that need to be reset:
- Parameters state, except for models and things dependent on model selection (like VAE precision)
- Canvas state, except for the `modelBase`, which is dependent on the model selection
- Canvas staging area state
- LoRAs state
- HRF state
- Style presets state

We also select the canvas tab.

For new gallery sessions, we:
- Open the image viewer
- Set the right panel tab to `gallery`

And for new canvas sessions, we:
- Close the image viewer
- Set the right panel tab to `layers`
This commit is contained in:
psychedelicious
2024-10-03 17:15:54 +10:00
committed by Kent Keirsey
parent b793328edd
commit 2d1e745594
12 changed files with 84 additions and 6 deletions

View File

@@ -1,4 +1,7 @@
import { createAction } from '@reduxjs/toolkit';
import { createAction, isAnyOf } from '@reduxjs/toolkit';
// Needed to split this from canvasSlice.ts to avoid circular dependencies
export const canvasReset = createAction('canvas/canvasReset');
export const newGallerySessionRequested = createAction('canvas/newGallerySessionRequested');
export const newCanvasSessionRequested = createAction('canvas/newCanvasSessionRequested');
export const newSessionRequested = isAnyOf(newGallerySessionRequested, newCanvasSessionRequested);

View File

@@ -1,6 +1,7 @@
import type { PayloadAction, Selector } from '@reduxjs/toolkit';
import { createSelector, createSlice } from '@reduxjs/toolkit';
import type { PersistConfig, RootState } from 'app/store/store';
import { newCanvasSessionRequested, newGallerySessionRequested } from 'features/controlLayers/store/actions';
import type { RgbaColor } from 'features/controlLayers/store/types';
type CanvasSettingsState = {
@@ -164,6 +165,14 @@ export const canvasSettingsSlice = createSlice({
state.pressureSensitivity = !state.pressureSensitivity;
},
},
extraReducers(builder) {
builder.addCase(newGallerySessionRequested, (state) => {
state.sendToCanvas = false;
});
builder.addCase(newCanvasSessionRequested, (state) => {
state.sendToCanvas = true;
});
},
});
export const {

View File

@@ -5,7 +5,7 @@ import { moveOneToEnd, moveOneToStart, moveToEnd, moveToStart } from 'common/uti
import { deepClone } from 'common/util/deepClone';
import { roundDownToMultiple, roundToMultiple } from 'common/util/roundDownToMultiple';
import { getPrefixedId } from 'features/controlLayers/konva/util';
import { canvasReset } from 'features/controlLayers/store/actions';
import { canvasReset, newSessionRequested } from 'features/controlLayers/store/actions';
import { modelChanged } from 'features/controlLayers/store/paramsSlice';
import {
selectAllEntities,
@@ -1130,6 +1130,9 @@ export const canvasSlice = createSlice({
syncScaledSize(state);
}
});
builder.addMatcher(newSessionRequested, (state) => {
return resetState(state);
});
},
});

View File

@@ -5,6 +5,8 @@ import { canvasReset } from 'features/controlLayers/store/actions';
import type { StagingAreaImage } from 'features/controlLayers/store/types';
import { selectCanvasQueueCounts } from 'services/api/endpoints/queue';
import { newSessionRequested } from './actions';
type CanvasStagingAreaState = {
stagedImages: StagingAreaImage[];
selectedStagedImageIndex: number;
@@ -43,6 +45,7 @@ export const canvasStagingAreaSlice = createSlice({
},
extraReducers(builder) {
builder.addCase(canvasReset, () => deepClone(initialState));
builder.addMatcher(newSessionRequested, () => deepClone(initialState));
},
});

View File

@@ -1,10 +1,13 @@
import { createSelector, createSlice, type PayloadAction } from '@reduxjs/toolkit';
import type { PersistConfig, RootState } from 'app/store/store';
import { deepClone } from 'common/util/deepClone';
import type { LoRA } from 'features/controlLayers/store/types';
import { zModelIdentifierField } from 'features/nodes/types/common';
import type { LoRAModelConfig } from 'services/api/types';
import { v4 as uuidv4 } from 'uuid';
import { newSessionRequested } from './actions';
type LoRAsState = {
loras: LoRA[];
};
@@ -60,6 +63,12 @@ export const lorasSlice = createSlice({
state.loras = [];
},
},
extraReducers(builder) {
builder.addMatcher(newSessionRequested, () => {
// When a new session is requested, clear all LoRAs
return deepClone(initialState);
});
},
});
export const { loraAdded, loraRecalled, loraDeleted, loraWeightChanged, loraIsEnabledChanged, loraAllDeleted } =

View File

@@ -1,6 +1,7 @@
import type { PayloadAction, Selector } from '@reduxjs/toolkit';
import { createSelector, createSlice } from '@reduxjs/toolkit';
import type { PersistConfig, RootState } from 'app/store/store';
import { deepClone } from 'common/util/deepClone';
import type { RgbaColor } from 'features/controlLayers/store/types';
import { CLIP_SKIP_MAP } from 'features/parameters/types/constants';
import type {
@@ -26,6 +27,8 @@ import type {
} from 'features/parameters/types/parameterSchemas';
import { clamp } from 'lodash-es';
import { newSessionRequested } from './actions';
export type ParamsState = {
maskBlur: number;
maskBlurMethod: ParameterMaskBlurMethod;
@@ -259,6 +262,21 @@ export const paramsSlice = createSlice({
state.canvasCoherenceMinDenoise = action.payload;
},
},
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;
});
},
});
export const {