mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
refactor(ui): metadata recall buttons & hotkeys (WIP)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
|
||||
import { useLoadWorkflow } from 'features/gallery/hooks/useLoadWorkflow';
|
||||
import { useRecallAll } from 'features/gallery/hooks/useRecallAll';
|
||||
@@ -27,6 +28,11 @@ export const GlobalImageHotkeys = memo(() => {
|
||||
GlobalImageHotkeys.displayName = 'GlobalImageHotkeys';
|
||||
|
||||
const GlobalImageHotkeysInternal = memo(({ imageDTO }: { imageDTO: ImageDTO }) => {
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
const isViewerFocused = useIsRegionFocused('viewer');
|
||||
|
||||
const isFocusOK = isGalleryFocused || isViewerFocused;
|
||||
|
||||
const recallAll = useRecallAll(imageDTO);
|
||||
const recallRemix = useRecallRemix(imageDTO);
|
||||
const recallPrompts = useRecallPrompts(imageDTO);
|
||||
@@ -38,48 +44,48 @@ const GlobalImageHotkeysInternal = memo(({ imageDTO }: { imageDTO: ImageDTO }) =
|
||||
id: 'loadWorkflow',
|
||||
category: 'viewer',
|
||||
callback: loadWorkflow.load,
|
||||
options: { enabled: loadWorkflow.isEnabled },
|
||||
dependencies: [loadWorkflow],
|
||||
options: { enabled: loadWorkflow.isEnabled && isFocusOK },
|
||||
dependencies: [loadWorkflow, isFocusOK],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'recallAll',
|
||||
category: 'viewer',
|
||||
callback: recallAll.recall,
|
||||
options: { enabled: recallAll.isEnabled },
|
||||
dependencies: [recallAll],
|
||||
options: { enabled: recallAll.isEnabled && isFocusOK },
|
||||
dependencies: [recallAll, isFocusOK],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'recallSeed',
|
||||
category: 'viewer',
|
||||
callback: recallSeed.recall,
|
||||
options: { enabled: recallSeed.isEnabled },
|
||||
dependencies: [recallSeed],
|
||||
options: { enabled: recallSeed.isEnabled && isFocusOK },
|
||||
dependencies: [recallSeed, isFocusOK],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'recallPrompts',
|
||||
category: 'viewer',
|
||||
callback: recallPrompts.recall,
|
||||
options: { enabled: recallPrompts.isEnabled },
|
||||
dependencies: [recallPrompts],
|
||||
options: { enabled: recallPrompts.isEnabled && isFocusOK },
|
||||
dependencies: [recallPrompts, isFocusOK],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'remix',
|
||||
category: 'viewer',
|
||||
callback: recallRemix.recall,
|
||||
options: { enabled: recallRemix.isEnabled },
|
||||
dependencies: [recallRemix],
|
||||
options: { enabled: recallRemix.isEnabled && isFocusOK },
|
||||
dependencies: [recallRemix, isFocusOK],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'useSize',
|
||||
category: 'viewer',
|
||||
callback: recallDimensions.recall,
|
||||
options: { enabled: recallDimensions.isEnabled },
|
||||
dependencies: [recallDimensions],
|
||||
options: { enabled: recallDimensions.isEnabled && isFocusOK },
|
||||
dependencies: [recallDimensions, isFocusOK],
|
||||
});
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Menu, MenuButton, MenuItem, MenuList } from '@invoke-ai/ui-library';
|
||||
import { SubMenuButtonContent, useSubMenu } from 'common/hooks/useSubMenu';
|
||||
import { useImageDTOContext } from 'features/gallery/contexts/ImageDTOContext';
|
||||
import { useCreateStylePresetFromMetadata } from 'features/gallery/hooks/useCreateStylePresetFromMetadata';
|
||||
import { useRecallAll } from 'features/gallery/hooks/useRecallAll';
|
||||
import { useRecallDimensions } from 'features/gallery/hooks/useRecallDimensions';
|
||||
import { useRecallPrompts } from 'features/gallery/hooks/useRecallPrompts';
|
||||
import { useRecallRemix } from 'features/gallery/hooks/useRecallRemix';
|
||||
import { useRecallSeed } from 'features/gallery/hooks/useRecallSeed';
|
||||
@@ -12,9 +12,9 @@ import {
|
||||
PiArrowBendUpLeftBold,
|
||||
PiArrowsCounterClockwiseBold,
|
||||
PiAsteriskBold,
|
||||
PiPaintBrushBold,
|
||||
PiPlantBold,
|
||||
PiQuotesBold,
|
||||
PiRulerBold,
|
||||
} from 'react-icons/pi';
|
||||
|
||||
export const ImageMenuItemMetadataRecallActions = memo(() => {
|
||||
@@ -27,7 +27,7 @@ export const ImageMenuItemMetadataRecallActions = memo(() => {
|
||||
const recallRemix = useRecallRemix(imageDTO);
|
||||
const recallPrompts = useRecallPrompts(imageDTO);
|
||||
const recallSeed = useRecallSeed(imageDTO);
|
||||
const stylePreset = useCreateStylePresetFromMetadata(imageDTO);
|
||||
const recallDimensions = useRecallDimensions(imageDTO);
|
||||
|
||||
return (
|
||||
<MenuItem {...subMenu.parentMenuItemProps} icon={<PiArrowBendUpLeftBold />}>
|
||||
@@ -52,8 +52,8 @@ export const ImageMenuItemMetadataRecallActions = memo(() => {
|
||||
<MenuItem icon={<PiAsteriskBold />} onClick={recallAll.recall} isDisabled={!recallAll.isEnabled}>
|
||||
{t('parameters.useAll')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<PiPaintBrushBold />} onClick={stylePreset.create} isDisabled={!stylePreset.isEnabled}>
|
||||
{t('stylePresets.useForTemplate')}
|
||||
<MenuItem icon={<PiRulerBold />} onClick={recallDimensions.recall} isDisabled={!recallDimensions.isEnabled}>
|
||||
{t('parameters.useSize')}
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { MenuItem } from '@invoke-ai/ui-library';
|
||||
import { useImageDTOContext } from 'features/gallery/contexts/ImageDTOContext';
|
||||
import { useCreateStylePresetFromMetadata } from 'features/gallery/hooks/useCreateStylePresetFromMetadata';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiPaintBrushBold } from 'react-icons/pi';
|
||||
|
||||
export const ImageMenuItemUseAsPromptTemplate = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const imageDTO = useImageDTOContext();
|
||||
const stylePreset = useCreateStylePresetFromMetadata(imageDTO);
|
||||
|
||||
return (
|
||||
<MenuItem icon={<PiPaintBrushBold />} onClickCapture={stylePreset.create} isDisabled={!stylePreset.isEnabled}>
|
||||
{t('stylePresets.useForTemplate')}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
|
||||
ImageMenuItemUseAsPromptTemplate.displayName = 'ImageMenuItemUseAsPromptTemplate';
|
||||
@@ -21,6 +21,8 @@ import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { memo } from 'react';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
import { ImageMenuItemUseAsPromptTemplate } from './ImageMenuItemUseAsPromptTemplate';
|
||||
|
||||
type SingleSelectionMenuItemsProps = {
|
||||
imageDTO: ImageDTO;
|
||||
};
|
||||
@@ -45,6 +47,7 @@ const SingleSelectionMenuItems = ({ imageDTO }: SingleSelectionMenuItemsProps) =
|
||||
<ImageMenuItemSendToUpscale />
|
||||
<ImageMenuItemUseForPromptGeneration />
|
||||
{(tab === 'canvas' || tab === 'generate') && <ImageMenuItemUseAsRefImage />}
|
||||
<ImageMenuItemUseAsPromptTemplate />
|
||||
<ImageMenuItemNewCanvasFromImageSubMenu />
|
||||
{tab === 'canvas' && <ImageMenuItemNewLayerFromImageSubMenu />}
|
||||
<MenuDivider />
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Button, Divider, IconButton, Menu, MenuButton, MenuList } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { DeleteImageButton } from 'features/deleteImageModal/components/DeleteImageButton';
|
||||
import SingleSelectionMenuItems from 'features/gallery/components/ImageContextMenu/SingleSelectionMenuItems';
|
||||
@@ -11,10 +10,9 @@ import { useRecallDimensions } from 'features/gallery/hooks/useRecallDimensions'
|
||||
import { useRecallPrompts } from 'features/gallery/hooks/useRecallPrompts';
|
||||
import { useRecallRemix } from 'features/gallery/hooks/useRecallRemix';
|
||||
import { useRecallSeed } from 'features/gallery/hooks/useRecallSeed';
|
||||
import { selectLastSelectedImage } from 'features/gallery/store/gallerySelectors';
|
||||
import { PostProcessingPopover } from 'features/parameters/components/PostProcessing/PostProcessingPopover';
|
||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||
import { selectShouldShowProgressInViewer } from 'features/ui/store/uiSelectors';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -27,19 +25,12 @@ import {
|
||||
PiQuotesBold,
|
||||
PiRulerBold,
|
||||
} from 'react-icons/pi';
|
||||
import { useImageDTO } from 'services/api/endpoints/images';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
import { useImageViewerContext } from './context';
|
||||
|
||||
export const CurrentImageButtons = memo(() => {
|
||||
export const CurrentImageButtons = memo(({ imageDTO }: { imageDTO: ImageDTO }) => {
|
||||
const { t } = useTranslation();
|
||||
const ctx = useImageViewerContext();
|
||||
const hasProgressImage = useStore(ctx.$hasProgressImage);
|
||||
const shouldShowProgressInViewer = useAppSelector(selectShouldShowProgressInViewer);
|
||||
const isDisabledOverride = hasProgressImage && shouldShowProgressInViewer;
|
||||
|
||||
const imageName = useAppSelector(selectLastSelectedImage);
|
||||
const imageDTO = useImageDTO(imageName);
|
||||
const tab = useAppSelector(selectActiveTab);
|
||||
const isCanvasOrGenerateTab = tab === 'canvas' || tab === 'generate';
|
||||
|
||||
const isUpscalingEnabled = useFeatureStatus('upscaling');
|
||||
|
||||
@@ -52,8 +43,6 @@ export const CurrentImageButtons = memo(() => {
|
||||
const editImage = useEditImage(imageDTO);
|
||||
const deleteImage = useDeleteImage(imageDTO);
|
||||
|
||||
console.log(isDisabledOverride, recallSeed.isEnabled);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Menu isLazy>
|
||||
@@ -61,7 +50,7 @@ export const CurrentImageButtons = memo(() => {
|
||||
as={IconButton}
|
||||
aria-label={t('parameters.imageActions')}
|
||||
tooltip={t('parameters.imageActions')}
|
||||
isDisabled={isDisabledOverride || !imageDTO}
|
||||
isDisabled={!imageDTO}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
icon={<PiDotsThreeOutlineFill />}
|
||||
@@ -74,7 +63,7 @@ export const CurrentImageButtons = memo(() => {
|
||||
<Button
|
||||
leftIcon={<PiPencilBold />}
|
||||
onClick={editImage.edit}
|
||||
isDisabled={isDisabledOverride || !editImage.isEnabled}
|
||||
isDisabled={!editImage.isEnabled}
|
||||
variant="link"
|
||||
size="sm"
|
||||
alignSelf="stretch"
|
||||
@@ -89,62 +78,72 @@ export const CurrentImageButtons = memo(() => {
|
||||
icon={<PiFlowArrowBold />}
|
||||
tooltip={`${t('nodes.loadWorkflow')} (W)`}
|
||||
aria-label={`${t('nodes.loadWorkflow')} (W)`}
|
||||
isDisabled={isDisabledOverride || !loadWorkflow.isEnabled}
|
||||
isDisabled={!loadWorkflow.isEnabled}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={loadWorkflow.load}
|
||||
/>
|
||||
<IconButton
|
||||
icon={<PiArrowsCounterClockwiseBold />}
|
||||
tooltip={`${t('parameters.remixImage')} (R)`}
|
||||
aria-label={`${t('parameters.remixImage')} (R)`}
|
||||
isDisabled={isDisabledOverride || !recallRemix.isEnabled}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={recallRemix.recall}
|
||||
/>
|
||||
<IconButton
|
||||
icon={<PiQuotesBold />}
|
||||
tooltip={`${t('parameters.usePrompt')} (P)`}
|
||||
aria-label={`${t('parameters.usePrompt')} (P)`}
|
||||
isDisabled={isDisabledOverride || !recallPrompts.isEnabled}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={recallPrompts.recall}
|
||||
/>
|
||||
<IconButton
|
||||
icon={<PiPlantBold />}
|
||||
tooltip={`${t('parameters.useSeed')} (S)`}
|
||||
aria-label={`${t('parameters.useSeed')} (S)`}
|
||||
isDisabled={isDisabledOverride || !recallSeed.isEnabled}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={recallSeed.recall}
|
||||
/>
|
||||
<IconButton
|
||||
icon={<PiRulerBold />}
|
||||
tooltip={`${t('parameters.useSize')} (D)`}
|
||||
aria-label={`${t('parameters.useSize')} (D)`}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={recallDimensions.recall}
|
||||
isDisabled={isDisabledOverride || !recallDimensions.isEnabled}
|
||||
/>
|
||||
<IconButton
|
||||
icon={<PiAsteriskBold />}
|
||||
tooltip={`${t('parameters.useAll')} (A)`}
|
||||
aria-label={`${t('parameters.useAll')} (A)`}
|
||||
isDisabled={isDisabledOverride || !recallAll.isEnabled}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={recallAll.recall}
|
||||
/>
|
||||
{isCanvasOrGenerateTab && (
|
||||
<IconButton
|
||||
icon={<PiArrowsCounterClockwiseBold />}
|
||||
tooltip={`${t('parameters.remixImage')} (R)`}
|
||||
aria-label={`${t('parameters.remixImage')} (R)`}
|
||||
isDisabled={!recallRemix.isEnabled}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={recallRemix.recall}
|
||||
/>
|
||||
)}
|
||||
{isCanvasOrGenerateTab && (
|
||||
<IconButton
|
||||
icon={<PiQuotesBold />}
|
||||
tooltip={`${t('parameters.usePrompt')} (P)`}
|
||||
aria-label={`${t('parameters.usePrompt')} (P)`}
|
||||
isDisabled={!recallPrompts.isEnabled}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={recallPrompts.recall}
|
||||
/>
|
||||
)}
|
||||
{isCanvasOrGenerateTab && (
|
||||
<IconButton
|
||||
icon={<PiPlantBold />}
|
||||
tooltip={`${t('parameters.useSeed')} (S)`}
|
||||
aria-label={`${t('parameters.useSeed')} (S)`}
|
||||
isDisabled={!recallSeed.isEnabled}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={recallSeed.recall}
|
||||
/>
|
||||
)}
|
||||
{isCanvasOrGenerateTab && (
|
||||
<IconButton
|
||||
icon={<PiRulerBold />}
|
||||
tooltip={`${t('parameters.useSize')} (D)`}
|
||||
aria-label={`${t('parameters.useSize')} (D)`}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={recallDimensions.recall}
|
||||
isDisabled={!recallDimensions.isEnabled}
|
||||
/>
|
||||
)}
|
||||
{isCanvasOrGenerateTab && (
|
||||
<IconButton
|
||||
icon={<PiAsteriskBold />}
|
||||
tooltip={`${t('parameters.useAll')} (A)`}
|
||||
aria-label={`${t('parameters.useAll')} (A)`}
|
||||
isDisabled={!recallAll.isEnabled}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={recallAll.recall}
|
||||
/>
|
||||
)}
|
||||
|
||||
{isUpscalingEnabled && <PostProcessingPopover imageDTO={imageDTO} isDisabled={isDisabledOverride} />}
|
||||
{isUpscalingEnabled && <PostProcessingPopover imageDTO={imageDTO} isDisabled={false} />}
|
||||
|
||||
<Divider orientation="vertical" h={8} mx={2} />
|
||||
|
||||
<DeleteImageButton onClick={deleteImage.delete} isDisabled={isDisabledOverride || !deleteImage.isEnabled} />
|
||||
<DeleteImageButton onClick={deleteImage.delete} isDisabled={!deleteImage.isEnabled} />
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
import { Flex, Spacer } from '@invoke-ai/ui-library';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { ToggleMetadataViewerButton } from 'features/gallery/components/ImageViewer/ToggleMetadataViewerButton';
|
||||
import { selectLastSelectedImage } from 'features/gallery/store/gallerySelectors';
|
||||
import { memo } from 'react';
|
||||
import { useImageDTO } from 'services/api/endpoints/images';
|
||||
|
||||
import { CurrentImageButtons } from './CurrentImageButtons';
|
||||
import { ToggleProgressButton } from './ToggleProgressButton';
|
||||
|
||||
export const ViewerToolbar = memo(() => {
|
||||
const imageName = useAppSelector(selectLastSelectedImage);
|
||||
const imageDTO = useImageDTO(imageName);
|
||||
|
||||
return (
|
||||
<Flex w="full" justifyContent="center" h={8}>
|
||||
<ToggleProgressButton />
|
||||
<Spacer />
|
||||
<CurrentImageButtons />
|
||||
{imageDTO && <CurrentImageButtons imageDTO={imageDTO} />}
|
||||
<Spacer />
|
||||
<ToggleMetadataViewerButton />
|
||||
{imageDTO && <ToggleMetadataViewerButton />}
|
||||
</Flex>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useAppStore } from 'app/store/storeHooks';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { useCanvasManagerSafe } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
import { newCanvasFromImage } from 'features/imageActions/actions';
|
||||
import { toast } from 'features/toast/toast';
|
||||
@@ -11,8 +10,6 @@ import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
export const useEditImage = (imageDTO?: ImageDTO | null) => {
|
||||
const { t } = useTranslation();
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
const isViewerFocused = useIsRegionFocused('viewer');
|
||||
|
||||
const { getState, dispatch } = useAppStore();
|
||||
const canvasManager = useCanvasManagerSafe();
|
||||
@@ -21,11 +18,8 @@ export const useEditImage = (imageDTO?: ImageDTO | null) => {
|
||||
if (!imageDTO) {
|
||||
return false;
|
||||
}
|
||||
if (!isGalleryFocused && !isViewerFocused) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, [imageDTO, isGalleryFocused, isViewerFocused]);
|
||||
}, [imageDTO]);
|
||||
|
||||
const edit = useCallback(async () => {
|
||||
if (!imageDTO) {
|
||||
|
||||
@@ -1,32 +1,23 @@
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { $hasTemplates } from 'features/nodes/store/nodesSlice';
|
||||
import { useLoadWorkflowWithDialog } from 'features/workflowLibrary/components/LoadWorkflowConfirmationAlertDialog';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
export const useLoadWorkflow = (imageDTO?: ImageDTO | null) => {
|
||||
export const useLoadWorkflow = (imageDTO: ImageDTO) => {
|
||||
const hasTemplates = useStore($hasTemplates);
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
const isViewerFocused = useIsRegionFocused('viewer');
|
||||
|
||||
const loadWorkflowWithDialog = useLoadWorkflowWithDialog();
|
||||
|
||||
const isEnabled = useMemo(() => {
|
||||
if (!imageDTO) {
|
||||
return false;
|
||||
}
|
||||
if (!imageDTO.has_workflow) {
|
||||
return false;
|
||||
}
|
||||
if (!hasTemplates) {
|
||||
return false;
|
||||
}
|
||||
if (!isGalleryFocused && !isViewerFocused) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, [hasTemplates, imageDTO, isGalleryFocused, isViewerFocused]);
|
||||
}, [hasTemplates, imageDTO]);
|
||||
|
||||
const load = useCallback(() => {
|
||||
if (!imageDTO) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useAppSelector, useAppStore } from 'app/store/storeHooks';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice';
|
||||
import { MetadataHandlers, MetadataUtils } from 'features/metadata/parsing';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
@@ -9,17 +8,15 @@ import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
import { useClearStylePresetWithToast } from './useClearStylePresetWithToast';
|
||||
|
||||
export const useRecallAll = (imageDTO?: ImageDTO | null) => {
|
||||
export const useRecallAll = (imageDTO: ImageDTO) => {
|
||||
const store = useAppStore();
|
||||
const tab = useAppSelector(selectActiveTab);
|
||||
const { metadata } = useDebouncedMetadata(imageDTO?.image_name);
|
||||
const { metadata, isLoading } = useDebouncedMetadata(imageDTO.image_name);
|
||||
const isStaging = useAppSelector(selectIsStaging);
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
const isViewerFocused = useIsRegionFocused('viewer');
|
||||
const clearStylePreset = useClearStylePresetWithToast();
|
||||
|
||||
const isEnabled = useMemo(() => {
|
||||
if (!isGalleryFocused && !isViewerFocused) {
|
||||
if (isLoading) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -32,7 +29,7 @@ export const useRecallAll = (imageDTO?: ImageDTO | null) => {
|
||||
}
|
||||
|
||||
return true;
|
||||
}, [isGalleryFocused, isViewerFocused, metadata, tab]);
|
||||
}, [isLoading, metadata, tab]);
|
||||
|
||||
const handlersToSkip = useMemo(() => {
|
||||
if (tab === 'canvas' && isStaging) {
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
import { useAppSelector, useAppStore } from 'app/store/storeHooks';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice';
|
||||
import { MetadataUtils } from 'features/metadata/parsing';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
export const useRecallDimensions = (imageDTO?: ImageDTO | null) => {
|
||||
export const useRecallDimensions = (imageDTO: ImageDTO) => {
|
||||
const store = useAppStore();
|
||||
const tab = useAppSelector(selectActiveTab);
|
||||
const isStaging = useAppSelector(selectIsStaging);
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
const isViewerFocused = useIsRegionFocused('viewer');
|
||||
|
||||
const isEnabled = useMemo(() => {
|
||||
if (!imageDTO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isGalleryFocused && !isViewerFocused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tab !== 'canvas' && tab !== 'generate') {
|
||||
return false;
|
||||
}
|
||||
@@ -31,12 +20,9 @@ export const useRecallDimensions = (imageDTO?: ImageDTO | null) => {
|
||||
}
|
||||
|
||||
return true;
|
||||
}, [imageDTO, isGalleryFocused, isStaging, isViewerFocused, tab]);
|
||||
}, [isStaging, tab]);
|
||||
|
||||
const recall = useCallback(() => {
|
||||
if (!imageDTO) {
|
||||
return;
|
||||
}
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useAppSelector, useAppStore } from 'app/store/storeHooks';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { MetadataHandlers, MetadataUtils } from 'features/metadata/parsing';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
@@ -8,15 +7,13 @@ import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
import { useClearStylePresetWithToast } from './useClearStylePresetWithToast';
|
||||
|
||||
export const useRecallPrompts = (imageDTO?: ImageDTO | null) => {
|
||||
export const useRecallPrompts = (imageDTO: ImageDTO) => {
|
||||
const store = useAppStore();
|
||||
const tab = useAppSelector(selectActiveTab);
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
const isViewerFocused = useIsRegionFocused('viewer');
|
||||
const clearStylePreset = useClearStylePresetWithToast();
|
||||
const [hasPrompts, setHasPrompts] = useState(false);
|
||||
|
||||
const { metadata } = useDebouncedMetadata(imageDTO?.image_name);
|
||||
const { metadata, isLoading } = useDebouncedMetadata(imageDTO.image_name);
|
||||
|
||||
useEffect(() => {
|
||||
const parse = async () => {
|
||||
@@ -42,7 +39,7 @@ export const useRecallPrompts = (imageDTO?: ImageDTO | null) => {
|
||||
}, [metadata, store]);
|
||||
|
||||
const isEnabled = useMemo(() => {
|
||||
if (!isGalleryFocused && !isViewerFocused) {
|
||||
if (isLoading) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -55,7 +52,7 @@ export const useRecallPrompts = (imageDTO?: ImageDTO | null) => {
|
||||
}
|
||||
|
||||
return true;
|
||||
}, [hasPrompts, isGalleryFocused, isViewerFocused, tab]);
|
||||
}, [hasPrompts, isLoading, tab]);
|
||||
|
||||
const recall = useCallback(() => {
|
||||
if (!metadata) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useAppSelector, useAppStore } from 'app/store/storeHooks';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice';
|
||||
import { MetadataHandlers, MetadataUtils } from 'features/metadata/parsing';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
@@ -9,18 +8,16 @@ import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
import { useClearStylePresetWithToast } from './useClearStylePresetWithToast';
|
||||
|
||||
export const useRecallRemix = (imageDTO?: ImageDTO | null) => {
|
||||
export const useRecallRemix = (imageDTO: ImageDTO) => {
|
||||
const store = useAppStore();
|
||||
const tab = useAppSelector(selectActiveTab);
|
||||
const isStaging = useAppSelector(selectIsStaging);
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
const isViewerFocused = useIsRegionFocused('viewer');
|
||||
const clearStylePreset = useClearStylePresetWithToast();
|
||||
|
||||
const { metadata } = useDebouncedMetadata(imageDTO?.image_name);
|
||||
const { metadata, isLoading } = useDebouncedMetadata(imageDTO.image_name);
|
||||
|
||||
const isEnabled = useMemo(() => {
|
||||
if (!isGalleryFocused && !isViewerFocused) {
|
||||
if (isLoading) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -33,7 +30,7 @@ export const useRecallRemix = (imageDTO?: ImageDTO | null) => {
|
||||
}
|
||||
|
||||
return true;
|
||||
}, [isGalleryFocused, isViewerFocused, metadata, tab]);
|
||||
}, [isLoading, metadata, tab]);
|
||||
|
||||
const handlersToSkip = useMemo(() => {
|
||||
// Remix always skips the seed handler
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
import { useAppSelector, useAppStore } from 'app/store/storeHooks';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { MetadataHandlers, MetadataUtils } from 'features/metadata/parsing';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useDebouncedMetadata } from 'services/api/hooks/useDebouncedMetadata';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
export const useRecallSeed = (imageDTO?: ImageDTO | null) => {
|
||||
export const useRecallSeed = (imageDTO: ImageDTO) => {
|
||||
const store = useAppStore();
|
||||
const tab = useAppSelector(selectActiveTab);
|
||||
const [hasSeed, setHasSeed] = useState(false);
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
const isViewerFocused = useIsRegionFocused('viewer');
|
||||
|
||||
const { metadata } = useDebouncedMetadata(imageDTO?.image_name);
|
||||
const { metadata, isLoading } = useDebouncedMetadata(imageDTO.image_name);
|
||||
|
||||
useEffect(() => {
|
||||
const parse = async () => {
|
||||
@@ -29,7 +26,7 @@ export const useRecallSeed = (imageDTO?: ImageDTO | null) => {
|
||||
}, [metadata, store]);
|
||||
|
||||
const isEnabled = useMemo(() => {
|
||||
if (!isGalleryFocused && !isViewerFocused) {
|
||||
if (isLoading) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -46,7 +43,7 @@ export const useRecallSeed = (imageDTO?: ImageDTO | null) => {
|
||||
}
|
||||
|
||||
return true;
|
||||
}, [hasSeed, isGalleryFocused, isViewerFocused, metadata, tab]);
|
||||
}, [hasSeed, isLoading, metadata, tab]);
|
||||
|
||||
const recall = useCallback(() => {
|
||||
if (!metadata) {
|
||||
|
||||
Reference in New Issue
Block a user