mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
fix(ui): Apple Pencil requires onPointerUp instead of onClick
With `onClick`, elements w/ a tooltip require a double-tap.
This commit is contained in:
committed by
Kent Keirsey
parent
af5f342347
commit
2a90f4f59e
@@ -65,10 +65,10 @@ const AppErrorBoundaryFallback = ({ error, resetErrorBoundary }: Props) => {
|
||||
</Text>
|
||||
</Flex>
|
||||
<Flex gap={4}>
|
||||
<Button leftIcon={<PiArrowCounterClockwiseBold />} onClick={resetErrorBoundary}>
|
||||
<Button leftIcon={<PiArrowCounterClockwiseBold />} onPointerUp={resetErrorBoundary}>
|
||||
{t('accessibility.resetUI')}
|
||||
</Button>
|
||||
<Button leftIcon={<PiCopyBold />} onClick={handleCopy}>
|
||||
<Button leftIcon={<PiCopyBold />} onPointerUp={handleCopy}>
|
||||
{t('common.copyError')}
|
||||
</Button>
|
||||
<Link href={url} isExternal>
|
||||
|
||||
@@ -98,8 +98,8 @@ const RgbColorPicker = (props: Props) => {
|
||||
export default memo(RgbColorPicker);
|
||||
|
||||
const ColorSwatch = ({ color, onChange }: { color: RgbColor; onChange: (color: RgbColor) => void }) => {
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
onChange(color);
|
||||
}, [color, onChange]);
|
||||
return <Box role="button" onClick={onClick} h={8} w={8} bg={rgbColorToString(color)} borderRadius="base" />;
|
||||
return <Box role="button" onPointerUp={onPointerUp} h={8} w={8} bg={rgbColorToString(color)} borderRadius="base" />;
|
||||
};
|
||||
|
||||
@@ -109,8 +109,8 @@ const RgbaColorPicker = (props: Props) => {
|
||||
export default memo(RgbaColorPicker);
|
||||
|
||||
const ColorSwatch = ({ color, onChange }: { color: RgbaColor; onChange: (color: RgbaColor) => void }) => {
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
onChange(color);
|
||||
}, [color, onChange]);
|
||||
return <Box role="button" onClick={onClick} h={8} w={8} bg={rgbaColorToString(color)} borderRadius="base" />;
|
||||
return <Box role="button" onPointerUp={onPointerUp} h={8} w={8} bg={rgbaColorToString(color)} borderRadius="base" />;
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ type IAIDndImageProps = FlexProps & {
|
||||
imageDTO: ImageDTO | undefined;
|
||||
onError?: (event: SyntheticEvent<HTMLImageElement>) => void;
|
||||
onLoad?: (event: SyntheticEvent<HTMLImageElement>) => void;
|
||||
onClick?: (event: MouseEvent<HTMLDivElement>) => void;
|
||||
onPointerUp?: (event: MouseEvent<HTMLDivElement>) => void;
|
||||
withMetadataOverlay?: boolean;
|
||||
isDragDisabled?: boolean;
|
||||
isDropDisabled?: boolean;
|
||||
@@ -82,7 +82,7 @@ const IAIDndImage = (props: IAIDndImageProps) => {
|
||||
const {
|
||||
imageDTO,
|
||||
onError,
|
||||
onClick,
|
||||
onPointerUp,
|
||||
withMetadataOverlay = false,
|
||||
isDropDisabled = false,
|
||||
isDragDisabled = false,
|
||||
@@ -228,7 +228,7 @@ const IAIDndImage = (props: IAIDndImageProps) => {
|
||||
<IAIDraggable
|
||||
data={draggableData}
|
||||
disabled={isDragDisabled || !imageDTO}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
onAuxClick={openInNewTab}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -16,17 +16,17 @@ const sx: SystemStyleObject = {
|
||||
},
|
||||
};
|
||||
|
||||
type Props = Omit<IconButtonProps, 'aria-label' | 'onClick' | 'tooltip'> & {
|
||||
onClick: (event: MouseEvent<HTMLButtonElement>) => void;
|
||||
type Props = Omit<IconButtonProps, 'aria-label' | 'onPointerUp' | 'tooltip'> & {
|
||||
onPointerUp: (event: MouseEvent<HTMLButtonElement>) => void;
|
||||
tooltip: string;
|
||||
};
|
||||
|
||||
const IAIDndImageIcon = (props: Props) => {
|
||||
const { onClick, tooltip, icon, ...rest } = props;
|
||||
const { onPointerUp, tooltip, icon, ...rest } = props;
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
aria-label={tooltip}
|
||||
icon={icon}
|
||||
variant="link"
|
||||
|
||||
@@ -95,14 +95,14 @@ const Content = ({ data, feature, hideDisable }: ContentProps) => {
|
||||
[feature, t]
|
||||
);
|
||||
|
||||
const onClickLearnMore = useCallback(() => {
|
||||
const onPointerUpLearnMore = useCallback(() => {
|
||||
if (!data?.href) {
|
||||
return;
|
||||
}
|
||||
window.open(data.href);
|
||||
}, [data?.href]);
|
||||
|
||||
const onClickDontShowMeThese = useCallback(() => {
|
||||
const onPointerUpDontShowMeThese = useCallback(() => {
|
||||
dispatch(setShouldEnableInformationalPopovers(false));
|
||||
toast({
|
||||
title: t('settings.informationalPopoversDisabled'),
|
||||
@@ -135,13 +135,13 @@ const Content = ({ data, feature, hideDisable }: ContentProps) => {
|
||||
<Divider />
|
||||
<Flex alignItems="center" justifyContent="space-between" w="full">
|
||||
{!hideDisable && (
|
||||
<Button onClick={onClickDontShowMeThese} variant="link" size="sm">
|
||||
<Button onPointerUp={onPointerUpDontShowMeThese} variant="link" size="sm">
|
||||
{t('common.dontShowMeThese')}
|
||||
</Button>
|
||||
)}
|
||||
<Spacer />
|
||||
{data?.href && (
|
||||
<Button onClick={onClickLearnMore} leftIcon={<PiArrowSquareOutBold />} variant="link" size="sm">
|
||||
<Button onPointerUp={onPointerUpLearnMore} leftIcon={<PiArrowSquareOutBold />} variant="link" size="sm">
|
||||
{t('common.learnMore') ?? heading}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -33,7 +33,7 @@ export const CanvasAddEntityButtons = memo(() => {
|
||||
variant="ghost"
|
||||
justifyContent="flex-start"
|
||||
leftIcon={<PiPlusBold />}
|
||||
onClick={addGlobalReferenceImage}
|
||||
onPointerUp={addGlobalReferenceImage}
|
||||
isDisabled={isFLUX}
|
||||
>
|
||||
{t('controlLayers.globalReferenceImage')}
|
||||
@@ -46,7 +46,7 @@ export const CanvasAddEntityButtons = memo(() => {
|
||||
variant="ghost"
|
||||
justifyContent="flex-start"
|
||||
leftIcon={<PiPlusBold />}
|
||||
onClick={addInpaintMask}
|
||||
onPointerUp={addInpaintMask}
|
||||
>
|
||||
{t('controlLayers.inpaintMask')}
|
||||
</Button>
|
||||
@@ -55,7 +55,7 @@ export const CanvasAddEntityButtons = memo(() => {
|
||||
variant="ghost"
|
||||
justifyContent="flex-start"
|
||||
leftIcon={<PiPlusBold />}
|
||||
onClick={addRegionalGuidance}
|
||||
onPointerUp={addRegionalGuidance}
|
||||
isDisabled={isFLUX}
|
||||
>
|
||||
{t('controlLayers.regionalGuidance')}
|
||||
@@ -65,7 +65,7 @@ export const CanvasAddEntityButtons = memo(() => {
|
||||
variant="ghost"
|
||||
justifyContent="flex-start"
|
||||
leftIcon={<PiPlusBold />}
|
||||
onClick={addRegionalReferenceImage}
|
||||
onPointerUp={addRegionalReferenceImage}
|
||||
isDisabled={isFLUX}
|
||||
>
|
||||
{t('controlLayers.regionalReferenceImage')}
|
||||
@@ -79,7 +79,7 @@ export const CanvasAddEntityButtons = memo(() => {
|
||||
variant="ghost"
|
||||
justifyContent="flex-start"
|
||||
leftIcon={<PiPlusBold />}
|
||||
onClick={addControlLayer}
|
||||
onPointerUp={addControlLayer}
|
||||
isDisabled={isFLUX}
|
||||
>
|
||||
{t('controlLayers.controlLayer')}
|
||||
@@ -89,7 +89,7 @@ export const CanvasAddEntityButtons = memo(() => {
|
||||
variant="ghost"
|
||||
justifyContent="flex-start"
|
||||
leftIcon={<PiPlusBold />}
|
||||
onClick={addRasterLayer}
|
||||
onPointerUp={addRasterLayer}
|
||||
>
|
||||
{t('controlLayers.rasterLayer')}
|
||||
</Button>
|
||||
|
||||
@@ -17,12 +17,12 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||
|
||||
const ActivateImageViewerButton = (props: PropsWithChildren) => {
|
||||
const imageViewer = useImageViewer();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
imageViewer.open();
|
||||
selectCanvasRightPanelGalleryTab();
|
||||
}, [imageViewer]);
|
||||
return (
|
||||
<Button onClick={onClick} size="sm" variant="link" color="base.50">
|
||||
<Button onPointerUp={onPointerUp} size="sm" variant="link" color="base.50">
|
||||
{props.children}
|
||||
</Button>
|
||||
);
|
||||
@@ -58,13 +58,13 @@ export const CanvasAlertsSendingToGallery = () => {
|
||||
const ActivateCanvasButton = (props: PropsWithChildren) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const imageViewer = useImageViewer();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(setActiveTab('canvas'));
|
||||
selectCanvasRightPanelLayersTab();
|
||||
imageViewer.close();
|
||||
}, [dispatch, imageViewer]);
|
||||
return (
|
||||
<Button onClick={onClick} size="sm" variant="link" color="base.50">
|
||||
<Button onPointerUp={onPointerUp} size="sm" variant="link" color="base.50">
|
||||
{props.children}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -30,24 +30,24 @@ export const CanvasContextMenuGlobalMenuItems = memo(() => {
|
||||
<CanvasContextMenuItemsCropCanvasToBbox />
|
||||
</MenuGroup>
|
||||
<MenuGroup title={t('controlLayers.canvasContextMenu.saveToGalleryGroup')}>
|
||||
<MenuItem icon={<PiFloppyDiskBold />} isDisabled={isBusy} onClick={saveCanvasToGallery}>
|
||||
<MenuItem icon={<PiFloppyDiskBold />} isDisabled={isBusy} onPointerUp={saveCanvasToGallery}>
|
||||
{t('controlLayers.canvasContextMenu.saveCanvasToGallery')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<PiFloppyDiskBold />} isDisabled={isBusy} onClick={saveBboxToGallery}>
|
||||
<MenuItem icon={<PiFloppyDiskBold />} isDisabled={isBusy} onPointerUp={saveBboxToGallery}>
|
||||
{t('controlLayers.canvasContextMenu.saveBboxToGallery')}
|
||||
</MenuItem>
|
||||
</MenuGroup>
|
||||
<MenuGroup title={t('controlLayers.canvasContextMenu.bboxGroup')}>
|
||||
<MenuItem icon={<NewLayerIcon />} isDisabled={isBusy} onClick={newGlobalReferenceImageFromBbox}>
|
||||
<MenuItem icon={<NewLayerIcon />} isDisabled={isBusy} onPointerUp={newGlobalReferenceImageFromBbox}>
|
||||
{t('controlLayers.canvasContextMenu.newGlobalReferenceImage')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<NewLayerIcon />} isDisabled={isBusy} onClick={newRegionalReferenceImageFromBbox}>
|
||||
<MenuItem icon={<NewLayerIcon />} isDisabled={isBusy} onPointerUp={newRegionalReferenceImageFromBbox}>
|
||||
{t('controlLayers.canvasContextMenu.newRegionalReferenceImage')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<NewLayerIcon />} isDisabled={isBusy} onClick={newControlLayerFromBbox}>
|
||||
<MenuItem icon={<NewLayerIcon />} isDisabled={isBusy} onPointerUp={newControlLayerFromBbox}>
|
||||
{t('controlLayers.canvasContextMenu.newControlLayer')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<NewLayerIcon />} isDisabled={isBusy} onClick={newRasterLayerFromBbox}>
|
||||
<MenuItem icon={<NewLayerIcon />} isDisabled={isBusy} onPointerUp={newRasterLayerFromBbox}>
|
||||
{t('controlLayers.canvasContextMenu.newRasterLayer')}
|
||||
</MenuItem>
|
||||
</MenuGroup>
|
||||
|
||||
@@ -17,7 +17,7 @@ export const CanvasContextMenuItemsCropCanvasToBbox = memo(() => {
|
||||
}, [canvasManager]);
|
||||
|
||||
return (
|
||||
<MenuItem icon={<PiCropBold />} isDisabled={isBusy} onClick={cropCanvasToBbox}>
|
||||
<MenuItem icon={<PiCropBold />} isDisabled={isBusy} onPointerUp={cropCanvasToBbox}>
|
||||
{t('controlLayers.canvasContextMenu.cropCanvasToBbox')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -40,26 +40,26 @@ export const EntityListGlobalActionBarAddLayerMenu = memo(() => {
|
||||
/>
|
||||
<MenuList>
|
||||
<MenuGroup title={t('controlLayers.global')}>
|
||||
<MenuItem icon={<PiPlusBold />} onClick={addGlobalReferenceImage} isDisabled={isFLUX}>
|
||||
<MenuItem icon={<PiPlusBold />} onPointerUp={addGlobalReferenceImage} isDisabled={isFLUX}>
|
||||
{t('controlLayers.globalReferenceImage')}
|
||||
</MenuItem>
|
||||
</MenuGroup>
|
||||
<MenuGroup title={t('controlLayers.regional')}>
|
||||
<MenuItem icon={<PiPlusBold />} onClick={addInpaintMask}>
|
||||
<MenuItem icon={<PiPlusBold />} onPointerUp={addInpaintMask}>
|
||||
{t('controlLayers.inpaintMask')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<PiPlusBold />} onClick={addRegionalGuidance} isDisabled={isFLUX}>
|
||||
<MenuItem icon={<PiPlusBold />} onPointerUp={addRegionalGuidance} isDisabled={isFLUX}>
|
||||
{t('controlLayers.regionalGuidance')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<PiPlusBold />} onClick={addRegionalReferenceImage} isDisabled={isFLUX}>
|
||||
<MenuItem icon={<PiPlusBold />} onPointerUp={addRegionalReferenceImage} isDisabled={isFLUX}>
|
||||
{t('controlLayers.regionalReferenceImage')}
|
||||
</MenuItem>
|
||||
</MenuGroup>
|
||||
<MenuGroup title={t('controlLayers.layer_other')}>
|
||||
<MenuItem icon={<PiPlusBold />} onClick={addControlLayer} isDisabled={isFLUX}>
|
||||
<MenuItem icon={<PiPlusBold />} onPointerUp={addControlLayer} isDisabled={isFLUX}>
|
||||
{t('controlLayers.controlLayer')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<PiPlusBold />} onClick={addRasterLayer}>
|
||||
<MenuItem icon={<PiPlusBold />} onPointerUp={addRasterLayer}>
|
||||
{t('controlLayers.rasterLayer')}
|
||||
</MenuItem>
|
||||
</MenuGroup>
|
||||
|
||||
@@ -12,7 +12,7 @@ export const EntityListSelectedEntityActionBarDuplicateButton = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const isBusy = useCanvasIsBusy();
|
||||
const selectedEntityIdentifier = useAppSelector(selectSelectedEntityIdentifier);
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
if (!selectedEntityIdentifier) {
|
||||
return;
|
||||
}
|
||||
@@ -21,7 +21,7 @@ export const EntityListSelectedEntityActionBarDuplicateButton = memo(() => {
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
isDisabled={!selectedEntityIdentifier || isBusy}
|
||||
size="sm"
|
||||
variant="link"
|
||||
|
||||
@@ -22,7 +22,7 @@ export const EntityListSelectedEntityActionBarFilterButton = memo(() => {
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClick={filter.start}
|
||||
onPointerUp={filter.start}
|
||||
isDisabled={filter.isDisabled}
|
||||
size="sm"
|
||||
variant="link"
|
||||
|
||||
@@ -15,7 +15,7 @@ export const EntityListSelectedEntityActionBarSaveToAssetsButton = memo(() => {
|
||||
const selectedEntityIdentifier = useAppSelector(selectSelectedEntityIdentifier);
|
||||
const adapter = useEntityAdapterSafe(selectedEntityIdentifier);
|
||||
const saveLayerToAssets = useSaveLayerToAssets();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
saveLayerToAssets(adapter);
|
||||
}, [saveLayerToAssets, adapter]);
|
||||
|
||||
@@ -29,7 +29,7 @@ export const EntityListSelectedEntityActionBarSaveToAssetsButton = memo(() => {
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
isDisabled={!selectedEntityIdentifier || isBusy}
|
||||
size="sm"
|
||||
variant="link"
|
||||
|
||||
@@ -22,7 +22,7 @@ export const EntityListSelectedEntityActionBarTransformButton = memo(() => {
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClick={transform.start}
|
||||
onPointerUp={transform.start}
|
||||
isDisabled={transform.isDisabled}
|
||||
size="sm"
|
||||
variant="link"
|
||||
|
||||
@@ -20,7 +20,7 @@ export const CanvasRightPanel = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const tabIndex = useStore($canvasRightPanelTabIndex);
|
||||
const imageViewer = useImageViewer();
|
||||
const onClickViewerToggleButton = useCallback(() => {
|
||||
const onPointerUpViewerToggleButton = useCallback(() => {
|
||||
if ($canvasRightPanelTabIndex.get() !== 1) {
|
||||
$canvasRightPanelTabIndex.set(1);
|
||||
}
|
||||
@@ -38,7 +38,7 @@ export const CanvasRightPanel = memo(() => {
|
||||
<TabList alignItems="center">
|
||||
<PanelTabs />
|
||||
<Spacer />
|
||||
<Button size="sm" variant="ghost" onClick={onClickViewerToggleButton}>
|
||||
<Button size="sm" variant="ghost" onPointerUp={onPointerUpViewerToggleButton}>
|
||||
{imageViewer.isOpen ? t('gallery.closeViewer') : t('gallery.openViewer')}
|
||||
</Button>
|
||||
</TabList>
|
||||
|
||||
@@ -84,7 +84,7 @@ export const ControlLayerControlAdapter = memo(() => {
|
||||
<Flex w="full" gap={2}>
|
||||
<ControlLayerControlAdapterModel modelKey={controlAdapter.model?.key ?? null} onChange={onChangeModel} />
|
||||
<IconButton
|
||||
onClick={filter.start}
|
||||
onPointerUp={filter.start}
|
||||
isDisabled={filter.isDisabled}
|
||||
size="sm"
|
||||
alignSelf="stretch"
|
||||
@@ -94,7 +94,7 @@ export const ControlLayerControlAdapter = memo(() => {
|
||||
icon={<PiShootingStarBold />}
|
||||
/>
|
||||
<IconButton
|
||||
onClick={pullBboxIntoLayer}
|
||||
onPointerUp={pullBboxIntoLayer}
|
||||
isDisabled={isBusy}
|
||||
size="sm"
|
||||
alignSelf="stretch"
|
||||
|
||||
@@ -18,7 +18,7 @@ export const ControlLayerMenuItemsConvertControlToRaster = memo(() => {
|
||||
}, [dispatch, entityIdentifier]);
|
||||
|
||||
return (
|
||||
<MenuItem onClick={convertControlLayerToRasterLayer} icon={<PiLightningBold />} isDisabled={!isInteractable}>
|
||||
<MenuItem onPointerUp={convertControlLayerToRasterLayer} icon={<PiLightningBold />} isDisabled={!isInteractable}>
|
||||
{t('controlLayers.convertToRasterLayer')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -28,7 +28,7 @@ export const ControlLayerMenuItemsTransparencyEffect = memo(() => {
|
||||
}, [dispatch, entityIdentifier]);
|
||||
|
||||
return (
|
||||
<MenuItem onClick={onToggle} icon={<PiDropHalfBold />} isDisabled={!isInteractable}>
|
||||
<MenuItem onPointerUp={onToggle} icon={<PiDropHalfBold />} isDisabled={!isInteractable}>
|
||||
{withTransparencyEffect
|
||||
? t('controlLayers.disableTransparencyEffect')
|
||||
: t('controlLayers.enableTransparencyEffect')}
|
||||
|
||||
@@ -109,7 +109,7 @@ const FilterContent = memo(
|
||||
<Button
|
||||
variant="ghost"
|
||||
leftIcon={<PiShootingStarBold />}
|
||||
onClick={adapter.filterer.processImmediate}
|
||||
onPointerUp={adapter.filterer.processImmediate}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.filter.process')}
|
||||
isDisabled={!isValid || autoProcessFilter}
|
||||
@@ -119,7 +119,7 @@ const FilterContent = memo(
|
||||
<Spacer />
|
||||
<Button
|
||||
leftIcon={<PiArrowsCounterClockwiseBold />}
|
||||
onClick={adapter.filterer.reset}
|
||||
onPointerUp={adapter.filterer.reset}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.filter.reset')}
|
||||
variant="ghost"
|
||||
@@ -129,7 +129,7 @@ const FilterContent = memo(
|
||||
<Button
|
||||
variant="ghost"
|
||||
leftIcon={<PiCheckBold />}
|
||||
onClick={adapter.filterer.apply}
|
||||
onPointerUp={adapter.filterer.apply}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.filter.apply')}
|
||||
isDisabled={!isValid || !hasProcessed}
|
||||
@@ -139,7 +139,7 @@ const FilterContent = memo(
|
||||
<Button
|
||||
variant="ghost"
|
||||
leftIcon={<PiXBold />}
|
||||
onClick={adapter.filterer.cancel}
|
||||
onPointerUp={adapter.filterer.cancel}
|
||||
loadingText={t('controlLayers.filter.cancel')}
|
||||
>
|
||||
{t('controlLayers.filter.cancel')}
|
||||
|
||||
@@ -60,7 +60,7 @@ export const IPAdapterImagePreview = memo(({ image, onChangeImage, droppableData
|
||||
{controlImage && (
|
||||
<Flex position="absolute" flexDir="column" top={2} insetInlineEnd={2} gap={1}>
|
||||
<IAIDndImageIcon
|
||||
onClick={handleResetControlImage}
|
||||
onPointerUp={handleResetControlImage}
|
||||
icon={<PiArrowCounterClockwiseBold size={16} />}
|
||||
tooltip={t('common.reset')}
|
||||
/>
|
||||
|
||||
@@ -103,7 +103,7 @@ export const IPAdapterSettings = memo(() => {
|
||||
/>
|
||||
</Box>
|
||||
<IconButton
|
||||
onClick={pullBboxIntoIPAdapter}
|
||||
onPointerUp={pullBboxIntoIPAdapter}
|
||||
isDisabled={isBusy}
|
||||
variant="ghost"
|
||||
aria-label={t('controlLayers.pullBboxIntoReferenceImage')}
|
||||
|
||||
@@ -15,7 +15,7 @@ export const RasterLayerMenuItemsConvertRasterToControl = memo(() => {
|
||||
const defaultControlAdapter = useAppSelector(selectDefaultControlAdapter);
|
||||
const isInteractable = useIsEntityInteractable(entityIdentifier);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(
|
||||
rasterLayerConvertedToControlLayer({
|
||||
entityIdentifier,
|
||||
@@ -27,7 +27,7 @@ export const RasterLayerMenuItemsConvertRasterToControl = memo(() => {
|
||||
}, [defaultControlAdapter, dispatch, entityIdentifier]);
|
||||
|
||||
return (
|
||||
<MenuItem onClick={onClick} icon={<PiLightningBold />} isDisabled={!isInteractable}>
|
||||
<MenuItem onPointerUp={onPointerUp} icon={<PiLightningBold />} isDisabled={!isInteractable}>
|
||||
{t('controlLayers.convertToControlLayer')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -30,7 +30,7 @@ export const RegionalGuidanceAddPromptsIPAdapterButtons = () => {
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
leftIcon={<PiPlusBold />}
|
||||
onClick={addRegionalGuidancePositivePrompt}
|
||||
onPointerUp={addRegionalGuidancePositivePrompt}
|
||||
isDisabled={!validActions.canAddPositivePrompt}
|
||||
>
|
||||
{t('controlLayers.prompt')}
|
||||
@@ -39,12 +39,12 @@ export const RegionalGuidanceAddPromptsIPAdapterButtons = () => {
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
leftIcon={<PiPlusBold />}
|
||||
onClick={addRegionalGuidanceNegativePrompt}
|
||||
onPointerUp={addRegionalGuidanceNegativePrompt}
|
||||
isDisabled={!validActions.canAddNegativePrompt}
|
||||
>
|
||||
{t('controlLayers.negativePrompt')}
|
||||
</Button>
|
||||
<Button size="sm" variant="ghost" leftIcon={<PiPlusBold />} onClick={addRegionalGuidanceIPAdapter}>
|
||||
<Button size="sm" variant="ghost" leftIcon={<PiPlusBold />} onPointerUp={addRegionalGuidanceIPAdapter}>
|
||||
{t('controlLayers.referenceImage')}
|
||||
</Button>
|
||||
</Flex>
|
||||
|
||||
@@ -15,7 +15,7 @@ export const RegionalGuidanceDeletePromptButton = memo(({ onDelete }: Props) =>
|
||||
variant="link"
|
||||
aria-label={t('controlLayers.deletePrompt')}
|
||||
icon={<PiTrashSimpleFill />}
|
||||
onClick={onDelete}
|
||||
onPointerUp={onDelete}
|
||||
flexGrow={0}
|
||||
size="sm"
|
||||
p={0}
|
||||
|
||||
@@ -120,7 +120,7 @@ export const RegionalGuidanceIPAdapterSettings = memo(({ referenceImageId }: Pro
|
||||
icon={<PiTrashSimpleFill />}
|
||||
tooltip={t('controlLayers.deleteReferenceImage')}
|
||||
aria-label={t('controlLayers.deleteReferenceImage')}
|
||||
onClick={onDeleteIPAdapter}
|
||||
onPointerUp={onDeleteIPAdapter}
|
||||
colorScheme="error"
|
||||
/>
|
||||
</Flex>
|
||||
@@ -135,7 +135,7 @@ export const RegionalGuidanceIPAdapterSettings = memo(({ referenceImageId }: Pro
|
||||
/>
|
||||
</Box>
|
||||
<IconButton
|
||||
onClick={pullBboxIntoIPAdapter}
|
||||
onPointerUp={pullBboxIntoIPAdapter}
|
||||
isDisabled={isBusy}
|
||||
variant="ghost"
|
||||
aria-label={t('controlLayers.pullBboxIntoReferenceImage')}
|
||||
|
||||
@@ -26,13 +26,13 @@ export const RegionalGuidanceMenuItemsAddPromptsAndIPAdapter = memo(() => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuItem onClick={addRegionalGuidancePositivePrompt} isDisabled={!validActions.canAddPositivePrompt || isBusy}>
|
||||
<MenuItem onPointerUp={addRegionalGuidancePositivePrompt} isDisabled={!validActions.canAddPositivePrompt || isBusy}>
|
||||
{t('controlLayers.addPositivePrompt')}
|
||||
</MenuItem>
|
||||
<MenuItem onClick={addRegionalGuidanceNegativePrompt} isDisabled={!validActions.canAddNegativePrompt || isBusy}>
|
||||
<MenuItem onPointerUp={addRegionalGuidanceNegativePrompt} isDisabled={!validActions.canAddNegativePrompt || isBusy}>
|
||||
{t('controlLayers.addNegativePrompt')}
|
||||
</MenuItem>
|
||||
<MenuItem onClick={addRegionalGuidanceIPAdapter} isDisabled={isBusy}>
|
||||
<MenuItem onPointerUp={addRegionalGuidanceIPAdapter} isDisabled={isBusy}>
|
||||
{t('controlLayers.addReferenceImage')}
|
||||
</MenuItem>
|
||||
</>
|
||||
|
||||
@@ -17,12 +17,12 @@ export const RegionalGuidanceMenuItemsAutoNegative = memo(() => {
|
||||
[entityIdentifier]
|
||||
);
|
||||
const autoNegative = useAppSelector(selectAutoNegative);
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(rgAutoNegativeToggled({ entityIdentifier }));
|
||||
}, [dispatch, entityIdentifier]);
|
||||
|
||||
return (
|
||||
<MenuItem icon={<PiSelectionInverseBold />} onClick={onClick}>
|
||||
<MenuItem icon={<PiSelectionInverseBold />} onPointerUp={onPointerUp}>
|
||||
{autoNegative ? t('controlLayers.disableAutoNegative') : t('controlLayers.enableAutoNegative')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -10,7 +10,7 @@ export const CanvasSettingsClearCachesButton = memo(() => {
|
||||
canvasManager.cache.clearAll();
|
||||
}, [canvasManager]);
|
||||
return (
|
||||
<Button onClick={clearCaches} size="sm" colorScheme="warning">
|
||||
<Button onPointerUp={clearCaches} size="sm" colorScheme="warning">
|
||||
{t('controlLayers.clearCaches')}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -7,11 +7,11 @@ import { useTranslation } from 'react-i18next';
|
||||
export const CanvasSettingsClearHistoryButton = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(canvasClearHistory());
|
||||
}, [dispatch]);
|
||||
return (
|
||||
<Button onClick={onClick} size="sm">
|
||||
<Button onPointerUp={onPointerUp} size="sm">
|
||||
{t('controlLayers.clearHistory')}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -6,11 +6,11 @@ import { useTranslation } from 'react-i18next';
|
||||
export const CanvasSettingsLogDebugInfoButton = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const canvasManager = useCanvasManager();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
canvasManager.logDebugInfo();
|
||||
}, [canvasManager]);
|
||||
return (
|
||||
<Button onClick={onClick} size="sm">
|
||||
<Button onPointerUp={onPointerUp} size="sm">
|
||||
{t('controlLayers.logDebugInfo')}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -6,14 +6,14 @@ import { useTranslation } from 'react-i18next';
|
||||
export const CanvasSettingsRecalculateRectsButton = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const canvasManager = useCanvasManager();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
for (const adapter of canvasManager.getAllAdapters()) {
|
||||
adapter.transformer.requestRectCalculation();
|
||||
}
|
||||
}, [canvasManager]);
|
||||
|
||||
return (
|
||||
<Button onClick={onClick} size="sm" colorScheme="warning">
|
||||
<Button onPointerUp={onPointerUp} size="sm" colorScheme="warning">
|
||||
{t('controlLayers.recalculateRects')}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -60,7 +60,7 @@ export const StagingAreaToolbarAcceptButton = memo(() => {
|
||||
tooltip={`${t('common.accept')} (Enter)`}
|
||||
aria-label={`${t('common.accept')} (Enter)`}
|
||||
icon={<PiCheckBold />}
|
||||
onClick={acceptSelected}
|
||||
onPointerUp={acceptSelected}
|
||||
colorScheme="invokeBlue"
|
||||
isDisabled={!selectedImage}
|
||||
/>
|
||||
|
||||
@@ -18,7 +18,7 @@ export const StagingAreaToolbarDiscardAllButton = memo(() => {
|
||||
tooltip={`${t('controlLayers.stagingArea.discardAll')} (Esc)`}
|
||||
aria-label={t('controlLayers.stagingArea.discardAll')}
|
||||
icon={<PiTrashSimpleBold />}
|
||||
onClick={discardAll}
|
||||
onPointerUp={discardAll}
|
||||
colorScheme="error"
|
||||
fontSize={16}
|
||||
/>
|
||||
|
||||
@@ -35,7 +35,7 @@ export const StagingAreaToolbarDiscardSelectedButton = memo(() => {
|
||||
tooltip={t('controlLayers.stagingArea.discard')}
|
||||
aria-label={t('controlLayers.stagingArea.discard')}
|
||||
icon={<PiXBold />}
|
||||
onClick={discardSelected}
|
||||
onPointerUp={discardSelected}
|
||||
colorScheme="invokeBlue"
|
||||
fontSize={16}
|
||||
isDisabled={!selectedImage}
|
||||
|
||||
@@ -40,7 +40,7 @@ export const StagingAreaToolbarNextButton = memo(() => {
|
||||
tooltip={`${t('controlLayers.stagingArea.next')} (Right)`}
|
||||
aria-label={`${t('controlLayers.stagingArea.next')} (Right)`}
|
||||
icon={<PiArrowRightBold />}
|
||||
onClick={selectNext}
|
||||
onPointerUp={selectNext}
|
||||
colorScheme="invokeBlue"
|
||||
isDisabled={imageCount <= 1 || !shouldShowStagedImage}
|
||||
/>
|
||||
|
||||
@@ -40,7 +40,7 @@ export const StagingAreaToolbarPrevButton = memo(() => {
|
||||
tooltip={`${t('controlLayers.stagingArea.previous')} (Left)`}
|
||||
aria-label={`${t('controlLayers.stagingArea.previous')} (Left)`}
|
||||
icon={<PiArrowLeftBold />}
|
||||
onClick={selectPrev}
|
||||
onPointerUp={selectPrev}
|
||||
colorScheme="invokeBlue"
|
||||
isDisabled={imageCount <= 1 || !shouldShowStagedImage}
|
||||
/>
|
||||
|
||||
@@ -40,7 +40,7 @@ export const StagingAreaToolbarSaveSelectedToGalleryButton = memo(() => {
|
||||
tooltip={t('controlLayers.stagingArea.saveToGallery')}
|
||||
aria-label={t('controlLayers.stagingArea.saveToGallery')}
|
||||
icon={<PiFloppyDiskBold />}
|
||||
onClick={saveSelectedImageToGallery}
|
||||
onPointerUp={saveSelectedImageToGallery}
|
||||
colorScheme="invokeBlue"
|
||||
isDisabled={!selectedImage || !selectedImage.imageDTO.is_intermediate}
|
||||
/>
|
||||
|
||||
@@ -29,7 +29,7 @@ export const StagingAreaToolbarToggleShowResultsButton = memo(() => {
|
||||
}
|
||||
data-alert={!shouldShowStagedImage}
|
||||
icon={shouldShowStagedImage ? <PiEyeBold /> : <PiEyeSlashBold />}
|
||||
onClick={toggleShowResults}
|
||||
onPointerUp={toggleShowResults}
|
||||
colorScheme="invokeBlue"
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ToolBboxButton = memo(() => {
|
||||
icon={<PiBoundingBoxBold />}
|
||||
colorScheme={isSelected ? 'invokeBlue' : 'base'}
|
||||
variant="solid"
|
||||
onClick={selectBbox}
|
||||
onPointerUp={selectBbox}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ToolBrushButton = memo(() => {
|
||||
icon={<PiPaintBrushBold />}
|
||||
colorScheme={isSelected ? 'invokeBlue' : 'base'}
|
||||
variant="solid"
|
||||
onClick={selectBrush}
|
||||
onPointerUp={selectBrush}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ToolColorPickerButton = memo(() => {
|
||||
icon={<PiEyedropperBold />}
|
||||
colorScheme={isSelected ? 'invokeBlue' : 'base'}
|
||||
variant="solid"
|
||||
onClick={selectColorPicker}
|
||||
onPointerUp={selectColorPicker}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ToolEraserButton = memo(() => {
|
||||
icon={<PiEraserBold />}
|
||||
colorScheme={isSelected ? 'invokeBlue' : 'base'}
|
||||
variant="solid"
|
||||
onClick={selectEraser}
|
||||
onPointerUp={selectEraser}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ToolMoveButton = memo(() => {
|
||||
icon={<PiCursorBold />}
|
||||
colorScheme={isSelected ? 'invokeBlue' : 'base'}
|
||||
variant="solid"
|
||||
onClick={selectMove}
|
||||
onPointerUp={selectMove}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ToolRectButton = memo(() => {
|
||||
icon={<PiRectangleBold />}
|
||||
colorScheme={isSelected ? 'invokeBlue' : 'base'}
|
||||
variant="solid"
|
||||
onClick={selectRect}
|
||||
onPointerUp={selectRect}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ToolViewButton = memo(() => {
|
||||
icon={<PiHandBold />}
|
||||
colorScheme={isSelected ? 'invokeBlue' : 'base'}
|
||||
variant="solid"
|
||||
onClick={selectView}
|
||||
onPointerUp={selectView}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -9,13 +9,13 @@ export const CanvasToolbarFitBboxToLayersButton = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const canvasManager = useCanvasManager();
|
||||
const isBusy = useCanvasIsBusy();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
canvasManager.bbox.fitToLayers();
|
||||
}, [canvasManager.bbox]);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
aria-label={t('controlLayers.fitBboxToLayers')}
|
||||
|
||||
@@ -12,7 +12,7 @@ export const CanvasToolbarRedoButton = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const isBusy = useCanvasIsBusy();
|
||||
const mayRedo = useAppSelector(selectCanvasMayRedo);
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(canvasRedo());
|
||||
}, [dispatch]);
|
||||
|
||||
@@ -20,7 +20,7 @@ export const CanvasToolbarRedoButton = memo(() => {
|
||||
<IconButton
|
||||
aria-label={t('hotkeys.canvas.redo.title')}
|
||||
tooltip={t('hotkeys.canvas.redo.title')}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
icon={<PiArrowClockwiseBold />}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
|
||||
@@ -10,7 +10,7 @@ export const CanvasToolbarResetCanvasButton = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const canvasManager = useCanvasManager();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(canvasReset());
|
||||
canvasManager.stage.fitLayersToStage();
|
||||
}, [canvasManager.stage, dispatch]);
|
||||
@@ -18,7 +18,7 @@ export const CanvasToolbarResetCanvasButton = memo(() => {
|
||||
<IconButton
|
||||
aria-label={t('controlLayers.resetCanvas')}
|
||||
tooltip={t('controlLayers.resetCanvas')}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
colorScheme="error"
|
||||
icon={<PiTrashBold />}
|
||||
variant="link"
|
||||
|
||||
@@ -60,7 +60,7 @@ export const CanvasToolbarResetViewButton = memo(() => {
|
||||
<IconButton
|
||||
tooltip={t('hotkeys.canvas.fitLayersToCanvas.title')}
|
||||
aria-label={t('hotkeys.canvas.fitLayersToCanvas.title')}
|
||||
onClick={canvasManager.stage.fitLayersToStage}
|
||||
onPointerUp={canvasManager.stage.fitLayersToStage}
|
||||
icon={<PiArrowsOutBold />}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
|
||||
@@ -16,7 +16,7 @@ export const CanvasToolbarSaveToGalleryButton = memo(() => {
|
||||
<IconButton
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={shift ? saveBboxToGallery : saveCanvasToGallery}
|
||||
onPointerUp={shift ? saveBboxToGallery : saveCanvasToGallery}
|
||||
icon={<PiFloppyDiskBold />}
|
||||
aria-label={shift ? t('controlLayers.saveBboxToGallery') : t('controlLayers.saveCanvasToGallery')}
|
||||
tooltip={shift ? t('controlLayers.saveBboxToGallery') : t('controlLayers.saveCanvasToGallery')}
|
||||
|
||||
@@ -174,7 +174,7 @@ const SCALE_SNAPS = [0.1, 0.15, 0.2, 0.25, 0.5, 0.75, 1, 1.5, 2, 2.5, 5, 7.5, 10
|
||||
const ZoomOutButton = () => {
|
||||
const canvasManager = useCanvasManager();
|
||||
const scale = useStore(computed(canvasManager.stage.$stageAttrs, (attrs) => attrs.scale));
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
const nextScale =
|
||||
SCALE_SNAPS.slice()
|
||||
.reverse()
|
||||
@@ -184,7 +184,7 @@ const ZoomOutButton = () => {
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
icon={<PiMagnifyingGlassMinusBold />}
|
||||
aria-label="Zoom out"
|
||||
variant="link"
|
||||
@@ -197,14 +197,14 @@ const ZoomOutButton = () => {
|
||||
const ZoomInButton = () => {
|
||||
const canvasManager = useCanvasManager();
|
||||
const scale = useStore(computed(canvasManager.stage.$stageAttrs, (attrs) => attrs.scale));
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
const nextScale = SCALE_SNAPS.find((snap) => snap > scale) ?? canvasManager.stage.config.MAX_SCALE;
|
||||
canvasManager.stage.setScale(Math.min(nextScale, canvasManager.stage.config.MAX_SCALE));
|
||||
}, [canvasManager.stage, scale]);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
icon={<PiMagnifyingGlassPlusBold />}
|
||||
aria-label="Zoom out"
|
||||
variant="link"
|
||||
|
||||
@@ -12,7 +12,7 @@ export const CanvasToolbarUndoButton = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const isBusy = useCanvasIsBusy();
|
||||
const mayUndo = useAppSelector(selectCanvasMayUndo);
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(canvasUndo());
|
||||
}, [dispatch]);
|
||||
|
||||
@@ -20,7 +20,7 @@ export const CanvasToolbarUndoButton = memo(() => {
|
||||
<IconButton
|
||||
aria-label={t('hotkeys.canvas.undo.title')}
|
||||
tooltip={t('hotkeys.canvas.undo.title')}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
icon={<PiArrowCounterClockwiseBold />}
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
|
||||
@@ -68,7 +68,7 @@ const TransformContent = memo(({ adapter }: { adapter: CanvasEntityAdapter }) =>
|
||||
<ButtonGroup isAttached={false} size="sm" w="full">
|
||||
<Button
|
||||
leftIcon={<PiArrowsOutBold />}
|
||||
onClick={adapter.transformer.fitProxyRectToBbox}
|
||||
onPointerUp={adapter.transformer.fitProxyRectToBbox}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.transform.fitToBbox')}
|
||||
variant="ghost"
|
||||
@@ -78,7 +78,7 @@ const TransformContent = memo(({ adapter }: { adapter: CanvasEntityAdapter }) =>
|
||||
<Spacer />
|
||||
<Button
|
||||
leftIcon={<PiArrowsCounterClockwiseBold />}
|
||||
onClick={adapter.transformer.resetTransform}
|
||||
onPointerUp={adapter.transformer.resetTransform}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.transform.reset')}
|
||||
variant="ghost"
|
||||
@@ -87,7 +87,7 @@ const TransformContent = memo(({ adapter }: { adapter: CanvasEntityAdapter }) =>
|
||||
</Button>
|
||||
<Button
|
||||
leftIcon={<PiCheckBold />}
|
||||
onClick={adapter.transformer.applyTransform}
|
||||
onPointerUp={adapter.transformer.applyTransform}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.transform.apply')}
|
||||
variant="ghost"
|
||||
@@ -96,7 +96,7 @@ const TransformContent = memo(({ adapter }: { adapter: CanvasEntityAdapter }) =>
|
||||
</Button>
|
||||
<Button
|
||||
leftIcon={<PiXBold />}
|
||||
onClick={adapter.transformer.stopTransform}
|
||||
onPointerUp={adapter.transformer.stopTransform}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('common.cancel')}
|
||||
variant="ghost"
|
||||
|
||||
@@ -25,7 +25,7 @@ export const CanvasEntityAddOfTypeButton = memo(({ type }: Props) => {
|
||||
const addControlLayer = useAddControlLayer();
|
||||
const addGlobalReferenceImage = useAddGlobalReferenceImage();
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
switch (type) {
|
||||
case 'inpaint_mask':
|
||||
addInpaintMask();
|
||||
@@ -67,7 +67,7 @@ export const CanvasEntityAddOfTypeButton = memo(({ type }: Props) => {
|
||||
tooltip={label}
|
||||
variant="link"
|
||||
icon={<NewLayerIcon />}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
alignSelf="stretch"
|
||||
isDisabled={isBusy}
|
||||
/>
|
||||
|
||||
@@ -12,7 +12,7 @@ export const CanvasEntityContainer = memo((props: PropsWithChildren) => {
|
||||
const entityIdentifier = useEntityIdentifierContext();
|
||||
const isSelected = useEntityIsSelected(entityIdentifier);
|
||||
const selectionColor = useEntitySelectionColor(entityIdentifier);
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
if (isSelected) {
|
||||
return;
|
||||
}
|
||||
@@ -25,7 +25,7 @@ export const CanvasEntityContainer = memo((props: PropsWithChildren) => {
|
||||
flexDir="column"
|
||||
w="full"
|
||||
bg={isSelected ? 'base.800' : 'base.850'}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
borderInlineStartWidth={5}
|
||||
borderColor={isSelected ? selectionColor : 'base.800'}
|
||||
borderRadius="base"
|
||||
|
||||
@@ -12,7 +12,7 @@ export const CanvasEntityDeleteButton = memo(() => {
|
||||
const entityIdentifier = useEntityIdentifierContext();
|
||||
const dispatch = useAppDispatch();
|
||||
const isBusy = useCanvasIsBusy();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(entityDeleted({ entityIdentifier }));
|
||||
}, [dispatch, entityIdentifier]);
|
||||
|
||||
@@ -24,7 +24,7 @@ export const CanvasEntityDeleteButton = memo(() => {
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
icon={<PiTrashSimpleFill />}
|
||||
onPointerUp={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
colorScheme="error"
|
||||
isDisabled={isBusy}
|
||||
/>
|
||||
|
||||
@@ -14,7 +14,7 @@ export const CanvasEntityEnabledToggle = memo(() => {
|
||||
const isEnabled = useEntityIsEnabled(entityIdentifier);
|
||||
const isBusy = useCanvasIsBusy();
|
||||
const dispatch = useAppDispatch();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(entityIsEnabledToggled({ entityIdentifier }));
|
||||
}, [dispatch, entityIdentifier]);
|
||||
|
||||
@@ -26,7 +26,7 @@ export const CanvasEntityEnabledToggle = memo(() => {
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
icon={isEnabled ? <PiCircleFill /> : <PiCircleBold />}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
isDisabled={isBusy}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ export const CanvasEntityGroupList = memo(({ isSelected, type, children }: Props
|
||||
<Flex
|
||||
flexGrow={1}
|
||||
as={Button}
|
||||
onClick={collapse.toggle}
|
||||
onPointerUp={collapse.toggle}
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
gap={3}
|
||||
|
||||
@@ -12,7 +12,7 @@ export const CanvasEntityIsBookmarkedForQuickSwitchToggle = memo(() => {
|
||||
const entityIdentifier = useEntityIdentifierContext();
|
||||
const isBookmarked = useEntityIsBookmarkedForQuickSwitch(entityIdentifier);
|
||||
const dispatch = useAppDispatch();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
if (isBookmarked) {
|
||||
dispatch(bookmarkedEntityChanged({ entityIdentifier: null }));
|
||||
} else {
|
||||
@@ -28,7 +28,7 @@ export const CanvasEntityIsBookmarkedForQuickSwitchToggle = memo(() => {
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
icon={isBookmarked ? <PiBookmarkSimpleFill /> : <PiBookmarkSimpleBold />}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ export const CanvasEntityIsLockedToggle = memo(() => {
|
||||
const isLocked = useEntityIsLocked(entityIdentifier);
|
||||
const isBusy = useCanvasIsBusy();
|
||||
const dispatch = useAppDispatch();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(entityIsLockedToggled({ entityIdentifier }));
|
||||
}, [dispatch, entityIdentifier]);
|
||||
|
||||
@@ -26,7 +26,7 @@ export const CanvasEntityIsLockedToggle = memo(() => {
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
icon={isLocked ? <PiLockSimpleFill /> : <PiLockSimpleOpenBold />}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
isDisabled={isBusy}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -89,28 +89,28 @@ export const CanvasEntityMenuItemsArrange = memo(() => {
|
||||
return (
|
||||
<>
|
||||
<MenuItem
|
||||
onClick={moveToFront}
|
||||
onPointerUp={moveToFront}
|
||||
isDisabled={!validActions.canMoveToFront || !isInteractable}
|
||||
icon={<PiArrowLineUpBold />}
|
||||
>
|
||||
{t('controlLayers.moveToFront')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={moveForwardOne}
|
||||
onPointerUp={moveForwardOne}
|
||||
isDisabled={!validActions.canMoveForwardOne || !isInteractable}
|
||||
icon={<PiArrowUpBold />}
|
||||
>
|
||||
{t('controlLayers.moveForward')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={moveBackwardOne}
|
||||
onPointerUp={moveBackwardOne}
|
||||
isDisabled={!validActions.canMoveBackwardOne || !isInteractable}
|
||||
icon={<PiArrowDownBold />}
|
||||
>
|
||||
{t('controlLayers.moveBackward')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={moveToBack}
|
||||
onPointerUp={moveToBack}
|
||||
isDisabled={!validActions.canMoveToBack || !isInteractable}
|
||||
icon={<PiArrowLineDownBold />}
|
||||
>
|
||||
|
||||
@@ -14,12 +14,12 @@ export const CanvasEntityMenuItemsCopyToClipboard = memo(() => {
|
||||
const isInteractable = useIsEntityInteractable(entityIdentifier);
|
||||
const copyLayerToClipboard = useCopyLayerToClipboard();
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
copyLayerToClipboard(adapter);
|
||||
}, [copyLayerToClipboard, adapter]);
|
||||
|
||||
return (
|
||||
<MenuItem onClick={onClick} icon={<PiCopyBold />} isDisabled={!isInteractable}>
|
||||
<MenuItem onPointerUp={onPointerUp} icon={<PiCopyBold />} isDisabled={!isInteractable}>
|
||||
{t('controlLayers.copyToClipboard')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ export const CanvasEntityMenuItemsCropToBbox = memo(() => {
|
||||
const entityIdentifier = useEntityIdentifierContext();
|
||||
const adapter = useEntityAdapterSafe(entityIdentifier);
|
||||
const isInteractable = useIsEntityInteractable(entityIdentifier);
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
if (!adapter) {
|
||||
return;
|
||||
}
|
||||
@@ -19,7 +19,7 @@ export const CanvasEntityMenuItemsCropToBbox = memo(() => {
|
||||
}, [adapter]);
|
||||
|
||||
return (
|
||||
<MenuItem onClick={onClick} icon={<PiCropBold />} isDisabled={!isInteractable}>
|
||||
<MenuItem onPointerUp={onPointerUp} icon={<PiCropBold />} isDisabled={!isInteractable}>
|
||||
{t('controlLayers.cropLayerToBbox')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -18,7 +18,7 @@ export const CanvasEntityMenuItemsDelete = memo(() => {
|
||||
}, [dispatch, entityIdentifier]);
|
||||
|
||||
return (
|
||||
<MenuItem onClick={deleteEntity} icon={<PiTrashSimpleBold />} isDestructive isDisabled={!isInteractable}>
|
||||
<MenuItem onPointerUp={deleteEntity} icon={<PiTrashSimpleBold />} isDestructive isDisabled={!isInteractable}>
|
||||
{t('common.delete')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -13,12 +13,12 @@ export const CanvasEntityMenuItemsDuplicate = memo(() => {
|
||||
const entityIdentifier = useEntityIdentifierContext();
|
||||
const isInteractable = useIsEntityInteractable(entityIdentifier);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(entityDuplicated({ entityIdentifier }));
|
||||
}, [dispatch, entityIdentifier]);
|
||||
|
||||
return (
|
||||
<MenuItem onClick={onClick} icon={<PiCopyFill />} isDisabled={!isInteractable}>
|
||||
<MenuItem onPointerUp={onPointerUp} icon={<PiCopyFill />} isDisabled={!isInteractable}>
|
||||
{t('controlLayers.duplicate')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ export const CanvasEntityMenuItemsFilter = memo(() => {
|
||||
const filter = useEntityFilter(entityIdentifier);
|
||||
|
||||
return (
|
||||
<MenuItem onClick={filter.start} icon={<PiShootingStarBold />} isDisabled={filter.isDisabled}>
|
||||
<MenuItem onPointerUp={filter.start} icon={<PiShootingStarBold />} isDisabled={filter.isDisabled}>
|
||||
{t('controlLayers.filter.filter')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -13,12 +13,12 @@ export const CanvasEntityMenuItemsSave = memo(() => {
|
||||
const adapter = useEntityAdapterSafe(entityIdentifier);
|
||||
const isInteractable = useIsEntityInteractable(entityIdentifier);
|
||||
const saveLayerToAssets = useSaveLayerToAssets();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
saveLayerToAssets(adapter);
|
||||
}, [saveLayerToAssets, adapter]);
|
||||
|
||||
return (
|
||||
<MenuItem onClick={onClick} icon={<PiFloppyDiskBold />} isDisabled={!isInteractable}>
|
||||
<MenuItem onPointerUp={onPointerUp} icon={<PiFloppyDiskBold />} isDisabled={!isInteractable}>
|
||||
{t('controlLayers.saveLayerToAssets')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ export const CanvasEntityMenuItemsTransform = memo(() => {
|
||||
const transform = useEntityTransform(entityIdentifier);
|
||||
|
||||
return (
|
||||
<MenuItem onClick={transform.start} icon={<PiFrameCornersBold />} isDisabled={transform.isDisabled}>
|
||||
<MenuItem onPointerUp={transform.start} icon={<PiFrameCornersBold />} isDisabled={transform.isDisabled}>
|
||||
{t('controlLayers.transform.transform')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -26,7 +26,7 @@ export const CanvasEntityMergeVisibleButton = memo(({ type }: Props) => {
|
||||
const canvasManager = useCanvasManager();
|
||||
const isBusy = useCanvasIsBusy();
|
||||
const entityCount = useEntityTypeCount(type);
|
||||
const onClick = useCallback(async () => {
|
||||
const onPointerUp = useCallback(async () => {
|
||||
if (type === 'raster_layer') {
|
||||
const rect = canvasManager.stage.getVisibleRect('raster_layer');
|
||||
const result = await withResultAsync(() =>
|
||||
@@ -83,7 +83,7 @@ export const CanvasEntityMergeVisibleButton = memo(({ type }: Props) => {
|
||||
tooltip={t('controlLayers.mergeVisible')}
|
||||
variant="link"
|
||||
icon={<PiStackBold />}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
alignSelf="stretch"
|
||||
isDisabled={entityCount <= 1 || isBusy}
|
||||
/>
|
||||
|
||||
@@ -18,7 +18,7 @@ export const CanvasEntityTypeIsHiddenToggle = memo(({ type }: Props) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const isHidden = useEntityTypeIsHidden(type);
|
||||
const typeString = useEntityTypeString(type, true);
|
||||
const onClick = useCallback<MouseEventHandler>(
|
||||
const onPointerUp = useCallback<MouseEventHandler>(
|
||||
(e) => {
|
||||
e.stopPropagation();
|
||||
dispatch(allEntitiesOfTypeIsHiddenToggled({ type }));
|
||||
@@ -33,7 +33,7 @@ export const CanvasEntityTypeIsHiddenToggle = memo(({ type }: Props) => {
|
||||
tooltip={t(isHidden ? 'controlLayers.hidingType' : 'controlLayers.showingType', { type: typeString })}
|
||||
variant="link"
|
||||
icon={isHidden ? <PiEyeClosedBold /> : <PiEyeBold />}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
alignSelf="stretch"
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -9,11 +9,11 @@ import { PiTrashSimpleBold } from 'react-icons/pi';
|
||||
import { $isConnected } from 'services/events/stores';
|
||||
|
||||
type DeleteImageButtonProps = Omit<IconButtonProps, 'aria-label'> & {
|
||||
onClick: () => void;
|
||||
onPointerUp: () => void;
|
||||
};
|
||||
|
||||
export const DeleteImageButton = memo((props: DeleteImageButtonProps) => {
|
||||
const { onClick, isDisabled } = props;
|
||||
const { onPointerUp, isDisabled } = props;
|
||||
const { t } = useTranslation();
|
||||
const isConnected = useStore($isConnected);
|
||||
const imageSelectionLength = useAppSelector(selectSelectionCount);
|
||||
@@ -21,7 +21,7 @@ export const DeleteImageButton = memo((props: DeleteImageButtonProps) => {
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
icon={<PiTrashSimpleBold />}
|
||||
tooltip={labelMessage}
|
||||
aria-label={labelMessage}
|
||||
|
||||
@@ -28,7 +28,7 @@ export const ShowDynamicPromptsPreviewButton = memo(() => {
|
||||
isDisabled={isOpen}
|
||||
aria-label={t('dynamicPrompts.showDynamicPrompts')}
|
||||
icon={<PiBracketsCurlyBold />}
|
||||
onClick={onOpen}
|
||||
onPointerUp={onOpen}
|
||||
sx={isLoading ? loadingStyles : undefined}
|
||||
colorScheme={isError && !isLoading ? 'error' : 'base'}
|
||||
/>
|
||||
|
||||
@@ -75,29 +75,29 @@ const BoardContextMenu = ({ board, children }: Props) => {
|
||||
<MenuList visibility="visible">
|
||||
<MenuGroup title={boardName}>
|
||||
{!autoAssignBoardOnClick && (
|
||||
<MenuItem icon={<PiPlusBold />} isDisabled={isSelectedForAutoAdd} onClick={handleSetAutoAdd}>
|
||||
<MenuItem icon={<PiPlusBold />} isDisabled={isSelectedForAutoAdd} onPointerUp={handleSetAutoAdd}>
|
||||
{isSelectedForAutoAdd ? t('boards.selectedForAutoAdd') : t('boards.menuItemAutoAdd')}
|
||||
</MenuItem>
|
||||
)}
|
||||
{isBulkDownloadEnabled && (
|
||||
<MenuItem icon={<PiDownloadBold />} onClickCapture={handleBulkDownload}>
|
||||
<MenuItem icon={<PiDownloadBold />} onPointerUpCapture={handleBulkDownload}>
|
||||
{t('boards.downloadBoard')}
|
||||
</MenuItem>
|
||||
)}
|
||||
|
||||
{board.archived && (
|
||||
<MenuItem icon={<PiArchiveBold />} onClick={handleUnarchive}>
|
||||
<MenuItem icon={<PiArchiveBold />} onPointerUp={handleUnarchive}>
|
||||
{t('boards.unarchiveBoard')}
|
||||
</MenuItem>
|
||||
)}
|
||||
|
||||
{!board.archived && (
|
||||
<MenuItem icon={<PiArchiveFill />} onClick={handleArchive}>
|
||||
<MenuItem icon={<PiArchiveFill />} onPointerUp={handleArchive}>
|
||||
{t('boards.archiveBoard')}
|
||||
</MenuItem>
|
||||
)}
|
||||
|
||||
<MenuItem color="error.300" icon={<PiTrashSimpleBold />} onClick={setAsBoardToDelete} isDestructive>
|
||||
<MenuItem color="error.300" icon={<PiTrashSimpleBold />} onPointerUp={setAsBoardToDelete} isDestructive>
|
||||
{t('boards.deleteBoard')}
|
||||
</MenuItem>
|
||||
</MenuGroup>
|
||||
|
||||
@@ -42,7 +42,7 @@ const AddBoardButton = ({ isPrivateBoard }: Props) => {
|
||||
isLoading={isLoading}
|
||||
tooltip={label}
|
||||
aria-label={label}
|
||||
onClick={handleCreateBoard}
|
||||
onPointerUp={handleCreateBoard}
|
||||
size="md"
|
||||
data-testid="add-board-button"
|
||||
variant="link"
|
||||
|
||||
@@ -84,7 +84,7 @@ export const BoardsList = ({ isPrivate }: Props) => {
|
||||
bg="base.900"
|
||||
>
|
||||
{allowPrivateBoards ? (
|
||||
<Button variant="unstyled" onClick={onToggle}>
|
||||
<Button variant="unstyled" onPointerUp={onToggle}>
|
||||
<Flex gap="2" alignItems="center">
|
||||
<Icon
|
||||
boxSize={4}
|
||||
|
||||
@@ -52,7 +52,7 @@ const BoardsSearch = () => {
|
||||
{boardSearchText && boardSearchText.length && (
|
||||
<InputRightElement h="full" pe={2}>
|
||||
<IconButton
|
||||
onClick={clearBoardSearch}
|
||||
onPointerUp={clearBoardSearch}
|
||||
size="sm"
|
||||
variant="link"
|
||||
aria-label={t('boards.clearSearch')}
|
||||
|
||||
@@ -60,7 +60,7 @@ const GalleryBoard = ({ board, isSelected }: GalleryBoardProps) => {
|
||||
const [localBoardName, setLocalBoardName] = useState(board.board_name);
|
||||
const onStartEditingRef = useRef<MouseEventHandler | undefined>(undefined);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
if (selectedBoardId !== board.board_id) {
|
||||
dispatch(boardIdSelected({ boardId: board.board_id }));
|
||||
}
|
||||
@@ -123,7 +123,7 @@ const GalleryBoard = ({ board, isSelected }: GalleryBoardProps) => {
|
||||
<Flex
|
||||
position="relative"
|
||||
ref={ref}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
onDoubleClick={onDoubleClick}
|
||||
w="full"
|
||||
alignItems="center"
|
||||
@@ -180,7 +180,7 @@ const GalleryBoard = ({ board, isSelected }: GalleryBoardProps) => {
|
||||
const JankEditableHijack = memo((props: { onStartEditingRef: MutableRefObject<MouseEventHandler | undefined> }) => {
|
||||
const editableControls = useEditableControls();
|
||||
useEffect(() => {
|
||||
props.onStartEditingRef.current = editableControls.getEditButtonProps().onClick;
|
||||
props.onStartEditingRef.current = editableControls.getEditButtonProps().onPointerUp;
|
||||
}, [props, editableControls]);
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -64,7 +64,7 @@ const NoBoardBoard = memo(({ isSelected }: Props) => {
|
||||
<Flex
|
||||
position="relative"
|
||||
ref={ref}
|
||||
onClick={handleSelectBoard}
|
||||
onPointerUp={handleSelectBoard}
|
||||
w="full"
|
||||
alignItems="center"
|
||||
borderRadius="base"
|
||||
|
||||
@@ -127,13 +127,13 @@ const DeleteBoardModal = () => {
|
||||
</AlertDialogBody>
|
||||
<AlertDialogFooter>
|
||||
<Flex w="full" gap={2} justifyContent="end">
|
||||
<Button ref={cancelRef} onClick={handleClose}>
|
||||
<Button ref={cancelRef} onPointerUp={handleClose}>
|
||||
{t('boards.cancel')}
|
||||
</Button>
|
||||
<Button colorScheme="warning" isLoading={isLoading} onClick={handleDeleteBoardOnly}>
|
||||
<Button colorScheme="warning" isLoading={isLoading} onPointerUp={handleDeleteBoardOnly}>
|
||||
{t('boards.deleteBoardOnly')}
|
||||
</Button>
|
||||
<Button colorScheme="error" isLoading={isLoading} onClick={handleDeleteBoardAndImages}>
|
||||
<Button colorScheme="error" isLoading={isLoading} onPointerUp={handleDeleteBoardAndImages}>
|
||||
{t('boards.deleteBoardAndImages')}
|
||||
</Button>
|
||||
</Flex>
|
||||
|
||||
@@ -38,12 +38,12 @@ const NoBoardBoardContextMenu = ({ children }: Props) => {
|
||||
<MenuList visibility="visible">
|
||||
<MenuGroup title={t('boards.uncategorized')}>
|
||||
{!autoAssignBoardOnClick && (
|
||||
<MenuItem icon={<PiPlusBold />} isDisabled={isSelectedForAutoAdd} onClick={handleSetAutoAdd}>
|
||||
<MenuItem icon={<PiPlusBold />} isDisabled={isSelectedForAutoAdd} onPointerUp={handleSetAutoAdd}>
|
||||
{isSelectedForAutoAdd ? t('boards.selectedForAutoAdd') : t('boards.menuItemAutoAdd')}
|
||||
</MenuItem>
|
||||
)}
|
||||
{isBulkDownloadEnabled && (
|
||||
<MenuItem icon={<PiDownloadBold />} onClickCapture={handleBulkDownload}>
|
||||
<MenuItem icon={<PiDownloadBold />} onPointerUpCapture={handleBulkDownload}>
|
||||
{t('boards.downloadBoard')}
|
||||
</MenuItem>
|
||||
)}
|
||||
|
||||
@@ -74,17 +74,17 @@ export const Gallery = () => {
|
||||
{boardName}
|
||||
</Text>
|
||||
<Spacer />
|
||||
<Tab sx={BASE_STYLES} _selected={SELECTED_STYLES} onClick={handleClickImages} data-testid="images-tab">
|
||||
<Tab sx={BASE_STYLES} _selected={SELECTED_STYLES} onPointerUp={handleClickImages} data-testid="images-tab">
|
||||
{t('parameters.images')}
|
||||
</Tab>
|
||||
<Tab sx={BASE_STYLES} _selected={SELECTED_STYLES} onClick={handleClickAssets} data-testid="assets-tab">
|
||||
<Tab sx={BASE_STYLES} _selected={SELECTED_STYLES} onPointerUp={handleClickAssets} data-testid="assets-tab">
|
||||
{t('gallery.assets')}
|
||||
</Tab>
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={handleClickSearch}
|
||||
onPointerUp={handleClickSearch}
|
||||
tooltip={searchDisclosure.isOpen ? `${t('gallery.exitSearch')}` : `${t('gallery.displaySearch')}`}
|
||||
aria-label={t('gallery.displaySearch')}
|
||||
icon={<PiMagnifyingGlassBold />}
|
||||
|
||||
@@ -56,7 +56,7 @@ const GalleryPanelContent = () => {
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
onClick={boardsListPanel.toggle}
|
||||
onPointerUp={boardsListPanel.toggle}
|
||||
rightIcon={boardsListPanel.isCollapsed ? <PiCaretDownBold /> : <PiCaretUpBold />}
|
||||
>
|
||||
{boardsListPanel.isCollapsed ? t('boards.viewBoards') : t('boards.hideBoards')}
|
||||
@@ -69,7 +69,7 @@ const GalleryPanelContent = () => {
|
||||
size="sm"
|
||||
variant="link"
|
||||
alignSelf="stretch"
|
||||
onClick={handleClickBoardSearch}
|
||||
onPointerUp={handleClickBoardSearch}
|
||||
tooltip={
|
||||
boardSearchDisclosure.isOpen ? `${t('gallery.exitBoardSearch')}` : `${t('gallery.displayBoardSearch')}`
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ export const ImageMenuItemChangeBoard = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const imageDTO = useImageDTOContext();
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(imagesToChangeSelected([imageDTO]));
|
||||
dispatch(isModalOpenChanged(true));
|
||||
}, [dispatch, imageDTO]);
|
||||
|
||||
return (
|
||||
<MenuItem icon={<PiFoldersBold />} onClickCapture={onClick}>
|
||||
<MenuItem icon={<PiFoldersBold />} onPointerUpCapture={onPointerUp}>
|
||||
{t('boards.changeBoard')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -10,7 +10,7 @@ export const ImageMenuItemCopy = memo(() => {
|
||||
const imageDTO = useImageDTOContext();
|
||||
const { isClipboardAPIAvailable, copyImageToClipboard } = useCopyImageToClipboard();
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
copyImageToClipboard(imageDTO.image_url);
|
||||
}, [copyImageToClipboard, imageDTO.image_url]);
|
||||
|
||||
@@ -23,7 +23,7 @@ export const ImageMenuItemCopy = memo(() => {
|
||||
icon={<PiCopyBold />}
|
||||
aria-label={t('parameters.copyImage')}
|
||||
tooltip={t('parameters.copyImage')}
|
||||
onClickCapture={onClick}
|
||||
onPointerUpCapture={onPointerUp}
|
||||
variant="ghost"
|
||||
colorScheme="base"
|
||||
/>
|
||||
|
||||
@@ -11,14 +11,14 @@ export const ImageMenuItemDelete = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const imageDTO = useImageDTOContext();
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(imagesToDeleteSelected([imageDTO]));
|
||||
}, [dispatch, imageDTO]);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
icon={<PiTrashSimpleBold />}
|
||||
onClickCapture={onClick}
|
||||
onPointerUpCapture={onPointerUp}
|
||||
aria-label={t('gallery.deleteImage', { count: 1 })}
|
||||
tooltip={t('gallery.deleteImage', { count: 1 })}
|
||||
variant="ghost"
|
||||
|
||||
@@ -10,7 +10,7 @@ export const ImageMenuItemDownload = memo(() => {
|
||||
const imageDTO = useImageDTOContext();
|
||||
const { downloadImage } = useDownloadImage();
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
downloadImage(imageDTO.image_url, imageDTO.image_name);
|
||||
}, [downloadImage, imageDTO.image_name, imageDTO.image_url]);
|
||||
|
||||
@@ -21,7 +21,7 @@ export const ImageMenuItemDownload = memo(() => {
|
||||
tooltip={t('parameters.downloadImage')}
|
||||
variant="ghost"
|
||||
colorScheme="base"
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -14,14 +14,14 @@ export const ImageMenuItemLoadWorkflow = memo(() => {
|
||||
const [getAndLoadEmbeddedWorkflow, { isLoading }] = useGetAndLoadEmbeddedWorkflow();
|
||||
const hasTemplates = useStore($hasTemplates);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
getAndLoadEmbeddedWorkflow(imageDTO.image_name);
|
||||
}, [getAndLoadEmbeddedWorkflow, imageDTO.image_name]);
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
icon={isLoading ? <SpinnerIcon /> : <PiFlowArrowBold />}
|
||||
onClickCapture={onClick}
|
||||
onPointerUpCapture={onPointerUp}
|
||||
isDisabled={!imageDTO.has_workflow || !hasTemplates}
|
||||
>
|
||||
{t('nodes.loadWorkflow')}
|
||||
|
||||
@@ -20,19 +20,19 @@ export const ImageMenuItemMetadataRecallActions = memo(() => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuItem icon={<PiArrowsCounterClockwiseBold />} onClickCapture={remix} isDisabled={!hasMetadata}>
|
||||
<MenuItem icon={<PiArrowsCounterClockwiseBold />} onPointerUpCapture={remix} isDisabled={!hasMetadata}>
|
||||
{t('parameters.remixImage')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<PiQuotesBold />} onClickCapture={recallPrompts} isDisabled={!hasPrompts}>
|
||||
<MenuItem icon={<PiQuotesBold />} onPointerUpCapture={recallPrompts} isDisabled={!hasPrompts}>
|
||||
{t('parameters.usePrompt')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<PiPlantBold />} onClickCapture={recallSeed} isDisabled={!hasSeed}>
|
||||
<MenuItem icon={<PiPlantBold />} onPointerUpCapture={recallSeed} isDisabled={!hasSeed}>
|
||||
{t('parameters.useSeed')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<PiAsteriskBold />} onClickCapture={recallAll} isDisabled={!hasMetadata}>
|
||||
<MenuItem icon={<PiAsteriskBold />} onPointerUpCapture={recallAll} isDisabled={!hasMetadata}>
|
||||
{t('parameters.useAll')}
|
||||
</MenuItem>
|
||||
<MenuItem icon={<PiPaintBrushBold />} onClickCapture={createAsPreset} isDisabled={!hasPrompts}>
|
||||
<MenuItem icon={<PiPaintBrushBold />} onPointerUpCapture={createAsPreset} isDisabled={!hasPrompts}>
|
||||
{t('stylePresets.useForTemplate')}
|
||||
</MenuItem>
|
||||
</>
|
||||
|
||||
@@ -41,7 +41,7 @@ export const ImageMenuItemNewCanvasFromImage = memo(() => {
|
||||
}, [bboxRect.x, bboxRect.y, dispatch, imageDTO, imageViewer, t]);
|
||||
|
||||
return (
|
||||
<MenuItem icon={<PiFileBold />} onClickCapture={handleSendToCanvas}>
|
||||
<MenuItem icon={<PiFileBold />} onPointerUpCapture={handleSendToCanvas}>
|
||||
{t('controlLayers.newCanvasFromImage')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -41,7 +41,7 @@ export const ImageMenuItemNewLayerFromImage = memo(() => {
|
||||
}, [bboxRect.x, bboxRect.y, dispatch, imageDTO, imageViewer, t]);
|
||||
|
||||
return (
|
||||
<MenuItem icon={<NewLayerIcon />} onClickCapture={handleSendToCanvas}>
|
||||
<MenuItem icon={<NewLayerIcon />} onPointerUpCapture={handleSendToCanvas}>
|
||||
{t('controlLayers.newLayerFromImage')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -7,13 +7,13 @@ import { PiArrowSquareOutBold } from 'react-icons/pi';
|
||||
export const ImageMenuItemOpenInNewTab = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const imageDTO = useImageDTOContext();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
window.open(imageDTO.image_url, '_blank');
|
||||
}, [imageDTO.image_url]);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClickCapture={onClick}
|
||||
onPointerUpCapture={onPointerUp}
|
||||
aria-label={t('common.openInNewTab')}
|
||||
tooltip={t('common.openInNewTab')}
|
||||
icon={<PiArrowSquareOutBold />}
|
||||
|
||||
@@ -9,14 +9,14 @@ export const ImageMenuItemOpenInViewer = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const imageDTO = useImageDTOContext();
|
||||
const imageViewer = useImageViewer();
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
imageViewer.openImageInViewer(imageDTO);
|
||||
}, [imageDTO, imageViewer]);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
icon={<PiArrowsOutBold />}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
aria-label={t('common.openInViewer')}
|
||||
tooltip={t('common.openInViewer')}
|
||||
variant="ghost"
|
||||
|
||||
@@ -17,7 +17,7 @@ export const ImageMenuItemSelectForCompare = memo(() => {
|
||||
);
|
||||
const maySelectForCompare = useAppSelector(selectMaySelectForCompare);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
dispatch(imageToCompareChanged(imageDTO));
|
||||
}, [dispatch, imageDTO]);
|
||||
|
||||
@@ -25,7 +25,7 @@ export const ImageMenuItemSelectForCompare = memo(() => {
|
||||
<IconButton
|
||||
icon={<PiImagesBold />}
|
||||
isDisabled={!maySelectForCompare}
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
aria-label={t('gallery.selectForCompare')}
|
||||
tooltip={t('gallery.selectForCompare')}
|
||||
variant="ghost"
|
||||
|
||||
@@ -24,7 +24,7 @@ export const ImageMenuItemSendToUpscale = memo(() => {
|
||||
}, [dispatch, imageDTO, t]);
|
||||
|
||||
return (
|
||||
<MenuItem icon={<PiShareFatBold />} onClickCapture={handleSendToCanvas} id="send-to-upscale">
|
||||
<MenuItem icon={<PiShareFatBold />} onPointerUpCapture={handleSendToCanvas} id="send-to-upscale">
|
||||
{t('parameters.sendToUpscale')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -28,14 +28,14 @@ export const ImageMenuItemStarUnstar = memo(() => {
|
||||
|
||||
if (imageDTO.starred) {
|
||||
return (
|
||||
<MenuItem icon={customStarUi ? customStarUi.off.icon : <PiStarFill />} onClickCapture={unstarImage}>
|
||||
<MenuItem icon={customStarUi ? customStarUi.off.icon : <PiStarFill />} onPointerUpCapture={unstarImage}>
|
||||
{customStarUi ? customStarUi.off.text : t('gallery.unstarImage')}
|
||||
</MenuItem>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<MenuItem icon={customStarUi ? customStarUi.on.icon : <PiStarBold />} onClickCapture={starImage}>
|
||||
<MenuItem icon={customStarUi ? customStarUi.on.icon : <PiStarBold />} onPointerUpCapture={starImage}>
|
||||
{customStarUi ? customStarUi.on.text : t('gallery.starImage')}
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
@@ -58,25 +58,25 @@ const MultipleSelectionMenuItems = () => {
|
||||
return (
|
||||
<>
|
||||
{areAllStarred && (
|
||||
<MenuItem icon={customStarUi ? customStarUi.on.icon : <PiStarBold />} onClickCapture={handleUnstarSelection}>
|
||||
<MenuItem icon={customStarUi ? customStarUi.on.icon : <PiStarBold />} onPointerUpCapture={handleUnstarSelection}>
|
||||
{customStarUi ? customStarUi.off.text : `Unstar All`}
|
||||
</MenuItem>
|
||||
)}
|
||||
{(areAllUnstarred || (!areAllStarred && !areAllUnstarred)) && (
|
||||
<MenuItem icon={customStarUi ? customStarUi.on.icon : <PiStarFill />} onClickCapture={handleStarSelection}>
|
||||
<MenuItem icon={customStarUi ? customStarUi.on.icon : <PiStarFill />} onPointerUpCapture={handleStarSelection}>
|
||||
{customStarUi ? customStarUi.on.text : `Star All`}
|
||||
</MenuItem>
|
||||
)}
|
||||
{isBulkDownloadEnabled && (
|
||||
<MenuItem icon={<PiDownloadSimpleBold />} onClickCapture={handleBulkDownload}>
|
||||
<MenuItem icon={<PiDownloadSimpleBold />} onPointerUpCapture={handleBulkDownload}>
|
||||
{t('gallery.downloadSelection')}
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuItem icon={<PiFoldersBold />} onClickCapture={handleChangeBoard}>
|
||||
<MenuItem icon={<PiFoldersBold />} onPointerUpCapture={handleChangeBoard}>
|
||||
{t('boards.changeBoard')}
|
||||
</MenuItem>
|
||||
<MenuDivider />
|
||||
<MenuItem color="error.300" icon={<PiTrashSimpleBold />} onClickCapture={handleDeleteSelection}>
|
||||
<MenuItem color="error.300" icon={<PiTrashSimpleBold />} onPointerUpCapture={handleDeleteSelection}>
|
||||
{t('gallery.deleteSelection')}
|
||||
</MenuItem>
|
||||
</>
|
||||
|
||||
@@ -157,7 +157,7 @@ const GalleryImageContent = memo(({ index, imageDTO }: HoverableImageProps) => {
|
||||
aspectRatio="1/1"
|
||||
>
|
||||
<IAIDndImage
|
||||
onClick={handleClick}
|
||||
onPointerUp={handleClick}
|
||||
onDoubleClick={onDoubleClick}
|
||||
imageDTO={imageDTO}
|
||||
draggableData={draggableData}
|
||||
@@ -191,7 +191,7 @@ const GalleryImageContent = memo(({ index, imageDTO }: HoverableImageProps) => {
|
||||
>{`${imageDTO.width}x${imageDTO.height}`}</Text>
|
||||
)}
|
||||
<IAIDndImageIcon
|
||||
onClick={toggleStarredState}
|
||||
onPointerUp={toggleStarredState}
|
||||
icon={starIcon}
|
||||
tooltip={starTooltip}
|
||||
position="absolute"
|
||||
@@ -213,7 +213,7 @@ const DeleteIcon = ({ imageDTO }: { imageDTO: ImageDTO }) => {
|
||||
const shift = useShiftModifier();
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const onClick = useCallback(
|
||||
const onPointerUp = useCallback(
|
||||
(e: MouseEvent<HTMLButtonElement>) => {
|
||||
e.stopPropagation();
|
||||
if (!imageDTO) {
|
||||
@@ -230,7 +230,7 @@ const DeleteIcon = ({ imageDTO }: { imageDTO: ImageDTO }) => {
|
||||
|
||||
return (
|
||||
<IAIDndImageIcon
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
icon={<PiTrashSimpleFill />}
|
||||
tooltip={t('gallery.deleteImage_one')}
|
||||
position="absolute"
|
||||
@@ -244,13 +244,13 @@ const OpenInViewerIconButton = ({ imageDTO }: { imageDTO: ImageDTO }) => {
|
||||
const imageViewer = useImageViewer();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
const onPointerUp = useCallback(() => {
|
||||
imageViewer.openImageInViewer(imageDTO);
|
||||
}, [imageDTO, imageViewer]);
|
||||
|
||||
return (
|
||||
<IAIDndImageIcon
|
||||
onClick={onClick}
|
||||
onPointerUp={onPointerUp}
|
||||
icon={<PiArrowsOutBold />}
|
||||
tooltip={t('gallery.openInViewer')}
|
||||
position="absolute"
|
||||
|
||||
@@ -9,11 +9,11 @@ export const GalleryPagination = () => {
|
||||
const { goPrev, goNext, isPrevEnabled, isNextEnabled, pageButtons, goToPage, currentPage, total } =
|
||||
useGalleryPagination();
|
||||
|
||||
const onClickPrev = useCallback(() => {
|
||||
const onPointerUpPrev = useCallback(() => {
|
||||
goPrev();
|
||||
}, [goPrev]);
|
||||
|
||||
const onClickNext = useCallback(() => {
|
||||
const onPointerUpNext = useCallback(() => {
|
||||
goNext();
|
||||
}, [goNext]);
|
||||
|
||||
@@ -27,7 +27,7 @@ export const GalleryPagination = () => {
|
||||
size="sm"
|
||||
aria-label="prev"
|
||||
icon={<PiCaretLeftBold />}
|
||||
onClick={onClickPrev}
|
||||
onPointerUp={onPointerUpPrev}
|
||||
isDisabled={!isPrevEnabled}
|
||||
variant="ghost"
|
||||
/>
|
||||
@@ -40,7 +40,7 @@ export const GalleryPagination = () => {
|
||||
size="sm"
|
||||
aria-label="next"
|
||||
icon={<PiCaretRightBold />}
|
||||
onClick={onClickNext}
|
||||
onPointerUp={onPointerUpNext}
|
||||
isDisabled={!isNextEnabled}
|
||||
variant="ghost"
|
||||
/>
|
||||
@@ -64,7 +64,7 @@ const PageButton = ({ page, currentPage, goToPage }: PageButtonProps) => {
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Button size="sm" onClick={goToPage.bind(null, page - 1)} variant={currentPage === page - 1 ? 'solid' : 'outline'}>
|
||||
<Button size="sm" onPointerUp={goToPage.bind(null, page - 1)} variant={currentPage === page - 1 ? 'solid' : 'outline'}>
|
||||
{page}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -54,7 +54,7 @@ export const GallerySearch = ({ searchTerm, onChangeSearchTerm, onResetSearchTer
|
||||
{!isPending && searchTerm.length && (
|
||||
<InputRightElement h="full" pe={2}>
|
||||
<IconButton
|
||||
onClick={onResetSearchTerm}
|
||||
onPointerUp={onResetSearchTerm}
|
||||
size="sm"
|
||||
variant="link"
|
||||
aria-label={t('boards.clearSearch')}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user