mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Change scheduled send to be as part of context for Cancel button
This commit is contained in:
parent
d00571b5a4
commit
e683b574d1
10
invokeai/frontend/.gitignore
vendored
10
invokeai/frontend/.gitignore
vendored
@ -27,5 +27,11 @@ dist-ssr
|
||||
# build stats
|
||||
stats.html
|
||||
|
||||
# Yarn
|
||||
.yarn
|
||||
# Yarn - https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
147529
invokeai/frontend/.yarn/releases/yarn-1.22.19.cjs
vendored
Normal file
147529
invokeai/frontend/.yarn/releases/yarn-1.22.19.cjs
vendored
Normal file
File diff suppressed because one or more lines are too long
5
invokeai/frontend/.yarnrc
Normal file
5
invokeai/frontend/.yarnrc
Normal file
@ -0,0 +1,5 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
yarn-path ".yarn/releases/yarn-1.22.19.cjs"
|
1
invokeai/frontend/.yarnrc.yml
Normal file
1
invokeai/frontend/.yarnrc.yml
Normal file
@ -0,0 +1 @@
|
||||
yarnPath: .yarn/releases/yarn-1.22.19.cjs
|
@ -7,7 +7,7 @@ The UI is in `invokeai/frontend`.
|
||||
Install [node](https://nodejs.org/en/download/) (includes npm) and
|
||||
[yarn](https://yarnpkg.com/getting-started/install).
|
||||
|
||||
From `invokeai/frontend/` run `yarn install` to get everything set up.
|
||||
From `invokeai/frontend/` run `yarn install --immutable` to get everything set up.
|
||||
|
||||
## Dev
|
||||
|
||||
|
638
invokeai/frontend/dist/assets/index-285d1fa2.js
vendored
Normal file
638
invokeai/frontend/dist/assets/index-285d1fa2.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
invokeai/frontend/dist/assets/index-c53bb2f3.css
vendored
Normal file
1
invokeai/frontend/dist/assets/index-c53bb2f3.css
vendored
Normal file
File diff suppressed because one or more lines are too long
638
invokeai/frontend/dist/assets/index-f007d4c5.js
vendored
638
invokeai/frontend/dist/assets/index-f007d4c5.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
invokeai/frontend/dist/index.html
vendored
4
invokeai/frontend/dist/index.html
vendored
@ -5,8 +5,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-f007d4c5.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index-fecb6dd4.css">
|
||||
<script type="module" crossorigin src="./assets/index-285d1fa2.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index-c53bb2f3.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -42,7 +42,13 @@
|
||||
"img2imgStrength": "Image To Image Strength",
|
||||
"toggleLoopback": "Toggle Loopback",
|
||||
"invoke": "Invoke",
|
||||
"cancel": "Cancel",
|
||||
"cancel":
|
||||
{
|
||||
"immediate": "Cancel immediately",
|
||||
"schedule": "Cancel after current iteration",
|
||||
"isScheduled": "Canceling",
|
||||
"setType": "Set cancel type"
|
||||
},
|
||||
"promptPlaceholder": "Type prompt here. [negative tokens], (upweight)++, (downweight)--, swap and blend are available (see docs)",
|
||||
"sendTo": "Send to",
|
||||
"sendToImg2Img": "Send to Image to Image",
|
||||
|
@ -43,9 +43,13 @@
|
||||
"img2imgStrength": "Image To Image Strength",
|
||||
"toggleLoopback": "Toggle Loopback",
|
||||
"invoke": "Invoke",
|
||||
"cancel": "Cancel",
|
||||
"scheduleCancel": "Cancel after current iteration",
|
||||
"cancelScheduled": "Canceling",
|
||||
"cancel":
|
||||
{
|
||||
"immediate": "Cancel immediately",
|
||||
"schedule": "Cancel after current iteration",
|
||||
"isScheduled": "Canceling",
|
||||
"setType": "Set cancel type"
|
||||
},
|
||||
"promptPlaceholder": "Type prompt here. [negative tokens], (upweight)++, (downweight)--, swap and blend are available (see docs)",
|
||||
"negativePrompts": "Negative Prompts",
|
||||
"sendTo": "Send to",
|
||||
|
@ -42,7 +42,13 @@
|
||||
"img2imgStrength": "Image To Image Strength",
|
||||
"toggleLoopback": "Toggle Loopback",
|
||||
"invoke": "Invoke",
|
||||
"cancel": "Cancel",
|
||||
"cancel":
|
||||
{
|
||||
"immediate": "Cancel immediately",
|
||||
"schedule": "Cancel after current iteration",
|
||||
"isScheduled": "Canceling",
|
||||
"setType": "Set cancel type"
|
||||
},
|
||||
"promptPlaceholder": "Type prompt here. [negative tokens], (upweight)++, (downweight)--, swap and blend are available (see docs)",
|
||||
"sendTo": "Send to",
|
||||
"sendToImg2Img": "Send to Image to Image",
|
||||
|
@ -43,9 +43,13 @@
|
||||
"img2imgStrength": "Image To Image Strength",
|
||||
"toggleLoopback": "Toggle Loopback",
|
||||
"invoke": "Invoke",
|
||||
"cancel": "Cancel",
|
||||
"scheduleCancel": "Cancel after current iteration",
|
||||
"cancelScheduled": "Canceling",
|
||||
"cancel":
|
||||
{
|
||||
"immediate": "Cancel immediately",
|
||||
"schedule": "Cancel after current iteration",
|
||||
"isScheduled": "Canceling",
|
||||
"setType": "Set cancel type"
|
||||
},
|
||||
"promptPlaceholder": "Type prompt here. [negative tokens], (upweight)++, (downweight)--, swap and blend are available (see docs)",
|
||||
"negativePrompts": "Negative Prompts",
|
||||
"sendTo": "Send to",
|
||||
|
@ -5,14 +5,30 @@ import IAIIconButton, {
|
||||
IAIIconButtonProps,
|
||||
} from 'common/components/IAIIconButton';
|
||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||
import { SystemState } from 'features/system/store/systemSlice';
|
||||
import {
|
||||
SystemState,
|
||||
setCancelAfter,
|
||||
setCancelType,
|
||||
} from 'features/system/store/systemSlice';
|
||||
import { isEqual } from 'lodash';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { Spinner } from '@chakra-ui/react';
|
||||
import { useEffect, useCallback } from 'react';
|
||||
import {
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuList,
|
||||
MenuItem,
|
||||
ButtonSpinner,
|
||||
ButtonGroup,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { MdCancel, MdCancelScheduleSend } from 'react-icons/md';
|
||||
import {
|
||||
MdCancel,
|
||||
MdCancelScheduleSend,
|
||||
MdArrowDropDown,
|
||||
MdArrowDropUp,
|
||||
} from 'react-icons/md';
|
||||
|
||||
const cancelButtonSelector = createSelector(
|
||||
systemSelector,
|
||||
@ -23,6 +39,8 @@ const cancelButtonSelector = createSelector(
|
||||
isCancelable: system.isCancelable,
|
||||
currentIteration: system.currentIteration,
|
||||
totalIterations: system.totalIterations,
|
||||
cancelType: system.cancelOptions.cancelType,
|
||||
cancelAfter: system.cancelOptions.cancelAfter,
|
||||
};
|
||||
},
|
||||
{
|
||||
@ -43,18 +61,17 @@ export default function CancelButton(
|
||||
isCancelable,
|
||||
currentIteration,
|
||||
totalIterations,
|
||||
cancelType,
|
||||
cancelAfter,
|
||||
} = useAppSelector(cancelButtonSelector);
|
||||
const [cancelAfterIteration, setCancelAfterIteration] = useState<number>(
|
||||
Number.MAX_SAFE_INTEGER
|
||||
);
|
||||
const handleClickCancel = useCallback(() => {
|
||||
dispatch(cancelProcessing());
|
||||
setCancelAfterIteration(Number.MAX_SAFE_INTEGER);
|
||||
dispatch(setCancelAfter(null));
|
||||
}, [dispatch]);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const isCancelScheduled = cancelAfterIteration !== Number.MAX_SAFE_INTEGER;
|
||||
const isCancelScheduled = cancelAfter === null ? false : true;
|
||||
|
||||
useHotkeys(
|
||||
'shift+x',
|
||||
@ -67,49 +84,74 @@ export default function CancelButton(
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (cancelAfterIteration < currentIteration) {
|
||||
if (cancelAfter !== null && cancelAfter < currentIteration) {
|
||||
handleClickCancel();
|
||||
}
|
||||
}, [cancelAfterIteration, currentIteration, handleClickCancel]);
|
||||
}, [cancelAfter, currentIteration, handleClickCancel]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<IAIIconButton
|
||||
icon={<MdCancel />}
|
||||
tooltip={t('parameters:cancel')}
|
||||
aria-label={t('parameters:cancel')}
|
||||
isDisabled={!isConnected || !isProcessing || !isCancelable}
|
||||
onClick={handleClickCancel}
|
||||
styleClass="cancel-btn"
|
||||
{...rest}
|
||||
/>
|
||||
<IAIIconButton
|
||||
icon={isCancelScheduled ? <Spinner /> : <MdCancelScheduleSend />}
|
||||
tooltip={
|
||||
isCancelScheduled
|
||||
? t('parameters:cancelScheduled')
|
||||
: t('parameters:scheduleCancel')
|
||||
}
|
||||
aria-label={
|
||||
isCancelScheduled
|
||||
? t('parameters:cancelScheduled')
|
||||
: t('parameters:scheduleCancel')
|
||||
}
|
||||
isDisabled={
|
||||
!isConnected ||
|
||||
!isProcessing ||
|
||||
!isCancelable ||
|
||||
currentIteration === totalIterations
|
||||
}
|
||||
onClick={() => {
|
||||
// If a cancel request has already been made, and the user clicks again before the next iteration has been processed, stop the request.
|
||||
if (isCancelScheduled)
|
||||
setCancelAfterIteration(Number.MAX_SAFE_INTEGER);
|
||||
else setCancelAfterIteration(currentIteration);
|
||||
}}
|
||||
styleClass="cancel-btn"
|
||||
{...rest}
|
||||
/>
|
||||
</>
|
||||
<ButtonGroup isAttached variant="link">
|
||||
{cancelType === 'immediate' ? (
|
||||
<IAIIconButton
|
||||
icon={<MdCancel />}
|
||||
tooltip={t('parameters:cancel.immediate')}
|
||||
aria-label={t('parameters:cancel.immediate')}
|
||||
isDisabled={!isConnected || !isProcessing || !isCancelable}
|
||||
onClick={handleClickCancel}
|
||||
className="cancel-btn"
|
||||
{...rest}
|
||||
/>
|
||||
) : (
|
||||
<IAIIconButton
|
||||
icon={
|
||||
isCancelScheduled ? <ButtonSpinner /> : <MdCancelScheduleSend />
|
||||
}
|
||||
tooltip={
|
||||
isCancelScheduled
|
||||
? t('parameters:cancel.isScheduled')
|
||||
: t('parameters:cancel.schedule')
|
||||
}
|
||||
aria-label={
|
||||
isCancelScheduled
|
||||
? t('parameters:cancel.isScheduled')
|
||||
: t('parameters:cancel.schedule')
|
||||
}
|
||||
isDisabled={
|
||||
!isConnected ||
|
||||
!isProcessing ||
|
||||
!isCancelable ||
|
||||
currentIteration === totalIterations
|
||||
}
|
||||
onClick={() => {
|
||||
// If a cancel request has already been made, and the user clicks again before the next iteration has been processed, stop the request.
|
||||
if (isCancelScheduled) dispatch(setCancelAfter(null));
|
||||
else dispatch(setCancelAfter(currentIteration));
|
||||
}}
|
||||
className="cancel-btn"
|
||||
{...rest}
|
||||
/>
|
||||
)}
|
||||
<Menu>
|
||||
{({ isOpen }) => (
|
||||
<>
|
||||
<MenuButton
|
||||
as={IAIIconButton}
|
||||
icon={isOpen ? <MdArrowDropUp /> : <MdArrowDropDown />}
|
||||
className="cancel-options-btn"
|
||||
tooltip={t('parameters:cancel.setType')}
|
||||
{...rest}
|
||||
/>
|
||||
<MenuList className="cancel-options-btn-context-menu">
|
||||
<MenuItem onClick={() => dispatch(setCancelType('immediate'))}>
|
||||
{t('parameters:cancel.immediate')}
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => dispatch(setCancelType('scheduled'))}>
|
||||
{t('parameters:cancel.schedule')}
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
</ButtonGroup>
|
||||
);
|
||||
}
|
||||
|
@ -24,6 +24,32 @@
|
||||
);
|
||||
}
|
||||
|
||||
.cancel-options-btn {
|
||||
@include Button(
|
||||
$btn-color: var(--destructive-color),
|
||||
$btn-color-hover: var(--destructive-color-hover),
|
||||
$btn-width: 1rem,
|
||||
);
|
||||
border-color: var(--background-color-secondary);
|
||||
border-left-width: 0.05rem;
|
||||
}
|
||||
|
||||
.cancel-options-btn-context-menu {
|
||||
z-index: 15;
|
||||
background-color: var(--background-color-secondary);
|
||||
color: var(--text-color-secondary);
|
||||
|
||||
[role='menuitem'] {
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-color-secondary);
|
||||
background-color: var(--background-color-secondary);
|
||||
&:focus {
|
||||
color: var(--text-color);
|
||||
background-color: var(--border-color-light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.loopback-btn {
|
||||
&[data-as-checkbox='true'] {
|
||||
background-color: var(--btn-btn-base-color);
|
||||
|
@ -23,6 +23,8 @@ export type ReadinessPayload = {
|
||||
|
||||
export type InProgressImageType = 'none' | 'full-res' | 'latents';
|
||||
|
||||
export type CancelType = 'immediate' | 'scheduled';
|
||||
|
||||
export interface SystemState
|
||||
extends InvokeAI.SystemStatus,
|
||||
InvokeAI.SystemConfig {
|
||||
@ -50,6 +52,10 @@ export interface SystemState
|
||||
searchFolder: string | null;
|
||||
foundModels: InvokeAI.FoundModel[] | null;
|
||||
openModel: string | null;
|
||||
cancelOptions: {
|
||||
cancelType: CancelType;
|
||||
cancelAfter: number | null;
|
||||
};
|
||||
}
|
||||
|
||||
const initialSystemState: SystemState = {
|
||||
@ -88,6 +94,10 @@ const initialSystemState: SystemState = {
|
||||
searchFolder: null,
|
||||
foundModels: null,
|
||||
openModel: null,
|
||||
cancelOptions: {
|
||||
cancelType: 'immediate',
|
||||
cancelAfter: null,
|
||||
},
|
||||
};
|
||||
|
||||
export const systemSlice = createSlice({
|
||||
@ -243,6 +253,12 @@ export const systemSlice = createSlice({
|
||||
setOpenModel: (state, action: PayloadAction<string | null>) => {
|
||||
state.openModel = action.payload;
|
||||
},
|
||||
setCancelType: (state, action: PayloadAction<CancelType>) => {
|
||||
state.cancelOptions.cancelType = action.payload;
|
||||
},
|
||||
setCancelAfter: (state, action: PayloadAction<number | null>) => {
|
||||
state.cancelOptions.cancelAfter = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -274,6 +290,8 @@ export const {
|
||||
setSearchFolder,
|
||||
setFoundModels,
|
||||
setOpenModel,
|
||||
setCancelType,
|
||||
setCancelAfter,
|
||||
} = systemSlice.actions;
|
||||
|
||||
export default systemSlice.reducer;
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user