mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Adds "loopback" feature
This commit is contained in:
parent
2d32cf4eeb
commit
6547c320a9
517
frontend/dist/assets/index.1ad4a17a.js
vendored
Normal file
517
frontend/dist/assets/index.1ad4a17a.js
vendored
Normal file
File diff suppressed because one or more lines are too long
517
frontend/dist/assets/index.616d87b3.js
vendored
517
frontend/dist/assets/index.616d87b3.js
vendored
File diff suppressed because one or more lines are too long
1
frontend/dist/assets/index.64a76932.css
vendored
1
frontend/dist/assets/index.64a76932.css
vendored
File diff suppressed because one or more lines are too long
1
frontend/dist/assets/index.c4f22615.css
vendored
Normal file
1
frontend/dist/assets/index.c4f22615.css
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.616d87b3.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index.64a76932.css">
|
||||
<script type="module" crossorigin src="./assets/index.1ad4a17a.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index.c4f22615.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -37,6 +37,7 @@ import {
|
||||
clearImageToInpaint,
|
||||
setImageToInpaint,
|
||||
} from '../../features/tabs/Inpainting/inpaintingSlice';
|
||||
import { tabMap } from '../../features/tabs/InvokeTabs';
|
||||
|
||||
/**
|
||||
* Returns an object containing listener callbacks for socketio events.
|
||||
@ -96,16 +97,34 @@ const makeSocketIOListeners = (
|
||||
*/
|
||||
onGenerationResult: (data: InvokeAI.ImageResultResponse) => {
|
||||
try {
|
||||
const { shouldLoopback, activeTab } = getState().options;
|
||||
const newImage = {
|
||||
uuid: uuidv4(),
|
||||
...data,
|
||||
category: 'result',
|
||||
};
|
||||
|
||||
dispatch(
|
||||
addImage({
|
||||
category: 'result',
|
||||
image: {
|
||||
uuid: uuidv4(),
|
||||
...data,
|
||||
category: 'result',
|
||||
},
|
||||
image: newImage,
|
||||
})
|
||||
);
|
||||
|
||||
if (shouldLoopback) {
|
||||
const activeTabName = tabMap[activeTab];
|
||||
switch (activeTabName) {
|
||||
case 'img2img': {
|
||||
dispatch(setInitialImage(newImage));
|
||||
break;
|
||||
}
|
||||
case 'inpainting': {
|
||||
dispatch(setImageToInpaint(newImage));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
|
24
frontend/src/features/options/ProcessButtons/Loopback.tsx
Normal file
24
frontend/src/features/options/ProcessButtons/Loopback.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import { FaRecycle } from 'react-icons/fa';
|
||||
import { RootState, useAppDispatch, useAppSelector } from '../../../app/store';
|
||||
import IAIIconButton from '../../../common/components/IAIIconButton';
|
||||
import { setShouldLoopback } from '../optionsSlice';
|
||||
|
||||
const LoopbackButton = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { shouldLoopback } = useAppSelector(
|
||||
(state: RootState) => state.options
|
||||
);
|
||||
return (
|
||||
<IAIIconButton
|
||||
aria-label="Loopback"
|
||||
tooltip="Loopback"
|
||||
data-selected={shouldLoopback}
|
||||
icon={<FaRecycle />}
|
||||
onClick={() => {
|
||||
dispatch(setShouldLoopback(!shouldLoopback));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoopbackButton;
|
@ -2,7 +2,7 @@
|
||||
|
||||
.process-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: auto max-content;
|
||||
grid-template-columns: auto max-content max-content;
|
||||
column-gap: 0.5rem;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import InvokeButton from './InvokeButton';
|
||||
import CancelButton from './CancelButton';
|
||||
import LoopbackButton from './Loopback';
|
||||
|
||||
/**
|
||||
* Buttons to start and cancel image generation.
|
||||
@ -8,6 +9,7 @@ const ProcessButtons = () => {
|
||||
return (
|
||||
<div className="process-buttons">
|
||||
<InvokeButton />
|
||||
<LoopbackButton />
|
||||
<CancelButton />
|
||||
</div>
|
||||
);
|
||||
|
@ -46,6 +46,7 @@ export interface OptionsState {
|
||||
shouldPinOptionsPanel: boolean;
|
||||
optionsPanelScrollPosition: number;
|
||||
shouldHoldOptionsPanelOpen: boolean;
|
||||
shouldLoopback: boolean;
|
||||
}
|
||||
|
||||
const initialOptionsState: OptionsState = {
|
||||
@ -83,6 +84,7 @@ const initialOptionsState: OptionsState = {
|
||||
shouldPinOptionsPanel: true,
|
||||
optionsPanelScrollPosition: 0,
|
||||
shouldHoldOptionsPanelOpen: false,
|
||||
shouldLoopback: true,
|
||||
};
|
||||
|
||||
const initialState: OptionsState = initialOptionsState;
|
||||
@ -344,6 +346,9 @@ export const optionsSlice = createSlice({
|
||||
setShouldHoldOptionsPanelOpen: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldHoldOptionsPanelOpen = action.payload;
|
||||
},
|
||||
setShouldLoopback: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldLoopback = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -390,6 +395,7 @@ export const {
|
||||
setShouldPinOptionsPanel,
|
||||
setOptionsPanelScrollPosition,
|
||||
setShouldHoldOptionsPanelOpen,
|
||||
setShouldLoopback,
|
||||
} = optionsSlice.actions;
|
||||
|
||||
export default optionsSlice.reducer;
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Tooltip } from '@chakra-ui/react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import {
|
||||
FocusEvent,
|
||||
@ -7,7 +8,7 @@ import {
|
||||
useEffect,
|
||||
useRef,
|
||||
} from 'react';
|
||||
import { BsPinAngleFill } from 'react-icons/bs';
|
||||
import { BsPinAngle, BsPinAngleFill } from 'react-icons/bs';
|
||||
import { CSSTransition } from 'react-transition-group';
|
||||
import { RootState, useAppDispatch, useAppSelector } from '../../app/store';
|
||||
import IAIIconButton from '../../common/components/IAIIconButton';
|
||||
@ -119,6 +120,16 @@ const InvokeOptionsPanel = (props: Props) => {
|
||||
!shouldPinOptionsPanel ? cancelCloseOptionsPanelTimer : undefined
|
||||
}
|
||||
>
|
||||
<Tooltip label="Pin Options Panel">
|
||||
<div
|
||||
className="options-panel-pin-button"
|
||||
data-selected={shouldPinOptionsPanel}
|
||||
onClick={handleClickPinOptionsPanel}
|
||||
>
|
||||
{shouldPinOptionsPanel ? <BsPinAngleFill /> : <BsPinAngle />}
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
<div
|
||||
className="options-panel"
|
||||
ref={optionsPanelContainerRef}
|
||||
@ -130,14 +141,6 @@ const InvokeOptionsPanel = (props: Props) => {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<IAIIconButton
|
||||
size={'sm'}
|
||||
aria-label={'Pin Options Panel'}
|
||||
tooltip={'Pin Options Panel (Shift+P)'}
|
||||
onClick={handleClickPinOptionsPanel}
|
||||
icon={<BsPinAngleFill />}
|
||||
data-selected={shouldPinOptionsPanel}
|
||||
/>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user