mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
fix(ui): delete hotkey operating on image and layer at same time
This commit is contained in:
committed by
Kent Keirsey
parent
384abab8d9
commit
4dc194510c
@@ -7,12 +7,13 @@ import { CanvasLayersPanelContent } from 'features/controlLayers/components/Canv
|
||||
import { selectEntityCountActive } from 'features/controlLayers/store/selectors';
|
||||
import GalleryPanelContent from 'features/gallery/components/GalleryPanelContent';
|
||||
import { useImageViewer } from 'features/gallery/components/ImageViewer/useImageViewer';
|
||||
import { atom } from 'nanostores';
|
||||
import { atom, computed } from 'nanostores';
|
||||
import { memo, useCallback, useMemo, useRef } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const $tabIndex = atom(0);
|
||||
export const $canvasRightPanelTab = computed($tabIndex, (index) => (index === 0 ? 'layers' : 'gallery'));
|
||||
export const setRightPanelTabToLayers = () => $tabIndex.set(0);
|
||||
export const setRightPanelTabToGallery = () => $tabIndex.set(1);
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
|
||||
import { $canvasRightPanelTab } from 'features/controlLayers/components/CanvasRightPanel';
|
||||
import { useCanvasIsBusy } from 'features/controlLayers/hooks/useCanvasIsBusy';
|
||||
import { entityDeleted } from 'features/controlLayers/store/canvasSlice';
|
||||
import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice';
|
||||
import { selectSelectedEntityIdentifier } from 'features/controlLayers/store/selectors';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
|
||||
@@ -11,8 +13,9 @@ export function useCanvasDeleteLayerHotkey() {
|
||||
useAssertSingleton(useCanvasDeleteLayerHotkey.name);
|
||||
const dispatch = useAppDispatch();
|
||||
const selectedEntityIdentifier = useAppSelector(selectSelectedEntityIdentifier);
|
||||
const isStaging = useAppSelector(selectIsStaging);
|
||||
const isBusy = useCanvasIsBusy();
|
||||
const canvasRightPanelTab = useStore($canvasRightPanelTab);
|
||||
const appTab = useAppSelector(selectActiveTab);
|
||||
|
||||
const deleteSelectedLayer = useCallback(() => {
|
||||
if (selectedEntityIdentifier === null) {
|
||||
@@ -22,13 +25,12 @@ export function useCanvasDeleteLayerHotkey() {
|
||||
}, [dispatch, selectedEntityIdentifier]);
|
||||
|
||||
const isDeleteEnabled = useMemo(
|
||||
() => selectedEntityIdentifier !== null && !isStaging,
|
||||
[selectedEntityIdentifier, isStaging]
|
||||
() => selectedEntityIdentifier !== null && !isBusy && canvasRightPanelTab === 'layers' && appTab === 'canvas',
|
||||
[selectedEntityIdentifier, isBusy, canvasRightPanelTab, appTab]
|
||||
);
|
||||
|
||||
useHotkeys(['delete', 'backspace'], deleteSelectedLayer, { enabled: isDeleteEnabled && !isBusy }, [
|
||||
useHotkeys(['delete', 'backspace'], deleteSelectedLayer, { enabled: isDeleteEnabled }, [
|
||||
isDeleteEnabled,
|
||||
isBusy,
|
||||
deleteSelectedLayer,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ const CurrentImageButtons = () => {
|
||||
const isConnected = useStore($isConnected);
|
||||
const lastSelectedImage = useAppSelector(selectLastSelectedImage);
|
||||
const progressImage = useStore($progressImage);
|
||||
const selection = useAppSelector((s) => s.gallery.selection);
|
||||
const shouldDisableToolbarButtons = useMemo(() => {
|
||||
return Boolean(progressImage) || !lastSelectedImage;
|
||||
}, [lastSelectedImage, progressImage]);
|
||||
@@ -73,8 +72,8 @@ const CurrentImageButtons = () => {
|
||||
if (!imageDTO) {
|
||||
return;
|
||||
}
|
||||
dispatch(imagesToDeleteSelected(selection));
|
||||
}, [dispatch, imageDTO, selection]);
|
||||
dispatch(imagesToDeleteSelected([imageDTO]));
|
||||
}, [dispatch, imageDTO]);
|
||||
|
||||
useHotkeys('w', handleLoadWorkflow, { enabled: isImageViewerActive }, [lastSelectedImage, isImageViewerActive]);
|
||||
useHotkeys('a', recallAll, { enabled: isImageViewerActive }, [recallAll, isImageViewerActive]);
|
||||
@@ -89,8 +88,6 @@ const CurrentImageButtons = () => {
|
||||
[isUpscalingEnabled, imageDTO, shouldDisableToolbarButtons, isConnected, isImageViewerActive]
|
||||
);
|
||||
|
||||
useHotkeys(['delete', 'backspace'], handleDelete, { enabled: isImageViewerActive }, [imageDTO, isImageViewerActive]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ButtonGroup isDisabled={shouldDisableToolbarButtons}>
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { $activeScopes } from 'common/hooks/interactionScopes';
|
||||
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
|
||||
import { $canvasRightPanelTab } from 'features/controlLayers/components/CanvasRightPanel';
|
||||
import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice';
|
||||
import { useGalleryNavigation } from 'features/gallery/hooks/useGalleryNavigation';
|
||||
import { useGalleryPagination } from 'features/gallery/hooks/useGalleryPagination';
|
||||
import { selectListImagesQueryArgs } from 'features/gallery/store/gallerySelectors';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { $isRightPanelOpen } from 'features/ui/store/uiSlice';
|
||||
import { computed } from 'nanostores';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useListImagesQuery } from 'services/api/endpoints/images';
|
||||
|
||||
@@ -26,10 +30,23 @@ const $upDownHotkeysEnabled = computed([$activeScopes, $isRightPanelOpen], (acti
|
||||
export const useGalleryHotkeys = () => {
|
||||
useAssertSingleton('useGalleryHotkeys');
|
||||
const { goNext, goPrev, isNextEnabled, isPrevEnabled } = useGalleryPagination();
|
||||
const dispatch = useAppDispatch();
|
||||
const selection = useAppSelector((s) => s.gallery.selection);
|
||||
const queryArgs = useAppSelector(selectListImagesQueryArgs);
|
||||
const queryResult = useListImagesQuery(queryArgs);
|
||||
const leftRightHotkeysEnabled = useStore($leftRightHotkeysEnabled);
|
||||
const upDownHotkeysEnabled = useStore($upDownHotkeysEnabled);
|
||||
const canvasRightPanelTab = useStore($canvasRightPanelTab);
|
||||
const appTab = useAppSelector(selectActiveTab);
|
||||
|
||||
// When we are on the canvas tab, we need to disable the delete hotkey when the user is focused on the layers tab in
|
||||
// the right hand panel, because the same hotkey is used to delete layers.
|
||||
const isDeleteEnabledByTab = useMemo(() => {
|
||||
if (appTab !== 'canvas') {
|
||||
return true;
|
||||
}
|
||||
return canvasRightPanelTab === 'gallery';
|
||||
}, [appTab, canvasRightPanelTab]);
|
||||
|
||||
const {
|
||||
handleLeftImage,
|
||||
@@ -95,4 +112,16 @@ export const useGalleryHotkeys = () => {
|
||||
{ preventDefault: true, enabled: upDownHotkeysEnabled },
|
||||
[isOnLastRow, goNext, isNextEnabled, queryResult.isFetching, handleDownImage, upDownHotkeysEnabled]
|
||||
);
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
if (!selection.length) {
|
||||
return;
|
||||
}
|
||||
dispatch(imagesToDeleteSelected(selection));
|
||||
}, [dispatch, selection]);
|
||||
|
||||
useHotkeys(['delete', 'backspace'], handleDelete, { enabled: leftRightHotkeysEnabled && isDeleteEnabledByTab }, [
|
||||
leftRightHotkeysEnabled,
|
||||
isDeleteEnabledByTab,
|
||||
]);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user