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:
psychedelicious 2022-11-02 19:51:38 +11:00 committed by Lincoln Stein
parent cfe567c62a
commit 620cf84d3d
19 changed files with 820 additions and 786 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

517
frontend/dist/assets/index.adcf8963.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -6,8 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>InvokeAI - A Stable Diffusion Toolkit</title> <title>InvokeAI - A Stable Diffusion Toolkit</title>
<link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" /> <link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" />
<script type="module" crossorigin src="./assets/index.552c95d8.js"></script> <script type="module" crossorigin src="./assets/index.adcf8963.js"></script>
<link rel="stylesheet" href="./assets/index.67342d6d.css"> <link rel="stylesheet" href="./assets/index.28b80602.css">
</head> </head>
<body> <body>

View File

@ -0,0 +1,3 @@
.invokeai__button {
justify-content: space-between;
}

View File

@ -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 { export interface IAIButtonProps extends ButtonProps {
label: string;
tooltip?: string; tooltip?: string;
tooltipProps?: Omit<TooltipProps, 'children'>;
styleClass?: string; styleClass?: string;
children: ReactNode;
} }
/** const IAIButton = forwardRef((props: IAIButtonProps, forwardedRef) => {
* Reusable customized button component. const { children, tooltip = '', tooltipProps, styleClass, ...rest } = props;
*/
const IAIButton = (props: IAIButtonProps) => {
const { label, tooltip = '', styleClass, ...rest } = props;
return ( return (
<Tooltip label={tooltip}> <Tooltip label={tooltip} {...tooltipProps}>
<Button className={styleClass ? styleClass : ''} {...rest}> <Button
{label} ref={forwardedRef}
className={['invokeai__button', styleClass].join(' ')}
{...rest}
>
{children}
</Button> </Button>
</Tooltip> </Tooltip>
); );
}; });
export default IAIButton; export default IAIButton;

View File

@ -3,17 +3,18 @@ import {
IconButton, IconButton,
Tooltip, Tooltip,
TooltipProps, TooltipProps,
forwardRef,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
interface Props extends IconButtonProps { export type IAIIconButtonProps = IconButtonProps & {
styleClass?: string; styleClass?: string;
tooltip?: string; tooltip?: string;
tooltipProps?: Omit<TooltipProps, 'children'>; tooltipProps?: Omit<TooltipProps, 'children'>;
asCheckbox?: boolean; asCheckbox?: boolean;
isChecked?: boolean; isChecked?: boolean;
} };
const IAIIconButton = (props: Props) => { const IAIIconButton = forwardRef((props: IAIIconButtonProps, forwardedRef) => {
const { const {
tooltip = '', tooltip = '',
styleClass, styleClass,
@ -26,6 +27,7 @@ const IAIIconButton = (props: Props) => {
return ( return (
<Tooltip label={tooltip} hasArrow {...tooltipProps}> <Tooltip label={tooltip} hasArrow {...tooltipProps}>
<IconButton <IconButton
ref={forwardedRef}
className={`invokeai__icon-button ${styleClass}`} className={`invokeai__icon-button ${styleClass}`}
data-as-checkbox={asCheckbox} data-as-checkbox={asCheckbox}
data-selected={isChecked !== undefined ? isChecked : undefined} data-selected={isChecked !== undefined ? isChecked : undefined}
@ -34,6 +36,6 @@ const IAIIconButton = (props: Props) => {
/> />
</Tooltip> </Tooltip>
); );
}; });
export default IAIIconButton; export default IAIIconButton;

View File

@ -3,7 +3,6 @@ import {
PopoverArrow, PopoverArrow,
PopoverContent, PopoverContent,
PopoverTrigger, PopoverTrigger,
Box,
BoxProps, BoxProps,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { PopoverProps } from '@chakra-ui/react'; import { PopoverProps } from '@chakra-ui/react';
@ -20,7 +19,6 @@ type IAIPopoverProps = PopoverProps & {
const IAIPopover = (props: IAIPopoverProps) => { const IAIPopover = (props: IAIPopoverProps) => {
const { const {
triggerComponent, triggerComponent,
triggerContainerProps,
children, children,
styleClass, styleClass,
hasArrow = true, hasArrow = true,
@ -29,9 +27,7 @@ const IAIPopover = (props: IAIPopoverProps) => {
return ( return (
<Popover {...rest}> <Popover {...rest}>
<PopoverTrigger> <PopoverTrigger>{triggerComponent}</PopoverTrigger>
<Box {...triggerContainerProps}>{triggerComponent}</Box>
</PopoverTrigger>
<PopoverContent className={`invokeai__popover-content ${styleClass}`}> <PopoverContent className={`invokeai__popover-content ${styleClass}`}>
{hasArrow && <PopoverArrow className={'invokeai__popover-arrow'} />} {hasArrow && <PopoverArrow className={'invokeai__popover-arrow'} />}
{children} {children}

View 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;
}
}

View File

@ -10,6 +10,7 @@ import {
setActiveTab, setActiveTab,
setAllParameters, setAllParameters,
setInitialImage, setInitialImage,
setPrompt,
setSeed, setSeed,
setShouldShowImageDetails, setShouldShowImageDetails,
} from '../options/optionsSlice'; } from '../options/optionsSlice';
@ -18,27 +19,27 @@ import { SystemState } from '../system/systemSlice';
import IAIButton from '../../common/components/IAIButton'; import IAIButton from '../../common/components/IAIButton';
import { runESRGAN, runFacetool } from '../../app/socketio/actions'; import { runESRGAN, runFacetool } from '../../app/socketio/actions';
import IAIIconButton from '../../common/components/IAIIconButton'; 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 UpscaleOptions from '../options/AdvancedOptions/Upscale/UpscaleOptions';
import FaceRestoreOptions from '../options/AdvancedOptions/FaceRestore/FaceRestoreOptions'; import FaceRestoreOptions from '../options/AdvancedOptions/FaceRestore/FaceRestoreOptions';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { useToast } from '@chakra-ui/react'; import { ButtonGroup, Link, useClipboard, useToast } from '@chakra-ui/react';
import { FaCopy, FaPaintBrush, FaSeedling } from 'react-icons/fa'; import {
FaAsterisk,
FaCode,
FaCopy,
FaDownload,
FaExpandArrowsAlt,
FaGrinStars,
FaQuoteRight,
FaSeedling,
FaShare,
FaShareAlt,
FaTrash,
} from 'react-icons/fa';
import { setImageToInpaint } from '../tabs/Inpainting/inpaintingSlice'; import { setImageToInpaint } from '../tabs/Inpainting/inpaintingSlice';
import { GalleryState } from './gallerySlice'; import { GalleryState } from './gallerySlice';
import { activeTabNameSelector } from '../options/optionsSelectors'; import { activeTabNameSelector } from '../options/optionsSelectors';
import IAIPopover from '../../common/components/IAIPopover';
const intermediateImageSelector = createSelector(
(state: RootState) => state.gallery,
(gallery: GalleryState) => gallery.intermediateImage,
{
memoizeOptions: {
resultEqualityCheck: (a, b) =>
(a === undefined && b === undefined) || a.uuid === b.uuid,
},
}
);
const systemSelector = createSelector( const systemSelector = createSelector(
[ [
@ -102,6 +103,8 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
activeTabName, activeTabName,
} = useAppSelector(systemSelector); } = useAppSelector(systemSelector);
const { onCopy } = useClipboard(window.location.toString() + image.url);
const toast = useToast(); const toast = useToast();
const handleClickUseAsInitialImage = () => { const handleClickUseAsInitialImage = () => {
@ -109,6 +112,16 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
dispatch(setActiveTab(1)); dispatch(setActiveTab(1));
}; };
const handleCopyImageLink = () => {
onCopy();
toast({
title: 'Image Link Copied',
status: 'success',
duration: 2500,
isClosable: true,
});
};
useHotkeys( useHotkeys(
'shift+i', 'shift+i',
() => { () => {
@ -186,6 +199,34 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
[image] [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)); const handleClickUpscale = () => dispatch(runESRGAN(image));
useHotkeys( useHotkeys(
'u', 'u',
@ -284,108 +325,133 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
return ( return (
<div className="current-image-options"> <div className="current-image-options">
<IAIIconButton <ButtonGroup isAttached={true}>
icon={<MdImage />} <IAIPopover
tooltip="Send To Image To Image" trigger="hover"
aria-label="Send To Image To Image" triggerComponent={
onClick={handleClickUseAsInitialImage} <IAIIconButton aria-label="Send to..." icon={<FaShareAlt />} />
/>
<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
} }
>
<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> </div>
); );
}; };

View File

@ -9,18 +9,6 @@
border-radius: 0.5rem; 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 { .current-image-preview {
position: relative; position: relative;
justify-content: center; justify-content: center;

View File

@ -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;
}

View File

@ -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;

View File

@ -17,7 +17,8 @@ const clearBrushHistorySelector = createSelector(
(inpainting: InpaintingState) => { (inpainting: InpaintingState) => {
const { pastLines, futureLines } = inpainting; const { pastLines, futureLines } = inpainting;
return { 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 ( return (
<IAIButton <IAIButton
label="Clear Brush History"
onClick={handleClearBrushHistory} onClick={handleClearBrushHistory}
tooltip="Clears brush stroke history" tooltip="Clears brush stroke history"
disabled={mayClearBrushHistory} disabled={mayClearBrushHistory}
styleClass="inpainting-options-btn" styleClass="inpainting-options-btn"
/> >
Clear Brush History
</IAIButton>
); );
} }

View File

@ -1,12 +1,13 @@
import { MdCancel } from 'react-icons/md'; import { MdCancel } from 'react-icons/md';
import { cancelProcessing } from '../../../app/socketio/actions'; import { cancelProcessing } from '../../../app/socketio/actions';
import { RootState, useAppDispatch, useAppSelector } from '../../../app/store'; 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 { useHotkeys } from 'react-hotkeys-hook';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { SystemState } from '../../system/systemSlice'; import { SystemState } from '../../system/systemSlice';
import _ from 'lodash'; import _ from 'lodash';
import { IAIButtonProps } from '../../../common/components/IAIButton';
const cancelButtonSelector = createSelector( const cancelButtonSelector = createSelector(
(state: RootState) => state.system, (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 { ...rest } = props;
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { isProcessing, isConnected, isCancelable } = const { isProcessing, isConnected, isCancelable } =

View File

@ -7,11 +7,14 @@ import { useAppDispatch, useAppSelector } from '../../../app/store';
import IAIButton, { import IAIButton, {
IAIButtonProps, IAIButtonProps,
} from '../../../common/components/IAIButton'; } from '../../../common/components/IAIButton';
import IAIIconButton from '../../../common/components/IAIIconButton'; import IAIIconButton, {
IAIIconButtonProps,
} from '../../../common/components/IAIIconButton';
import IAIPopover from '../../../common/components/IAIPopover'; import IAIPopover from '../../../common/components/IAIPopover';
import { activeTabNameSelector } from '../optionsSelectors'; import { activeTabNameSelector } from '../optionsSelectors';
interface InvokeButton extends Omit<IAIButtonProps, 'label'> { interface InvokeButton
extends Omit<IAIButtonProps | IAIIconButtonProps, 'aria-label'> {
iconButton?: boolean; iconButton?: boolean;
} }
@ -35,38 +38,39 @@ export default function InvokeButton(props: InvokeButton) {
[isReady, activeTabName] [isReady, activeTabName]
); );
const buttonComponent = iconButton ? ( const buttonComponent = (
<IAIIconButton <div style={{ flexGrow: 4 }}>
aria-label="Invoke" {iconButton ? (
type="submit" <IAIIconButton
icon={<FaPlay />} aria-label="Invoke"
isDisabled={!isReady} type="submit"
onClick={handleClickGenerate} icon={<FaPlay />}
className="invoke-btn invoke" isDisabled={!isReady}
tooltip="Invoke" onClick={handleClickGenerate}
tooltipProps={{ placement: 'bottom' }} className="invoke-btn invoke"
{...rest} tooltip="Invoke"
/> tooltipProps={{ placement: 'bottom' }}
) : ( {...rest}
<IAIButton />
label="Invoke" ) : (
aria-label="Invoke" <IAIButton
type="submit" aria-label="Invoke"
isDisabled={!isReady} type="submit"
onClick={handleClickGenerate} isDisabled={!isReady}
className="invoke-btn" onClick={handleClickGenerate}
{...rest} className="invoke-btn"
/> {...rest}
>
Invoke
</IAIButton>
)}
</div>
); );
return isReady ? ( return isReady ? (
buttonComponent buttonComponent
) : ( ) : (
<IAIPopover <IAIPopover trigger="hover" triggerComponent={buttonComponent}>
trigger="hover"
triggerContainerProps={{ style: { flexGrow: 4 } }}
triggerComponent={buttonComponent}
>
{reasonsWhyNotReady && ( {reasonsWhyNotReady && (
<UnorderedList> <UnorderedList>
{reasonsWhyNotReady.map((reason, i) => ( {reasonsWhyNotReady.map((reason, i) => (
@ -76,4 +80,20 @@ export default function InvokeButton(props: InvokeButton) {
)} )}
</IAIPopover> </IAIPopover>
); );
// return isReady ? (
// buttonComponent
// ) : (
// <IAIPopover trigger="hover" triggerComponent={buttonComponent}>
// {reasonsWhyNotReady ? (
// <UnorderedList>
// {reasonsWhyNotReady.map((reason, i) => (
// <ListItem key={i}>{reason}</ListItem>
// ))}
// </UnorderedList>
// ) : (
// 'test'
// )}
// </IAIPopover>
// );
} }

View File

@ -73,15 +73,20 @@ export default function HotkeysModal({ children }: HotkeysModalProps) {
const generalHotkeys = [ const generalHotkeys = [
{ {
title: 'Set Parameters', title: 'Set Prompt',
desc: 'Use all parameters of the current image', desc: 'Use the prompt of the current image',
hotkey: 'A', hotkey: 'P',
}, },
{ {
title: 'Set Seed', title: 'Set Seed',
desc: 'Use the seed of the current image', desc: 'Use the seed of the current image',
hotkey: 'S', 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: 'Restore Faces', desc: 'Restore the current image', hotkey: 'R' },
{ title: 'Upscale', desc: 'Upscale the current image', hotkey: 'U' }, { title: 'Upscale', desc: 'Upscale the current image', hotkey: 'U' },
{ {

View File

@ -28,9 +28,9 @@
// gallery // gallery
@use '../features/gallery/CurrentImageDisplay.scss'; @use '../features/gallery/CurrentImageDisplay.scss';
@use '../features/gallery/CurrentImageButtons.scss';
@use '../features/gallery/ImageGallery.scss'; @use '../features/gallery/ImageGallery.scss';
@use '../features/gallery/HoverableImage.scss'; @use '../features/gallery/HoverableImage.scss';
@use '../features/gallery/InvokePopover.scss';
@use '../features/gallery/ImageMetaDataViewer/ImageMetadataViewer.scss'; @use '../features/gallery/ImageMetaDataViewer/ImageMetadataViewer.scss';
// Tabs // Tabs
@ -47,6 +47,7 @@
@use '../common/components/IAINumberInput.scss'; @use '../common/components/IAINumberInput.scss';
@use '../common/components/IAIInput.scss'; @use '../common/components/IAIInput.scss';
@use '../common/components/IAIIconButton.scss'; @use '../common/components/IAIIconButton.scss';
@use '../common/components/IAIButton.scss';
@use '../common/components/IAISwitch.scss'; @use '../common/components/IAISwitch.scss';
@use '../common/components/IAISelect.scss'; @use '../common/components/IAISelect.scss';
@use '../common/components/IAISlider.scss'; @use '../common/components/IAISlider.scss';