mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): "stagingArea" -> "session"
This commit is contained in:
parent
0c539ff00b
commit
d4da00e607
@ -4,8 +4,8 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'
|
|||||||
import {
|
import {
|
||||||
layerAdded,
|
layerAdded,
|
||||||
layerImageAdded,
|
layerImageAdded,
|
||||||
stagingAreaCanceledStaging,
|
sessionStagingCanceled,
|
||||||
stagingAreaImageAccepted,
|
sessionStagedImageAccepted,
|
||||||
} from 'features/controlLayers/store/canvasV2Slice';
|
} from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { toast } from 'features/toast/toast';
|
import { toast } from 'features/toast/toast';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
@ -14,7 +14,7 @@ import { assert } from 'tsafe';
|
|||||||
|
|
||||||
export const addStagingListeners = (startAppListening: AppStartListening) => {
|
export const addStagingListeners = (startAppListening: AppStartListening) => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
matcher: isAnyOf(stagingAreaCanceledStaging, stagingAreaImageAccepted),
|
matcher: isAnyOf(sessionStagingCanceled, sessionStagedImageAccepted),
|
||||||
effect: async (_, { dispatch }) => {
|
effect: async (_, { dispatch }) => {
|
||||||
const log = logger('canvas');
|
const log = logger('canvas');
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ export const addStagingListeners = (startAppListening: AppStartListening) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
startAppListening({
|
startAppListening({
|
||||||
actionCreator: stagingAreaImageAccepted,
|
actionCreator: sessionStagedImageAccepted,
|
||||||
effect: async (action, api) => {
|
effect: async (action, api) => {
|
||||||
const { imageDTO } = action.payload;
|
const { imageDTO } = action.payload;
|
||||||
const { layers, selectedEntityIdentifier, bbox } = api.getState().canvasV2;
|
const { layers, selectedEntityIdentifier, bbox } = api.getState().canvasV2;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { enqueueRequested } from 'app/store/actions';
|
import { enqueueRequested } from 'app/store/actions';
|
||||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||||
import { getCanvasManager } from 'features/controlLayers/konva/CanvasManager';
|
import { getCanvasManager } from 'features/controlLayers/konva/CanvasManager';
|
||||||
import { stagingAreaCanceledStaging, stagingAreaStartedStaging } from 'features/controlLayers/store/canvasV2Slice';
|
import { sessionStagingCanceled, sessionStartedStaging } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { prepareLinearUIBatch } from 'features/nodes/util/graph/buildLinearBatchConfig';
|
import { prepareLinearUIBatch } from 'features/nodes/util/graph/buildLinearBatchConfig';
|
||||||
import { buildSD1Graph } from 'features/nodes/util/graph/generation/buildSD1Graph';
|
import { buildSD1Graph } from 'features/nodes/util/graph/generation/buildSD1Graph';
|
||||||
import { buildSDXLGraph } from 'features/nodes/util/graph/generation/buildSDXLGraph';
|
import { buildSDXLGraph } from 'features/nodes/util/graph/generation/buildSDXLGraph';
|
||||||
@ -18,8 +18,8 @@ export const addEnqueueRequestedLinear = (startAppListening: AppStartListening)
|
|||||||
const { prepend } = action.payload;
|
const { prepend } = action.payload;
|
||||||
|
|
||||||
let didStartStaging = false;
|
let didStartStaging = false;
|
||||||
if (!state.canvasV2.stagingArea.isStaging) {
|
if (!state.canvasV2.session.isStaging) {
|
||||||
dispatch(stagingAreaStartedStaging());
|
dispatch(sessionStartedStaging());
|
||||||
didStartStaging = true;
|
didStartStaging = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,8 +48,8 @@ export const addEnqueueRequestedLinear = (startAppListening: AppStartListening)
|
|||||||
req.reset();
|
req.reset();
|
||||||
await req.unwrap();
|
await req.unwrap();
|
||||||
} catch {
|
} catch {
|
||||||
if (didStartStaging && getState().canvasV2.stagingArea.isStaging) {
|
if (didStartStaging && getState().canvasV2.session.isStaging) {
|
||||||
dispatch(stagingAreaCanceledStaging());
|
dispatch(sessionStagingCanceled());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,7 @@ import { logger } from 'app/logging/logger';
|
|||||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||||
import { deepClone } from 'common/util/deepClone';
|
import { deepClone } from 'common/util/deepClone';
|
||||||
import { parseify } from 'common/util/serialize';
|
import { parseify } from 'common/util/serialize';
|
||||||
import { stagingAreaImageAdded } from 'features/controlLayers/store/canvasV2Slice';
|
import { sessionImageStaged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { boardIdSelected, galleryViewChanged, imageSelected, offsetChanged } from 'features/gallery/store/gallerySlice';
|
import { boardIdSelected, galleryViewChanged, imageSelected, offsetChanged } from 'features/gallery/store/gallerySlice';
|
||||||
import { $nodeExecutionStates, upsertExecutionState } from 'features/nodes/hooks/useExecutionState';
|
import { $nodeExecutionStates, upsertExecutionState } from 'features/nodes/hooks/useExecutionState';
|
||||||
import { zNodeStatus } from 'features/nodes/types/invocation';
|
import { zNodeStatus } from 'features/nodes/types/invocation';
|
||||||
@ -42,8 +42,8 @@ export const addInvocationCompleteEventListener = (startAppListening: AppStartLi
|
|||||||
|
|
||||||
// handle tab-specific logic
|
// handle tab-specific logic
|
||||||
if (data.origin === 'canvas') {
|
if (data.origin === 'canvas') {
|
||||||
if (data.invocation_source_id === CANVAS_OUTPUT && canvasV2.stagingArea.isStaging) {
|
if (data.invocation_source_id === CANVAS_OUTPUT && canvasV2.session.isStaging) {
|
||||||
dispatch(stagingAreaImageAdded({ imageDTO }));
|
dispatch(sessionImageStaged({ imageDTO }));
|
||||||
}
|
}
|
||||||
} else if (data.origin === 'workflows') {
|
} else if (data.origin === 'workflows') {
|
||||||
const nes = deepClone($nodeExecutionStates.get()[invocation_source_id]);
|
const nes = deepClone($nodeExecutionStates.get()[invocation_source_id]);
|
||||||
|
@ -3,11 +3,11 @@ import { useStore } from '@nanostores/react';
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import {
|
import {
|
||||||
$shouldShowStagedImage,
|
$shouldShowStagedImage,
|
||||||
stagingAreaCanceledStaging,
|
sessionStagingCanceled,
|
||||||
stagingAreaImageAccepted,
|
sessionStagedImageAccepted,
|
||||||
stagingAreaImageDiscarded,
|
sessionStagedImageDiscarded,
|
||||||
stagingAreaNextImageSelected,
|
sessionNextStagedImageSelected,
|
||||||
stagingAreaPreviousImageSelected,
|
sessionPrevStagedImageSelected,
|
||||||
} from 'features/controlLayers/store/canvasV2Slice';
|
} from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
@ -24,7 +24,7 @@ import {
|
|||||||
} from 'react-icons/pi';
|
} from 'react-icons/pi';
|
||||||
|
|
||||||
export const StagingAreaToolbar = memo(() => {
|
export const StagingAreaToolbar = memo(() => {
|
||||||
const isStaging = useAppSelector((s) => s.canvasV2.stagingArea.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
||||||
|
|
||||||
if (!isStaging) {
|
if (!isStaging) {
|
||||||
return null;
|
return null;
|
||||||
@ -37,30 +37,30 @@ StagingAreaToolbar.displayName = 'StagingAreaToolbar';
|
|||||||
|
|
||||||
export const StagingAreaToolbarContent = memo(() => {
|
export const StagingAreaToolbarContent = memo(() => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const stagingArea = useAppSelector((s) => s.canvasV2.stagingArea);
|
const stagingArea = useAppSelector((s) => s.canvasV2.session);
|
||||||
const shouldShowStagedImage = useStore($shouldShowStagedImage);
|
const shouldShowStagedImage = useStore($shouldShowStagedImage);
|
||||||
const images = useMemo(() => stagingArea.images, [stagingArea]);
|
const images = useMemo(() => stagingArea.stagedImages, [stagingArea]);
|
||||||
const selectedImageDTO = useMemo(() => {
|
const selectedImageDTO = useMemo(() => {
|
||||||
return images[stagingArea.selectedImageIndex] ?? null;
|
return images[stagingArea.selectedStagedImageIndex] ?? null;
|
||||||
}, [images, stagingArea.selectedImageIndex]);
|
}, [images, stagingArea.selectedStagedImageIndex]);
|
||||||
|
|
||||||
// const [changeIsImageIntermediate] = useChangeImageIsIntermediateMutation();
|
// const [changeIsImageIntermediate] = useChangeImageIsIntermediateMutation();
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const onPrev = useCallback(() => {
|
const onPrev = useCallback(() => {
|
||||||
dispatch(stagingAreaPreviousImageSelected());
|
dispatch(sessionPrevStagedImageSelected());
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
const onNext = useCallback(() => {
|
const onNext = useCallback(() => {
|
||||||
dispatch(stagingAreaNextImageSelected());
|
dispatch(sessionNextStagedImageSelected());
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
const onAccept = useCallback(() => {
|
const onAccept = useCallback(() => {
|
||||||
if (!selectedImageDTO) {
|
if (!selectedImageDTO) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dispatch(stagingAreaImageAccepted({ imageDTO: selectedImageDTO }));
|
dispatch(sessionStagedImageAccepted({ imageDTO: selectedImageDTO }));
|
||||||
}, [dispatch, selectedImageDTO]);
|
}, [dispatch, selectedImageDTO]);
|
||||||
|
|
||||||
const onDiscardOne = useCallback(() => {
|
const onDiscardOne = useCallback(() => {
|
||||||
@ -68,14 +68,14 @@ export const StagingAreaToolbarContent = memo(() => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (images.length === 1) {
|
if (images.length === 1) {
|
||||||
dispatch(stagingAreaCanceledStaging());
|
dispatch(sessionStagingCanceled());
|
||||||
} else {
|
} else {
|
||||||
dispatch(stagingAreaImageDiscarded({ imageDTO: selectedImageDTO }));
|
dispatch(sessionStagedImageDiscarded({ imageDTO: selectedImageDTO }));
|
||||||
}
|
}
|
||||||
}, [dispatch, selectedImageDTO, images.length]);
|
}, [dispatch, selectedImageDTO, images.length]);
|
||||||
|
|
||||||
const onDiscardAll = useCallback(() => {
|
const onDiscardAll = useCallback(() => {
|
||||||
dispatch(stagingAreaCanceledStaging());
|
dispatch(sessionStagingCanceled());
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
const onToggleShouldShowStagedImage = useCallback(() => {
|
const onToggleShouldShowStagedImage = useCallback(() => {
|
||||||
@ -109,11 +109,11 @@ export const StagingAreaToolbarContent = memo(() => {
|
|||||||
|
|
||||||
const counterText = useMemo(() => {
|
const counterText = useMemo(() => {
|
||||||
if (images.length > 0) {
|
if (images.length > 0) {
|
||||||
return `${(stagingArea.selectedImageIndex ?? 0) + 1} of ${images.length}`;
|
return `${(stagingArea.selectedStagedImageIndex ?? 0) + 1} of ${images.length}`;
|
||||||
} else {
|
} else {
|
||||||
return `0 of 0`;
|
return `0 of 0`;
|
||||||
}
|
}
|
||||||
}, [images.length, stagingArea.selectedImageIndex]);
|
}, [images.length, stagingArea.selectedStagedImageIndex]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -43,7 +43,7 @@ export const ToolChooser: React.FC = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const selectedEntityIdentifier = useAppSelector(selectSelectedEntityIdentifier);
|
const selectedEntityIdentifier = useAppSelector(selectSelectedEntityIdentifier);
|
||||||
const isStaging = useAppSelector((s) => s.canvasV2.stagingArea.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
||||||
const isDrawingToolDisabled = useMemo(
|
const isDrawingToolDisabled = useMemo(
|
||||||
() => !getIsDrawingToolEnabled(selectedEntityIdentifier),
|
() => !getIsDrawingToolEnabled(selectedEntityIdentifier),
|
||||||
[selectedEntityIdentifier]
|
[selectedEntityIdentifier]
|
||||||
|
@ -281,7 +281,7 @@ export class CanvasManager {
|
|||||||
// debouncedUpdateBboxes(stage, canvasV2.layers, canvasV2.controlAdapters, canvasV2.regions, onBboxChanged);
|
// debouncedUpdateBboxes(stage, canvasV2.layers, canvasV2.controlAdapters, canvasV2.regions, onBboxChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isFirstRender || state.stagingArea !== this.prevState.stagingArea) {
|
if (this.isFirstRender || state.session !== this.prevState.session) {
|
||||||
log.debug('Rendering staging area');
|
log.debug('Rendering staging area');
|
||||||
this.preview.stagingArea.render();
|
this.preview.stagingArea.render();
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ export class CanvasStagingArea {
|
|||||||
const shouldShowStagedImage = this.manager.stateApi.getShouldShowStagedImage();
|
const shouldShowStagedImage = this.manager.stateApi.getShouldShowStagedImage();
|
||||||
const lastProgressEvent = this.manager.stateApi.getLastProgressEvent();
|
const lastProgressEvent = this.manager.stateApi.getLastProgressEvent();
|
||||||
|
|
||||||
this.imageDTO = stagingArea.images[stagingArea.selectedImageIndex] ?? null;
|
this.imageDTO = stagingArea.stagedImages[stagingArea.selectedStagedImageIndex] ?? null;
|
||||||
|
|
||||||
if (this.imageDTO) {
|
if (this.imageDTO) {
|
||||||
if (this.image) {
|
if (this.image) {
|
||||||
|
@ -232,7 +232,7 @@ export class CanvasStateApi {
|
|||||||
return this.getState().settings.maskOpacity;
|
return this.getState().settings.maskOpacity;
|
||||||
};
|
};
|
||||||
getStagingAreaState = () => {
|
getStagingAreaState = () => {
|
||||||
return this.getState().stagingArea;
|
return this.getState().session;
|
||||||
};
|
};
|
||||||
getIsSelected = (id: string) => {
|
getIsSelected = (id: string) => {
|
||||||
return this.getSelectedEntity()?.id === id;
|
return this.getSelectedEntity()?.id === id;
|
||||||
|
@ -13,8 +13,8 @@ import { layersReducers } from 'features/controlLayers/store/layersReducers';
|
|||||||
import { lorasReducers } from 'features/controlLayers/store/lorasReducers';
|
import { lorasReducers } from 'features/controlLayers/store/lorasReducers';
|
||||||
import { paramsReducers } from 'features/controlLayers/store/paramsReducers';
|
import { paramsReducers } from 'features/controlLayers/store/paramsReducers';
|
||||||
import { regionsReducers } from 'features/controlLayers/store/regionsReducers';
|
import { regionsReducers } from 'features/controlLayers/store/regionsReducers';
|
||||||
|
import { sessionReducers } from 'features/controlLayers/store/sessionReducers';
|
||||||
import { settingsReducers } from 'features/controlLayers/store/settingsReducers';
|
import { settingsReducers } from 'features/controlLayers/store/settingsReducers';
|
||||||
import { stagingAreaReducers } from 'features/controlLayers/store/stagingAreaReducers';
|
|
||||||
import { toolReducers } from 'features/controlLayers/store/toolReducers';
|
import { toolReducers } from 'features/controlLayers/store/toolReducers';
|
||||||
import { initialAspectRatioState } from 'features/parameters/components/ImageSize/constants';
|
import { initialAspectRatioState } from 'features/parameters/components/ImageSize/constants';
|
||||||
import type { AspectRatioState } from 'features/parameters/components/ImageSize/types';
|
import type { AspectRatioState } from 'features/parameters/components/ImageSize/types';
|
||||||
@ -122,10 +122,11 @@ const initialState: CanvasV2State = {
|
|||||||
refinerNegativeAestheticScore: 2.5,
|
refinerNegativeAestheticScore: 2.5,
|
||||||
refinerStart: 0.8,
|
refinerStart: 0.8,
|
||||||
},
|
},
|
||||||
stagingArea: {
|
session: {
|
||||||
|
isActive: false,
|
||||||
isStaging: false,
|
isStaging: false,
|
||||||
images: [],
|
stagedImages: [],
|
||||||
selectedImageIndex: 0,
|
selectedStagedImageIndex: 0,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,7 +145,7 @@ export const canvasV2Slice = createSlice({
|
|||||||
...toolReducers,
|
...toolReducers,
|
||||||
...bboxReducers,
|
...bboxReducers,
|
||||||
...inpaintMaskReducers,
|
...inpaintMaskReducers,
|
||||||
...stagingAreaReducers,
|
...sessionReducers,
|
||||||
widthChanged: (state, action: PayloadAction<{ width: number; updateAspectRatio?: boolean; clamp?: boolean }>) => {
|
widthChanged: (state, action: PayloadAction<{ width: number; updateAspectRatio?: boolean; clamp?: boolean }>) => {
|
||||||
const { width, updateAspectRatio, clamp } = action.payload;
|
const { width, updateAspectRatio, clamp } = action.payload;
|
||||||
state.document.width = clamp ? Math.max(roundDownToMultiple(width, 8), 64) : width;
|
state.document.width = clamp ? Math.max(roundDownToMultiple(width, 8), 64) : width;
|
||||||
@ -184,7 +185,7 @@ export const canvasV2Slice = createSlice({
|
|||||||
state.layers = deepClone(initialState.layers);
|
state.layers = deepClone(initialState.layers);
|
||||||
state.regions = deepClone(initialState.regions);
|
state.regions = deepClone(initialState.regions);
|
||||||
state.selectedEntityIdentifier = deepClone(initialState.selectedEntityIdentifier);
|
state.selectedEntityIdentifier = deepClone(initialState.selectedEntityIdentifier);
|
||||||
state.stagingArea = deepClone(initialState.stagingArea);
|
state.session = deepClone(initialState.session);
|
||||||
state.tool = deepClone(initialState.tool);
|
state.tool = deepClone(initialState.tool);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -350,13 +351,14 @@ export const {
|
|||||||
imEraserLineAdded,
|
imEraserLineAdded,
|
||||||
imRectShapeAdded,
|
imRectShapeAdded,
|
||||||
// Staging
|
// Staging
|
||||||
stagingAreaStartedStaging,
|
sessionStarted,
|
||||||
stagingAreaImageAdded,
|
sessionStartedStaging,
|
||||||
stagingAreaImageDiscarded,
|
sessionImageStaged,
|
||||||
stagingAreaImageAccepted,
|
sessionStagedImageDiscarded,
|
||||||
stagingAreaCanceledStaging,
|
sessionStagedImageAccepted,
|
||||||
stagingAreaNextImageSelected,
|
sessionStagingCanceled,
|
||||||
stagingAreaPreviousImageSelected,
|
sessionNextStagedImageSelected,
|
||||||
|
sessionPrevStagedImageSelected,
|
||||||
} = canvasV2Slice.actions;
|
} = canvasV2Slice.actions;
|
||||||
|
|
||||||
export const selectCanvasV2Slice = (state: RootState) => state.canvasV2;
|
export const selectCanvasV2Slice = (state: RootState) => state.canvasV2;
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
|
||||||
|
import type { CanvasV2State } from 'features/controlLayers/store/types';
|
||||||
|
import type { ImageDTO } from 'services/api/types';
|
||||||
|
|
||||||
|
export const sessionReducers = {
|
||||||
|
sessionStarted: (state) => {
|
||||||
|
state.session.isActive = true;
|
||||||
|
},
|
||||||
|
sessionStartedStaging: (state) => {
|
||||||
|
state.session.isStaging = true;
|
||||||
|
state.session.selectedStagedImageIndex = 0;
|
||||||
|
// When we start staging, the user should not be interacting with the stage except to move it around. Set the tool
|
||||||
|
// to view.
|
||||||
|
state.tool.selectedBuffer = state.tool.selected;
|
||||||
|
state.tool.selected = 'view';
|
||||||
|
},
|
||||||
|
sessionImageStaged: (state, action: PayloadAction<{ imageDTO: ImageDTO }>) => {
|
||||||
|
const { imageDTO } = action.payload;
|
||||||
|
state.session.stagedImages.push(imageDTO);
|
||||||
|
state.session.selectedStagedImageIndex = state.session.stagedImages.length - 1;
|
||||||
|
},
|
||||||
|
sessionNextStagedImageSelected: (state) => {
|
||||||
|
state.session.selectedStagedImageIndex =
|
||||||
|
(state.session.selectedStagedImageIndex + 1) % state.session.stagedImages.length;
|
||||||
|
},
|
||||||
|
sessionPrevStagedImageSelected: (state) => {
|
||||||
|
state.session.selectedStagedImageIndex =
|
||||||
|
(state.session.selectedStagedImageIndex - 1 + state.session.stagedImages.length) %
|
||||||
|
state.session.stagedImages.length;
|
||||||
|
},
|
||||||
|
sessionStagedImageDiscarded: (state, action: PayloadAction<{ imageDTO: ImageDTO }>) => {
|
||||||
|
const { imageDTO } = action.payload;
|
||||||
|
state.session.stagedImages = state.session.stagedImages.filter((image) => image.image_name !== imageDTO.image_name);
|
||||||
|
state.session.selectedStagedImageIndex = Math.min(
|
||||||
|
state.session.selectedStagedImageIndex,
|
||||||
|
state.session.stagedImages.length - 1
|
||||||
|
);
|
||||||
|
if (state.session.stagedImages.length === 0) {
|
||||||
|
state.session.isStaging = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sessionStagedImageAccepted: (state, _: PayloadAction<{ imageDTO: ImageDTO }>) => {
|
||||||
|
// When we finish staging, reset the tool back to the previous selection.
|
||||||
|
state.session.isStaging = false;
|
||||||
|
state.session.stagedImages = [];
|
||||||
|
state.session.selectedStagedImageIndex = 0;
|
||||||
|
if (state.tool.selectedBuffer) {
|
||||||
|
state.tool.selected = state.tool.selectedBuffer;
|
||||||
|
state.tool.selectedBuffer = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sessionStagingCanceled: (state) => {
|
||||||
|
state.session.isStaging = false;
|
||||||
|
state.session.stagedImages = [];
|
||||||
|
state.session.selectedStagedImageIndex = 0;
|
||||||
|
// When we finish staging, reset the tool back to the previous selection.
|
||||||
|
if (state.tool.selectedBuffer) {
|
||||||
|
state.tool.selected = state.tool.selectedBuffer;
|
||||||
|
state.tool.selectedBuffer = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} satisfies SliceCaseReducers<CanvasV2State>;
|
@ -1,57 +0,0 @@
|
|||||||
import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
|
|
||||||
import type { CanvasV2State } from 'features/controlLayers/store/types';
|
|
||||||
import type { ImageDTO } from 'services/api/types';
|
|
||||||
|
|
||||||
export const stagingAreaReducers = {
|
|
||||||
stagingAreaStartedStaging: (state) => {
|
|
||||||
state.stagingArea.isStaging = true;
|
|
||||||
state.stagingArea.selectedImageIndex = 0;
|
|
||||||
// When we start staging, the user should not be interacting with the stage except to move it around. Set the tool
|
|
||||||
// to view.
|
|
||||||
state.tool.selectedBuffer = state.tool.selected;
|
|
||||||
state.tool.selected = 'view';
|
|
||||||
},
|
|
||||||
stagingAreaImageAdded: (state, action: PayloadAction<{ imageDTO: ImageDTO }>) => {
|
|
||||||
const { imageDTO } = action.payload;
|
|
||||||
state.stagingArea.images.push(imageDTO);
|
|
||||||
state.stagingArea.selectedImageIndex = state.stagingArea.images.length - 1;
|
|
||||||
},
|
|
||||||
stagingAreaNextImageSelected: (state) => {
|
|
||||||
state.stagingArea.selectedImageIndex = (state.stagingArea.selectedImageIndex + 1) % state.stagingArea.images.length;
|
|
||||||
},
|
|
||||||
stagingAreaPreviousImageSelected: (state) => {
|
|
||||||
state.stagingArea.selectedImageIndex =
|
|
||||||
(state.stagingArea.selectedImageIndex - 1 + state.stagingArea.images.length) % state.stagingArea.images.length;
|
|
||||||
},
|
|
||||||
stagingAreaImageDiscarded: (state, action: PayloadAction<{ imageDTO: ImageDTO }>) => {
|
|
||||||
const { imageDTO } = action.payload;
|
|
||||||
state.stagingArea.images = state.stagingArea.images.filter((image) => image.image_name !== imageDTO.image_name);
|
|
||||||
state.stagingArea.selectedImageIndex = Math.min(
|
|
||||||
state.stagingArea.selectedImageIndex,
|
|
||||||
state.stagingArea.images.length - 1
|
|
||||||
);
|
|
||||||
if (state.stagingArea.images.length === 0) {
|
|
||||||
state.stagingArea.isStaging = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
stagingAreaImageAccepted: (state, _: PayloadAction<{ imageDTO: ImageDTO }>) => {
|
|
||||||
// When we finish staging, reset the tool back to the previous selection.
|
|
||||||
state.stagingArea.isStaging = false;
|
|
||||||
state.stagingArea.images = [];
|
|
||||||
state.stagingArea.selectedImageIndex = 0;
|
|
||||||
if (state.tool.selectedBuffer) {
|
|
||||||
state.tool.selected = state.tool.selectedBuffer;
|
|
||||||
state.tool.selectedBuffer = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
stagingAreaCanceledStaging: (state) => {
|
|
||||||
state.stagingArea.isStaging = false;
|
|
||||||
state.stagingArea.images = [];
|
|
||||||
state.stagingArea.selectedImageIndex = 0;
|
|
||||||
// When we finish staging, reset the tool back to the previous selection.
|
|
||||||
if (state.tool.selectedBuffer) {
|
|
||||||
state.tool.selected = state.tool.selectedBuffer;
|
|
||||||
state.tool.selectedBuffer = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
} satisfies SliceCaseReducers<CanvasV2State>;
|
|
@ -895,10 +895,11 @@ export type CanvasV2State = {
|
|||||||
refinerNegativeAestheticScore: number;
|
refinerNegativeAestheticScore: number;
|
||||||
refinerStart: number;
|
refinerStart: number;
|
||||||
};
|
};
|
||||||
stagingArea: {
|
session: {
|
||||||
|
isActive: boolean;
|
||||||
isStaging: boolean;
|
isStaging: boolean;
|
||||||
images: ImageDTO[];
|
stagedImages: ImageDTO[];
|
||||||
selectedImageIndex: number;
|
selectedStagedImageIndex: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import { useListImagesQuery } from 'services/api/endpoints/images';
|
|||||||
* Registers gallery hotkeys. This hook is a singleton.
|
* Registers gallery hotkeys. This hook is a singleton.
|
||||||
*/
|
*/
|
||||||
export const useGalleryHotkeys = () => {
|
export const useGalleryHotkeys = () => {
|
||||||
const isStaging = useAppSelector((s) => s.canvasV2.stagingArea.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
||||||
|
|
||||||
const { goNext, goPrev, isNextEnabled, isPrevEnabled } = useGalleryPagination();
|
const { goNext, goPrev, isNextEnabled, isPrevEnabled } = useGalleryPagination();
|
||||||
const queryArgs = useAppSelector(selectListImagesQueryArgs);
|
const queryArgs = useAppSelector(selectListImagesQueryArgs);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user