mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Reworks CurrentImageButtons.tsx
- Change all icons to FA iconset for consistency - Refactors IAIIconButton, IAIButton, IAIPopover to handle ref forwarding - Redesigns buttons into group
This commit is contained in:
parent
cfe567c62a
commit
620cf84d3d
1
frontend/dist/assets/index.28b80602.css
vendored
Normal file
1
frontend/dist/assets/index.28b80602.css
vendored
Normal file
File diff suppressed because one or more lines are too long
517
frontend/dist/assets/index.552c95d8.js
vendored
517
frontend/dist/assets/index.552c95d8.js
vendored
File diff suppressed because one or more lines are too long
1
frontend/dist/assets/index.67342d6d.css
vendored
1
frontend/dist/assets/index.67342d6d.css
vendored
File diff suppressed because one or more lines are too long
517
frontend/dist/assets/index.adcf8963.js
vendored
Normal file
517
frontend/dist/assets/index.adcf8963.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
frontend/dist/index.html
vendored
4
frontend/dist/index.html
vendored
@ -6,8 +6,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
||||
<link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" />
|
||||
<script type="module" crossorigin src="./assets/index.552c95d8.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index.67342d6d.css">
|
||||
<script type="module" crossorigin src="./assets/index.adcf8963.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index.28b80602.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
3
frontend/src/common/components/IAIButton.scss
Normal file
3
frontend/src/common/components/IAIButton.scss
Normal file
@ -0,0 +1,3 @@
|
||||
.invokeai__button {
|
||||
justify-content: space-between;
|
||||
}
|
@ -1,23 +1,32 @@
|
||||
import { Button, ButtonProps, Tooltip } from '@chakra-ui/react';
|
||||
import {
|
||||
Button,
|
||||
ButtonProps,
|
||||
forwardRef,
|
||||
Tooltip,
|
||||
TooltipProps,
|
||||
} from '@chakra-ui/react';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export interface IAIButtonProps extends ButtonProps {
|
||||
label: string;
|
||||
tooltip?: string;
|
||||
tooltipProps?: Omit<TooltipProps, 'children'>;
|
||||
styleClass?: string;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable customized button component.
|
||||
*/
|
||||
const IAIButton = (props: IAIButtonProps) => {
|
||||
const { label, tooltip = '', styleClass, ...rest } = props;
|
||||
const IAIButton = forwardRef((props: IAIButtonProps, forwardedRef) => {
|
||||
const { children, tooltip = '', tooltipProps, styleClass, ...rest } = props;
|
||||
return (
|
||||
<Tooltip label={tooltip}>
|
||||
<Button className={styleClass ? styleClass : ''} {...rest}>
|
||||
{label}
|
||||
<Tooltip label={tooltip} {...tooltipProps}>
|
||||
<Button
|
||||
ref={forwardedRef}
|
||||
className={['invokeai__button', styleClass].join(' ')}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default IAIButton;
|
||||
|
@ -3,17 +3,18 @@ import {
|
||||
IconButton,
|
||||
Tooltip,
|
||||
TooltipProps,
|
||||
forwardRef,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
interface Props extends IconButtonProps {
|
||||
export type IAIIconButtonProps = IconButtonProps & {
|
||||
styleClass?: string;
|
||||
tooltip?: string;
|
||||
tooltipProps?: Omit<TooltipProps, 'children'>;
|
||||
asCheckbox?: boolean;
|
||||
isChecked?: boolean;
|
||||
}
|
||||
};
|
||||
|
||||
const IAIIconButton = (props: Props) => {
|
||||
const IAIIconButton = forwardRef((props: IAIIconButtonProps, forwardedRef) => {
|
||||
const {
|
||||
tooltip = '',
|
||||
styleClass,
|
||||
@ -26,6 +27,7 @@ const IAIIconButton = (props: Props) => {
|
||||
return (
|
||||
<Tooltip label={tooltip} hasArrow {...tooltipProps}>
|
||||
<IconButton
|
||||
ref={forwardedRef}
|
||||
className={`invokeai__icon-button ${styleClass}`}
|
||||
data-as-checkbox={asCheckbox}
|
||||
data-selected={isChecked !== undefined ? isChecked : undefined}
|
||||
@ -34,6 +36,6 @@ const IAIIconButton = (props: Props) => {
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default IAIIconButton;
|
||||
|
@ -3,7 +3,6 @@ import {
|
||||
PopoverArrow,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
Box,
|
||||
BoxProps,
|
||||
} from '@chakra-ui/react';
|
||||
import { PopoverProps } from '@chakra-ui/react';
|
||||
@ -20,7 +19,6 @@ type IAIPopoverProps = PopoverProps & {
|
||||
const IAIPopover = (props: IAIPopoverProps) => {
|
||||
const {
|
||||
triggerComponent,
|
||||
triggerContainerProps,
|
||||
children,
|
||||
styleClass,
|
||||
hasArrow = true,
|
||||
@ -29,9 +27,7 @@ const IAIPopover = (props: IAIPopoverProps) => {
|
||||
|
||||
return (
|
||||
<Popover {...rest}>
|
||||
<PopoverTrigger>
|
||||
<Box {...triggerContainerProps}>{triggerComponent}</Box>
|
||||
</PopoverTrigger>
|
||||
<PopoverTrigger>{triggerComponent}</PopoverTrigger>
|
||||
<PopoverContent className={`invokeai__popover-content ${styleClass}`}>
|
||||
{hasArrow && <PopoverArrow className={'invokeai__popover-arrow'} />}
|
||||
{children}
|
||||
|
19
frontend/src/features/gallery/CurrentImageButtons.scss
Normal file
19
frontend/src/features/gallery/CurrentImageButtons.scss
Normal file
@ -0,0 +1,19 @@
|
||||
.current-image-options {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
column-gap: 0.5rem;
|
||||
|
||||
.current-image-send-to-popover,
|
||||
.current-image-postprocessing-popover {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 0.5rem;
|
||||
max-width: 25rem;
|
||||
}
|
||||
|
||||
.chakra-popover__popper {
|
||||
z-index: 11;
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import {
|
||||
setActiveTab,
|
||||
setAllParameters,
|
||||
setInitialImage,
|
||||
setPrompt,
|
||||
setSeed,
|
||||
setShouldShowImageDetails,
|
||||
} from '../options/optionsSlice';
|
||||
@ -18,27 +19,27 @@ import { SystemState } from '../system/systemSlice';
|
||||
import IAIButton from '../../common/components/IAIButton';
|
||||
import { runESRGAN, runFacetool } from '../../app/socketio/actions';
|
||||
import IAIIconButton from '../../common/components/IAIIconButton';
|
||||
import { MdDelete, MdFace, MdHd, MdImage, MdInfo } from 'react-icons/md';
|
||||
import InvokePopover from './InvokePopover';
|
||||
import UpscaleOptions from '../options/AdvancedOptions/Upscale/UpscaleOptions';
|
||||
import FaceRestoreOptions from '../options/AdvancedOptions/FaceRestore/FaceRestoreOptions';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useToast } from '@chakra-ui/react';
|
||||
import { FaCopy, FaPaintBrush, FaSeedling } from 'react-icons/fa';
|
||||
import { ButtonGroup, Link, useClipboard, useToast } from '@chakra-ui/react';
|
||||
import {
|
||||
FaAsterisk,
|
||||
FaCode,
|
||||
FaCopy,
|
||||
FaDownload,
|
||||
FaExpandArrowsAlt,
|
||||
FaGrinStars,
|
||||
FaQuoteRight,
|
||||
FaSeedling,
|
||||
FaShare,
|
||||
FaShareAlt,
|
||||
FaTrash,
|
||||
} from 'react-icons/fa';
|
||||
import { setImageToInpaint } from '../tabs/Inpainting/inpaintingSlice';
|
||||
import { GalleryState } from './gallerySlice';
|
||||
import { activeTabNameSelector } from '../options/optionsSelectors';
|
||||
|
||||
const intermediateImageSelector = createSelector(
|
||||
(state: RootState) => state.gallery,
|
||||
(gallery: GalleryState) => gallery.intermediateImage,
|
||||
{
|
||||
memoizeOptions: {
|
||||
resultEqualityCheck: (a, b) =>
|
||||
(a === undefined && b === undefined) || a.uuid === b.uuid,
|
||||
},
|
||||
}
|
||||
);
|
||||
import IAIPopover from '../../common/components/IAIPopover';
|
||||
|
||||
const systemSelector = createSelector(
|
||||
[
|
||||
@ -102,6 +103,8 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
||||
activeTabName,
|
||||
} = useAppSelector(systemSelector);
|
||||
|
||||
const { onCopy } = useClipboard(window.location.toString() + image.url);
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
const handleClickUseAsInitialImage = () => {
|
||||
@ -109,6 +112,16 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
||||
dispatch(setActiveTab(1));
|
||||
};
|
||||
|
||||
const handleCopyImageLink = () => {
|
||||
onCopy();
|
||||
toast({
|
||||
title: 'Image Link Copied',
|
||||
status: 'success',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
};
|
||||
|
||||
useHotkeys(
|
||||
'shift+i',
|
||||
() => {
|
||||
@ -186,6 +199,34 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
||||
[image]
|
||||
);
|
||||
|
||||
const handleClickUsePrompt = () =>
|
||||
image?.metadata?.image?.prompt &&
|
||||
dispatch(setPrompt(image.metadata.image.prompt));
|
||||
|
||||
useHotkeys(
|
||||
'p',
|
||||
() => {
|
||||
if (image?.metadata?.image?.prompt) {
|
||||
handleClickUsePrompt();
|
||||
toast({
|
||||
title: 'Prompt Set',
|
||||
status: 'success',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
} else {
|
||||
toast({
|
||||
title: 'Prompt Not Set',
|
||||
description: 'Could not find prompt for this image.',
|
||||
status: 'error',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
[image]
|
||||
);
|
||||
|
||||
const handleClickUpscale = () => dispatch(runESRGAN(image));
|
||||
useHotkeys(
|
||||
'u',
|
||||
@ -284,108 +325,133 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
||||
|
||||
return (
|
||||
<div className="current-image-options">
|
||||
<IAIIconButton
|
||||
icon={<MdImage />}
|
||||
tooltip="Send To Image To Image"
|
||||
aria-label="Send To Image To Image"
|
||||
onClick={handleClickUseAsInitialImage}
|
||||
/>
|
||||
|
||||
<IAIIconButton
|
||||
icon={<FaPaintBrush />}
|
||||
tooltip="Send To Inpainting"
|
||||
aria-label="Send To Inpainting"
|
||||
onClick={handleSendToInpainting}
|
||||
/>
|
||||
|
||||
<IAIIconButton
|
||||
icon={<FaCopy />}
|
||||
tooltip="Use All"
|
||||
aria-label="Use All"
|
||||
isDisabled={
|
||||
!['txt2img', 'img2img'].includes(image?.metadata?.image?.type)
|
||||
}
|
||||
onClick={handleClickUseAllParameters}
|
||||
/>
|
||||
|
||||
<IAIIconButton
|
||||
icon={<FaSeedling />}
|
||||
tooltip="Use Seed"
|
||||
aria-label="Use Seed"
|
||||
isDisabled={!image?.metadata?.image?.seed}
|
||||
onClick={handleClickUseSeed}
|
||||
/>
|
||||
|
||||
{/* <IAIButton
|
||||
label="Use All"
|
||||
isDisabled={
|
||||
!['txt2img', 'img2img'].includes(image?.metadata?.image?.type)
|
||||
}
|
||||
onClick={handleClickUseAllParameters}
|
||||
/>
|
||||
|
||||
<IAIButton
|
||||
label="Use Seed"
|
||||
isDisabled={!image?.metadata?.image?.seed}
|
||||
onClick={handleClickUseSeed}
|
||||
/> */}
|
||||
|
||||
<InvokePopover
|
||||
title="Restore Faces"
|
||||
popoverOptions={<FaceRestoreOptions />}
|
||||
actionButton={
|
||||
<IAIButton
|
||||
label={'Restore Faces'}
|
||||
isDisabled={
|
||||
!isGFPGANAvailable ||
|
||||
Boolean(intermediateImage) ||
|
||||
!(isConnected && !isProcessing) ||
|
||||
!facetoolStrength
|
||||
}
|
||||
onClick={handleClickFixFaces}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<IAIIconButton icon={<MdFace />} aria-label="Restore Faces" />
|
||||
</InvokePopover>
|
||||
|
||||
<InvokePopover
|
||||
title="Upscale"
|
||||
styleClass="upscale-popover"
|
||||
popoverOptions={<UpscaleOptions />}
|
||||
actionButton={
|
||||
<IAIButton
|
||||
label={'Upscale Image'}
|
||||
isDisabled={
|
||||
!isESRGANAvailable ||
|
||||
Boolean(intermediateImage) ||
|
||||
!(isConnected && !isProcessing) ||
|
||||
!upscalingLevel
|
||||
}
|
||||
onClick={handleClickUpscale}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<IAIIconButton icon={<MdHd />} aria-label="Upscale" />
|
||||
</InvokePopover>
|
||||
|
||||
<IAIIconButton
|
||||
icon={<MdInfo />}
|
||||
tooltip="Details"
|
||||
aria-label="Details"
|
||||
onClick={handleClickShowImageDetails}
|
||||
/>
|
||||
|
||||
<DeleteImageModal image={image}>
|
||||
<IAIIconButton
|
||||
icon={<MdDelete />}
|
||||
tooltip="Delete Image"
|
||||
aria-label="Delete Image"
|
||||
isDisabled={
|
||||
Boolean(intermediateImage) || !isConnected || isProcessing
|
||||
<ButtonGroup isAttached={true}>
|
||||
<IAIPopover
|
||||
trigger="hover"
|
||||
triggerComponent={
|
||||
<IAIIconButton aria-label="Send to..." icon={<FaShareAlt />} />
|
||||
}
|
||||
>
|
||||
<div className="current-image-send-to-popover">
|
||||
<IAIButton
|
||||
size={'sm'}
|
||||
onClick={handleClickUseAsInitialImage}
|
||||
leftIcon={<FaShare />}
|
||||
>
|
||||
Send to Image to Image
|
||||
</IAIButton>
|
||||
<IAIButton
|
||||
size={'sm'}
|
||||
onClick={handleSendToInpainting}
|
||||
leftIcon={<FaShare />}
|
||||
>
|
||||
Send to Inpainting
|
||||
</IAIButton>
|
||||
<IAIButton
|
||||
size={'sm'}
|
||||
onClick={handleCopyImageLink}
|
||||
leftIcon={<FaCopy />}
|
||||
>
|
||||
Copy Link to Image
|
||||
</IAIButton>
|
||||
|
||||
<IAIButton leftIcon={<FaDownload />} size={'sm'}>
|
||||
<Link download={true} href={image.url}>
|
||||
Download Image
|
||||
</Link>
|
||||
</IAIButton>
|
||||
</div>
|
||||
</IAIPopover>
|
||||
|
||||
<IAIIconButton
|
||||
icon={<FaQuoteRight />}
|
||||
tooltip="Use Prompt"
|
||||
aria-label="Use Prompt"
|
||||
isDisabled={!image?.metadata?.image?.prompt}
|
||||
onClick={handleClickUsePrompt}
|
||||
/>
|
||||
</DeleteImageModal>
|
||||
|
||||
<IAIIconButton
|
||||
icon={<FaSeedling />}
|
||||
tooltip="Use Seed"
|
||||
aria-label="Use Seed"
|
||||
isDisabled={!image?.metadata?.image?.seed}
|
||||
onClick={handleClickUseSeed}
|
||||
/>
|
||||
|
||||
<IAIIconButton
|
||||
icon={<FaAsterisk />}
|
||||
tooltip="Use All"
|
||||
aria-label="Use All"
|
||||
isDisabled={
|
||||
!['txt2img', 'img2img'].includes(image?.metadata?.image?.type)
|
||||
}
|
||||
onClick={handleClickUseAllParameters}
|
||||
/>
|
||||
|
||||
<IAIPopover
|
||||
trigger="hover"
|
||||
triggerComponent={
|
||||
<IAIIconButton icon={<FaGrinStars />} aria-label="Restore Faces" />
|
||||
}
|
||||
>
|
||||
<div className="current-image-postprocessing-popover">
|
||||
<FaceRestoreOptions />
|
||||
<IAIButton
|
||||
isDisabled={
|
||||
!isGFPGANAvailable ||
|
||||
Boolean(intermediateImage) ||
|
||||
!(isConnected && !isProcessing) ||
|
||||
!facetoolStrength
|
||||
}
|
||||
onClick={handleClickFixFaces}
|
||||
>
|
||||
Restore Faces
|
||||
</IAIButton>
|
||||
</div>
|
||||
</IAIPopover>
|
||||
|
||||
<IAIPopover
|
||||
trigger="hover"
|
||||
triggerComponent={
|
||||
<IAIIconButton icon={<FaExpandArrowsAlt />} aria-label="Upscale" />
|
||||
}
|
||||
>
|
||||
<div className="current-image-postprocessing-popover">
|
||||
<UpscaleOptions />
|
||||
<IAIButton
|
||||
isDisabled={
|
||||
!isESRGANAvailable ||
|
||||
Boolean(intermediateImage) ||
|
||||
!(isConnected && !isProcessing) ||
|
||||
!upscalingLevel
|
||||
}
|
||||
onClick={handleClickUpscale}
|
||||
>
|
||||
Upscale Image
|
||||
</IAIButton>
|
||||
</div>
|
||||
</IAIPopover>
|
||||
|
||||
<IAIIconButton
|
||||
icon={<FaCode />}
|
||||
tooltip="Details"
|
||||
aria-label="Details"
|
||||
data-selected={shouldShowImageDetails}
|
||||
onClick={handleClickShowImageDetails}
|
||||
/>
|
||||
|
||||
<DeleteImageModal image={image}>
|
||||
<IAIIconButton
|
||||
icon={<FaTrash />}
|
||||
tooltip="Delete Image"
|
||||
aria-label="Delete Image"
|
||||
isDisabled={
|
||||
Boolean(intermediateImage) || !isConnected || isProcessing
|
||||
}
|
||||
/>
|
||||
</DeleteImageModal>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -9,18 +9,6 @@
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.current-image-options {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
column-gap: 0.5rem;
|
||||
|
||||
.chakra-popover__popper {
|
||||
z-index: 11;
|
||||
}
|
||||
}
|
||||
|
||||
.current-image-preview {
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
|
@ -1,35 +0,0 @@
|
||||
.popover-content {
|
||||
background-color: var(--background-color-secondary) !important;
|
||||
border: none !important;
|
||||
border-top: 0px;
|
||||
background-color: var(--tab-hover-color);
|
||||
border-radius: 0 0 0.4rem 0.4rem;
|
||||
}
|
||||
|
||||
.popover-arrow {
|
||||
background: var(--tab-hover-color) !important;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.popover-options {
|
||||
background: var(--tab-panel-bg);
|
||||
border-radius: 0 0 0.4rem 0.4rem;
|
||||
border: 2px solid var(--tab-hover-color);
|
||||
padding: 0.75rem 1rem 0.75rem 1rem;
|
||||
display: grid;
|
||||
grid-auto-rows: max-content;
|
||||
grid-row-gap: 0.5rem;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.popover-header {
|
||||
background: var(--tab-hover-color);
|
||||
border-radius: 0.4rem 0.4rem 0 0;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
padding-left: 1rem !important;
|
||||
}
|
||||
|
||||
.upscale-popover {
|
||||
width: 23rem !important;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
import {
|
||||
Box,
|
||||
Popover,
|
||||
PopoverArrow,
|
||||
PopoverContent,
|
||||
PopoverHeader,
|
||||
PopoverTrigger,
|
||||
} from '@chakra-ui/react';
|
||||
import React, { ReactNode } from 'react';
|
||||
|
||||
type PopoverProps = {
|
||||
title?: string;
|
||||
delay?: number;
|
||||
styleClass?: string;
|
||||
popoverOptions?: ReactNode;
|
||||
actionButton?: ReactNode;
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
const InvokePopover = ({
|
||||
title = 'Popup',
|
||||
styleClass,
|
||||
delay = 50,
|
||||
popoverOptions,
|
||||
actionButton,
|
||||
children,
|
||||
}: PopoverProps) => {
|
||||
return (
|
||||
<Popover trigger={'hover'} closeDelay={delay}>
|
||||
<PopoverTrigger>
|
||||
<Box>{children}</Box>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className={`popover-content ${styleClass}`}>
|
||||
<PopoverArrow className="popover-arrow" />
|
||||
<PopoverHeader className="popover-header">{title}</PopoverHeader>
|
||||
<div className="popover-options">
|
||||
{popoverOptions ? popoverOptions : null}
|
||||
{actionButton}
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
export default InvokePopover;
|
@ -17,7 +17,8 @@ const clearBrushHistorySelector = createSelector(
|
||||
(inpainting: InpaintingState) => {
|
||||
const { pastLines, futureLines } = inpainting;
|
||||
return {
|
||||
mayClearBrushHistory: futureLines.length > 0 || pastLines.length > 0 ? false : true
|
||||
mayClearBrushHistory:
|
||||
futureLines.length > 0 || pastLines.length > 0 ? false : true,
|
||||
};
|
||||
},
|
||||
{
|
||||
@ -44,11 +45,12 @@ export default function ClearBrushHistory() {
|
||||
};
|
||||
return (
|
||||
<IAIButton
|
||||
label="Clear Brush History"
|
||||
onClick={handleClearBrushHistory}
|
||||
tooltip="Clears brush stroke history"
|
||||
disabled={mayClearBrushHistory}
|
||||
styleClass="inpainting-options-btn"
|
||||
/>
|
||||
>
|
||||
Clear Brush History
|
||||
</IAIButton>
|
||||
);
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { MdCancel } from 'react-icons/md';
|
||||
import { cancelProcessing } from '../../../app/socketio/actions';
|
||||
import { RootState, useAppDispatch, useAppSelector } from '../../../app/store';
|
||||
import IAIIconButton from '../../../common/components/IAIIconButton';
|
||||
import IAIIconButton, {
|
||||
IAIIconButtonProps,
|
||||
} from '../../../common/components/IAIIconButton';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { SystemState } from '../../system/systemSlice';
|
||||
import _ from 'lodash';
|
||||
import { IAIButtonProps } from '../../../common/components/IAIButton';
|
||||
|
||||
const cancelButtonSelector = createSelector(
|
||||
(state: RootState) => state.system,
|
||||
@ -24,7 +25,9 @@ const cancelButtonSelector = createSelector(
|
||||
}
|
||||
);
|
||||
|
||||
export default function CancelButton(props: Omit<IAIButtonProps, 'label'>) {
|
||||
export default function CancelButton(
|
||||
props: Omit<IAIIconButtonProps, 'aria-label'>
|
||||
) {
|
||||
const { ...rest } = props;
|
||||
const dispatch = useAppDispatch();
|
||||
const { isProcessing, isConnected, isCancelable } =
|
||||
|
@ -7,11 +7,14 @@ import { useAppDispatch, useAppSelector } from '../../../app/store';
|
||||
import IAIButton, {
|
||||
IAIButtonProps,
|
||||
} from '../../../common/components/IAIButton';
|
||||
import IAIIconButton from '../../../common/components/IAIIconButton';
|
||||
import IAIIconButton, {
|
||||
IAIIconButtonProps,
|
||||
} from '../../../common/components/IAIIconButton';
|
||||
import IAIPopover from '../../../common/components/IAIPopover';
|
||||
import { activeTabNameSelector } from '../optionsSelectors';
|
||||
|
||||
interface InvokeButton extends Omit<IAIButtonProps, 'label'> {
|
||||
interface InvokeButton
|
||||
extends Omit<IAIButtonProps | IAIIconButtonProps, 'aria-label'> {
|
||||
iconButton?: boolean;
|
||||
}
|
||||
|
||||
@ -35,38 +38,39 @@ export default function InvokeButton(props: InvokeButton) {
|
||||
[isReady, activeTabName]
|
||||
);
|
||||
|
||||
const buttonComponent = iconButton ? (
|
||||
<IAIIconButton
|
||||
aria-label="Invoke"
|
||||
type="submit"
|
||||
icon={<FaPlay />}
|
||||
isDisabled={!isReady}
|
||||
onClick={handleClickGenerate}
|
||||
className="invoke-btn invoke"
|
||||
tooltip="Invoke"
|
||||
tooltipProps={{ placement: 'bottom' }}
|
||||
{...rest}
|
||||
/>
|
||||
) : (
|
||||
<IAIButton
|
||||
label="Invoke"
|
||||
aria-label="Invoke"
|
||||
type="submit"
|
||||
isDisabled={!isReady}
|
||||
onClick={handleClickGenerate}
|
||||
className="invoke-btn"
|
||||
{...rest}
|
||||
/>
|
||||
const buttonComponent = (
|
||||
<div style={{ flexGrow: 4 }}>
|
||||
{iconButton ? (
|
||||
<IAIIconButton
|
||||
aria-label="Invoke"
|
||||
type="submit"
|
||||
icon={<FaPlay />}
|
||||
isDisabled={!isReady}
|
||||
onClick={handleClickGenerate}
|
||||
className="invoke-btn invoke"
|
||||
tooltip="Invoke"
|
||||
tooltipProps={{ placement: 'bottom' }}
|
||||
{...rest}
|
||||
/>
|
||||
) : (
|
||||
<IAIButton
|
||||
aria-label="Invoke"
|
||||
type="submit"
|
||||
isDisabled={!isReady}
|
||||
onClick={handleClickGenerate}
|
||||
className="invoke-btn"
|
||||
{...rest}
|
||||
>
|
||||
Invoke
|
||||
</IAIButton>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
return isReady ? (
|
||||
buttonComponent
|
||||
) : (
|
||||
<IAIPopover
|
||||
trigger="hover"
|
||||
triggerContainerProps={{ style: { flexGrow: 4 } }}
|
||||
triggerComponent={buttonComponent}
|
||||
>
|
||||
<IAIPopover trigger="hover" triggerComponent={buttonComponent}>
|
||||
{reasonsWhyNotReady && (
|
||||
<UnorderedList>
|
||||
{reasonsWhyNotReady.map((reason, i) => (
|
||||
@ -76,4 +80,20 @@ export default function InvokeButton(props: InvokeButton) {
|
||||
)}
|
||||
</IAIPopover>
|
||||
);
|
||||
|
||||
// return isReady ? (
|
||||
// buttonComponent
|
||||
// ) : (
|
||||
// <IAIPopover trigger="hover" triggerComponent={buttonComponent}>
|
||||
// {reasonsWhyNotReady ? (
|
||||
// <UnorderedList>
|
||||
// {reasonsWhyNotReady.map((reason, i) => (
|
||||
// <ListItem key={i}>{reason}</ListItem>
|
||||
// ))}
|
||||
// </UnorderedList>
|
||||
// ) : (
|
||||
// 'test'
|
||||
// )}
|
||||
// </IAIPopover>
|
||||
// );
|
||||
}
|
||||
|
@ -73,15 +73,20 @@ export default function HotkeysModal({ children }: HotkeysModalProps) {
|
||||
|
||||
const generalHotkeys = [
|
||||
{
|
||||
title: 'Set Parameters',
|
||||
desc: 'Use all parameters of the current image',
|
||||
hotkey: 'A',
|
||||
title: 'Set Prompt',
|
||||
desc: 'Use the prompt of the current image',
|
||||
hotkey: 'P',
|
||||
},
|
||||
{
|
||||
title: 'Set Seed',
|
||||
desc: 'Use the seed of the current image',
|
||||
hotkey: 'S',
|
||||
},
|
||||
{
|
||||
title: 'Set Parameters',
|
||||
desc: 'Use all parameters of the current image',
|
||||
hotkey: 'A',
|
||||
},
|
||||
{ title: 'Restore Faces', desc: 'Restore the current image', hotkey: 'R' },
|
||||
{ title: 'Upscale', desc: 'Upscale the current image', hotkey: 'U' },
|
||||
{
|
||||
|
@ -28,9 +28,9 @@
|
||||
|
||||
// gallery
|
||||
@use '../features/gallery/CurrentImageDisplay.scss';
|
||||
@use '../features/gallery/CurrentImageButtons.scss';
|
||||
@use '../features/gallery/ImageGallery.scss';
|
||||
@use '../features/gallery/HoverableImage.scss';
|
||||
@use '../features/gallery/InvokePopover.scss';
|
||||
@use '../features/gallery/ImageMetaDataViewer/ImageMetadataViewer.scss';
|
||||
|
||||
// Tabs
|
||||
@ -47,6 +47,7 @@
|
||||
@use '../common/components/IAINumberInput.scss';
|
||||
@use '../common/components/IAIInput.scss';
|
||||
@use '../common/components/IAIIconButton.scss';
|
||||
@use '../common/components/IAIButton.scss';
|
||||
@use '../common/components/IAISwitch.scss';
|
||||
@use '../common/components/IAISelect.scss';
|
||||
@use '../common/components/IAISlider.scss';
|
||||
|
Loading…
Reference in New Issue
Block a user