mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
wip buttons
This commit is contained in:
parent
8eca3bbbcd
commit
3651cf7ee2
@ -718,10 +718,11 @@
|
|||||||
"swapSizes": "Swap Sizes"
|
"swapSizes": "Swap Sizes"
|
||||||
},
|
},
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"reloadSchema": "Reload Schema",
|
"reloadSchema": "Reload Node Templates",
|
||||||
"saveGraph": "Save Graph",
|
"saveGraph": "Save Workflow",
|
||||||
"loadGraph": "Load Graph (saved from Node Editor) (Do not copy-paste metadata)",
|
"loadGraph": "Load Workflow",
|
||||||
"clearGraph": "Clear Graph",
|
"resetGraph": "Reset Workflow",
|
||||||
|
"clearGraph": "Reset Graph",
|
||||||
"clearGraphDesc": "Are you sure you want to clear all nodes?",
|
"clearGraphDesc": "Are you sure you want to clear all nodes?",
|
||||||
"zoomInNodes": "Zoom In",
|
"zoomInNodes": "Zoom In",
|
||||||
"zoomOutNodes": "Zoom Out",
|
"zoomOutNodes": "Zoom Out",
|
||||||
|
@ -32,6 +32,10 @@ const selector = createSelector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (activeTabName === 'nodes' && nodes.shouldValidateGraph) {
|
if (activeTabName === 'nodes' && nodes.shouldValidateGraph) {
|
||||||
|
if (!nodes.nodes.length) {
|
||||||
|
reasons.push('No nodes in graph');
|
||||||
|
}
|
||||||
|
|
||||||
nodes.nodes.forEach((node) => {
|
nodes.nodes.forEach((node) => {
|
||||||
if (!isInvocationNode(node)) {
|
if (!isInvocationNode(node)) {
|
||||||
return;
|
return;
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
import { Box } from '@chakra-ui/react';
|
|
||||||
import { userInvoked } from 'app/store/actions';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|
||||||
import IAIButton, { IAIButtonProps } from 'common/components/IAIButton';
|
|
||||||
import { IAIIconButtonProps } from 'common/components/IAIIconButton';
|
|
||||||
import { useIsReadyToInvoke } from 'common/hooks/useIsReadyToInvoke';
|
|
||||||
import { InvokeButtonTooltipContent } from 'features/parameters/components/ProcessButtons/InvokeButton';
|
|
||||||
import ProgressBar from 'features/system/components/ProgressBar';
|
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
|
||||||
import { memo, useCallback } from 'react';
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { FaPlay } from 'react-icons/fa';
|
|
||||||
|
|
||||||
interface InvokeButton
|
|
||||||
extends Omit<IAIButtonProps | IAIIconButtonProps, 'aria-label'> {}
|
|
||||||
|
|
||||||
const NodeInvokeButton = (props: InvokeButton) => {
|
|
||||||
const { ...rest } = props;
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
|
||||||
const { isReady, isProcessing } = useIsReadyToInvoke();
|
|
||||||
const handleInvoke = useCallback(() => {
|
|
||||||
dispatch(userInvoked('nodes'));
|
|
||||||
}, [dispatch]);
|
|
||||||
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
['ctrl+enter', 'meta+enter'],
|
|
||||||
handleInvoke,
|
|
||||||
{
|
|
||||||
enabled: () => isReady,
|
|
||||||
preventDefault: true,
|
|
||||||
enableOnFormTags: ['input', 'textarea', 'select'],
|
|
||||||
},
|
|
||||||
[isReady, activeTabName]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box style={{ flexGrow: 4 }} position="relative">
|
|
||||||
<Box style={{ position: 'relative' }}>
|
|
||||||
{!isReady && (
|
|
||||||
<Box
|
|
||||||
borderRadius="base"
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
bottom: '0',
|
|
||||||
left: '0',
|
|
||||||
right: '0',
|
|
||||||
height: '100%',
|
|
||||||
overflow: 'clip',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ProgressBar />
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
<IAIButton
|
|
||||||
tooltip={<InvokeButtonTooltipContent />}
|
|
||||||
aria-label={t('parameters.invoke')}
|
|
||||||
type="submit"
|
|
||||||
isDisabled={!isReady}
|
|
||||||
onClick={handleInvoke}
|
|
||||||
flexGrow={1}
|
|
||||||
w="100%"
|
|
||||||
colorScheme="accent"
|
|
||||||
id="invoke-button"
|
|
||||||
leftIcon={isProcessing ? undefined : <FaPlay />}
|
|
||||||
fontWeight={700}
|
|
||||||
isLoading={isProcessing}
|
|
||||||
loadingText={t('parameters.invoke')}
|
|
||||||
{...rest}
|
|
||||||
>
|
|
||||||
Invoke
|
|
||||||
</IAIButton>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(NodeInvokeButton);
|
|
@ -1,5 +1,5 @@
|
|||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
import IAIButton from 'common/components/IAIButton';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaSyncAlt } from 'react-icons/fa';
|
import { FaSyncAlt } from 'react-icons/fa';
|
||||||
@ -14,12 +14,14 @@ const ReloadSchemaButton = () => {
|
|||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAIIconButton
|
<IAIButton
|
||||||
icon={<FaSyncAlt />}
|
leftIcon={<FaSyncAlt />}
|
||||||
tooltip={t('nodes.reloadSchema')}
|
tooltip={t('nodes.reloadSchema')}
|
||||||
aria-label={t('nodes.reloadSchema')}
|
aria-label={t('nodes.reloadSchema')}
|
||||||
onClick={handleReloadSchema}
|
onClick={handleReloadSchema}
|
||||||
/>
|
>
|
||||||
|
{t('nodes.reloadSchema')}
|
||||||
|
</IAIButton>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,24 +1,14 @@
|
|||||||
import { HStack } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import CancelButton from 'features/parameters/components/ProcessButtons/CancelButton';
|
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { Panel } from 'reactflow';
|
import { Panel } from 'reactflow';
|
||||||
import NodeEditorSettings from './NodeEditorSettings';
|
import WorkflowEditorControls from './WorkflowEditorControls';
|
||||||
import ClearGraphButton from './ClearGraphButton';
|
|
||||||
import NodeInvokeButton from './NodeInvokeButton';
|
|
||||||
import ReloadSchemaButton from './ReloadSchemaButton';
|
|
||||||
import LoadWorkflowButton from './LoadWorkflowButton';
|
|
||||||
|
|
||||||
const TopCenterPanel = () => {
|
const TopCenterPanel = () => {
|
||||||
return (
|
return (
|
||||||
<Panel position="top-center">
|
<Panel position="top-center">
|
||||||
<HStack>
|
<Flex gap={2}>
|
||||||
<NodeInvokeButton />
|
<WorkflowEditorControls />
|
||||||
<CancelButton />
|
</Flex>
|
||||||
<ReloadSchemaButton />
|
|
||||||
<ClearGraphButton />
|
|
||||||
<NodeEditorSettings />
|
|
||||||
<LoadWorkflowButton />
|
|
||||||
</HStack>
|
|
||||||
</Panel>
|
</Panel>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
import CancelButton from 'features/parameters/components/ProcessButtons/CancelButton';
|
||||||
|
import InvokeButton from 'features/parameters/components/ProcessButtons/InvokeButton';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import ClearGraphButton from './ClearGraphButton';
|
||||||
|
import LoadWorkflowButton from './LoadWorkflowButton';
|
||||||
|
|
||||||
|
const WorkflowEditorControls = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<InvokeButton />
|
||||||
|
<CancelButton />
|
||||||
|
<ClearGraphButton />
|
||||||
|
<LoadWorkflowButton />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(WorkflowEditorControls);
|
@ -2,6 +2,7 @@ import { useAppSelector } from 'app/store/storeHooks';
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { Panel } from 'reactflow';
|
import { Panel } from 'reactflow';
|
||||||
import FieldTypeLegend from './FieldTypeLegend';
|
import FieldTypeLegend from './FieldTypeLegend';
|
||||||
|
import WorkflowEditorSettings from './WorkflowEditorSettings';
|
||||||
|
|
||||||
const TopRightPanel = () => {
|
const TopRightPanel = () => {
|
||||||
const shouldShowFieldTypeLegend = useAppSelector(
|
const shouldShowFieldTypeLegend = useAppSelector(
|
||||||
@ -10,6 +11,7 @@ const TopRightPanel = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Panel position="top-right">
|
<Panel position="top-right">
|
||||||
|
<WorkflowEditorSettings />
|
||||||
{shouldShowFieldTypeLegend && <FieldTypeLegend />}
|
{shouldShowFieldTypeLegend && <FieldTypeLegend />}
|
||||||
</Panel>
|
</Panel>
|
||||||
);
|
);
|
||||||
|
@ -27,6 +27,11 @@ import {
|
|||||||
import { ChangeEvent, memo, useCallback } from 'react';
|
import { ChangeEvent, memo, useCallback } from 'react';
|
||||||
import { FaCog } from 'react-icons/fa';
|
import { FaCog } from 'react-icons/fa';
|
||||||
import { SelectionMode } from 'reactflow';
|
import { SelectionMode } from 'reactflow';
|
||||||
|
import ReloadSchemaButton from '../TopCenterPanel/ReloadSchemaButton';
|
||||||
|
|
||||||
|
const formLabelProps: FormLabelProps = {
|
||||||
|
fontWeight: 600,
|
||||||
|
};
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
stateSelector,
|
stateSelector,
|
||||||
@ -49,7 +54,7 @@ const selector = createSelector(
|
|||||||
defaultSelectorOptions
|
defaultSelectorOptions
|
||||||
);
|
);
|
||||||
|
|
||||||
const NodeEditorSettings = () => {
|
const WorkflowEditorSettings = () => {
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const {
|
const {
|
||||||
@ -98,7 +103,8 @@ const NodeEditorSettings = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
aria-label="Node Editor Settings"
|
aria-label="Workflow Editor Settings"
|
||||||
|
tooltip="Workflow Editor Settings"
|
||||||
icon={<FaCog />}
|
icon={<FaCog />}
|
||||||
onClick={onOpen}
|
onClick={onOpen}
|
||||||
/>
|
/>
|
||||||
@ -106,7 +112,7 @@ const NodeEditorSettings = () => {
|
|||||||
<Modal isOpen={isOpen} onClose={onClose} size="2xl" isCentered>
|
<Modal isOpen={isOpen} onClose={onClose} size="2xl" isCentered>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
<ModalHeader>Node Editor Settings</ModalHeader>
|
<ModalHeader>Workflow Editor Settings</ModalHeader>
|
||||||
<ModalCloseButton />
|
<ModalCloseButton />
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Flex
|
<Flex
|
||||||
@ -157,6 +163,7 @@ const NodeEditorSettings = () => {
|
|||||||
label="Validate Connections and Graph"
|
label="Validate Connections and Graph"
|
||||||
helperText="Prevent invalid connections from being made, and invalid graphs from being invoked"
|
helperText="Prevent invalid connections from being made, and invalid graphs from being invoked"
|
||||||
/>
|
/>
|
||||||
|
<ReloadSchemaButton />
|
||||||
</Flex>
|
</Flex>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
@ -165,8 +172,4 @@ const NodeEditorSettings = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(NodeEditorSettings);
|
export default memo(WorkflowEditorSettings);
|
||||||
|
|
||||||
const formLabelProps: FormLabelProps = {
|
|
||||||
fontWeight: 600,
|
|
||||||
};
|
|
@ -7,14 +7,11 @@ import { zWorkflow } from 'features/nodes/types/types';
|
|||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { makeToast } from 'features/system/util/makeToast';
|
import { makeToast } from 'features/system/util/makeToast';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { flushSync } from 'react-dom';
|
|
||||||
import { useReactFlow } from 'reactflow';
|
|
||||||
import { ZodError } from 'zod';
|
import { ZodError } from 'zod';
|
||||||
import { fromZodError, fromZodIssue } from 'zod-validation-error';
|
import { fromZodError, fromZodIssue } from 'zod-validation-error';
|
||||||
|
|
||||||
export const useLoadWorkflowFromFile = () => {
|
export const useLoadWorkflowFromFile = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { fitView } = useReactFlow();
|
|
||||||
const logger = useLogger('nodes');
|
const logger = useLogger('nodes');
|
||||||
const loadWorkflowFromFile = useCallback(
|
const loadWorkflowFromFile = useCallback(
|
||||||
(file: File | null) => {
|
(file: File | null) => {
|
||||||
@ -51,7 +48,6 @@ export const useLoadWorkflowFromFile = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dispatch(workflowLoaded(result.data));
|
dispatch(workflowLoaded(result.data));
|
||||||
flushSync(fitView);
|
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
addToast(
|
addToast(
|
||||||
@ -79,7 +75,7 @@ export const useLoadWorkflowFromFile = () => {
|
|||||||
|
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
},
|
},
|
||||||
[dispatch, fitView, logger]
|
[dispatch, logger]
|
||||||
);
|
);
|
||||||
|
|
||||||
return loadWorkflowFromFile;
|
return loadWorkflowFromFile;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
ChakraProps,
|
|
||||||
Divider,
|
Divider,
|
||||||
Flex,
|
Flex,
|
||||||
ListItem,
|
ListItem,
|
||||||
@ -19,7 +18,6 @@ import IAIIconButton, {
|
|||||||
import { useIsReadyToInvoke } from 'common/hooks/useIsReadyToInvoke';
|
import { useIsReadyToInvoke } from 'common/hooks/useIsReadyToInvoke';
|
||||||
import { clampSymmetrySteps } from 'features/parameters/store/generationSlice';
|
import { clampSymmetrySteps } from 'features/parameters/store/generationSlice';
|
||||||
import ProgressBar from 'features/system/components/ProgressBar';
|
import ProgressBar from 'features/system/components/ProgressBar';
|
||||||
import { selectIsBusy } from 'features/system/store/systemSelectors';
|
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
@ -27,32 +25,6 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { FaPlay } from 'react-icons/fa';
|
import { FaPlay } from 'react-icons/fa';
|
||||||
import { useBoardName } from 'services/api/hooks/useBoardName';
|
import { useBoardName } from 'services/api/hooks/useBoardName';
|
||||||
|
|
||||||
const IN_PROGRESS_STYLES: ChakraProps['sx'] = {
|
|
||||||
_disabled: {
|
|
||||||
bg: 'none',
|
|
||||||
color: 'base.600',
|
|
||||||
cursor: 'not-allowed',
|
|
||||||
_hover: {
|
|
||||||
color: 'base.600',
|
|
||||||
bg: 'none',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const selector = createSelector(
|
|
||||||
[stateSelector, activeTabNameSelector, selectIsBusy],
|
|
||||||
({ gallery }, activeTabName, isBusy) => {
|
|
||||||
const { autoAddBoardId } = gallery;
|
|
||||||
|
|
||||||
return {
|
|
||||||
isBusy,
|
|
||||||
autoAddBoardId,
|
|
||||||
activeTabName,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
defaultSelectorOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
interface InvokeButton
|
interface InvokeButton
|
||||||
extends Omit<IAIButtonProps | IAIIconButtonProps, 'aria-label'> {
|
extends Omit<IAIButtonProps | IAIIconButtonProps, 'aria-label'> {
|
||||||
asIconButton?: boolean;
|
asIconButton?: boolean;
|
||||||
@ -62,7 +34,7 @@ export default function InvokeButton(props: InvokeButton) {
|
|||||||
const { asIconButton = false, sx, ...rest } = props;
|
const { asIconButton = false, sx, ...rest } = props;
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { isReady, isProcessing } = useIsReadyToInvoke();
|
const { isReady, isProcessing } = useIsReadyToInvoke();
|
||||||
const { activeTabName } = useAppSelector(selector);
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||||
|
|
||||||
const handleInvoke = useCallback(() => {
|
const handleInvoke = useCallback(() => {
|
||||||
dispatch(clampSymmetrySteps());
|
dispatch(clampSymmetrySteps());
|
||||||
@ -113,10 +85,10 @@ export default function InvokeButton(props: InvokeButton) {
|
|||||||
colorScheme="accent"
|
colorScheme="accent"
|
||||||
isLoading={isProcessing}
|
isLoading={isProcessing}
|
||||||
id="invoke-button"
|
id="invoke-button"
|
||||||
|
data-progress={isProcessing}
|
||||||
sx={{
|
sx={{
|
||||||
w: 'full',
|
w: 'full',
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
...(isProcessing ? IN_PROGRESS_STYLES : {}),
|
|
||||||
...sx,
|
...sx,
|
||||||
}}
|
}}
|
||||||
{...rest}
|
{...rest}
|
||||||
@ -126,6 +98,7 @@ export default function InvokeButton(props: InvokeButton) {
|
|||||||
tooltip={<InvokeButtonTooltipContent />}
|
tooltip={<InvokeButtonTooltipContent />}
|
||||||
aria-label={t('parameters.invoke')}
|
aria-label={t('parameters.invoke')}
|
||||||
type="submit"
|
type="submit"
|
||||||
|
data-progress={isProcessing}
|
||||||
isDisabled={!isReady}
|
isDisabled={!isReady}
|
||||||
onClick={handleInvoke}
|
onClick={handleInvoke}
|
||||||
colorScheme="accent"
|
colorScheme="accent"
|
||||||
@ -137,7 +110,6 @@ export default function InvokeButton(props: InvokeButton) {
|
|||||||
w: 'full',
|
w: 'full',
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
...(isProcessing ? IN_PROGRESS_STYLES : {}),
|
|
||||||
...sx,
|
...sx,
|
||||||
}}
|
}}
|
||||||
{...rest}
|
{...rest}
|
||||||
@ -150,9 +122,21 @@ export default function InvokeButton(props: InvokeButton) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tooltipSelector = createSelector(
|
||||||
|
[stateSelector],
|
||||||
|
({ gallery }) => {
|
||||||
|
const { autoAddBoardId } = gallery;
|
||||||
|
|
||||||
|
return {
|
||||||
|
autoAddBoardId,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
defaultSelectorOptions
|
||||||
|
);
|
||||||
|
|
||||||
export const InvokeButtonTooltipContent = memo(() => {
|
export const InvokeButtonTooltipContent = memo(() => {
|
||||||
const { isReady, reasons } = useIsReadyToInvoke();
|
const { isReady, reasons } = useIsReadyToInvoke();
|
||||||
const { autoAddBoardId } = useAppSelector(selector);
|
const { autoAddBoardId } = useAppSelector(tooltipSelector);
|
||||||
const autoAddBoardName = useBoardName(autoAddBoardId);
|
const autoAddBoardName = useBoardName(autoAddBoardId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -15,7 +15,7 @@ const InvokeAILogoComponent = ({ showVersion = true }: Props) => {
|
|||||||
const isHovered = useHoverDirty(ref);
|
const isHovered = useHoverDirty(ref);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex alignItems="center" gap={3} ps={1} ref={ref}>
|
<Flex alignItems="center" gap={5} ps={1} ref={ref}>
|
||||||
<Image
|
<Image
|
||||||
src={InvokeAILogoImage}
|
src={InvokeAILogoImage}
|
||||||
alt="invoke-ai-logo"
|
alt="invoke-ai-logo"
|
||||||
|
@ -3,7 +3,7 @@ import { PayloadAction, createSlice, isAnyOf } from '@reduxjs/toolkit';
|
|||||||
import { InvokeLogLevel } from 'app/logging/logger';
|
import { InvokeLogLevel } from 'app/logging/logger';
|
||||||
import { userInvoked } from 'app/store/actions';
|
import { userInvoked } from 'app/store/actions';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { startCase, upperFirst } from 'lodash-es';
|
import { get, startCase, upperFirst } from 'lodash-es';
|
||||||
import { LogLevelName } from 'roarr';
|
import { LogLevelName } from 'roarr';
|
||||||
import {
|
import {
|
||||||
isAnySessionRejected,
|
isAnySessionRejected,
|
||||||
@ -368,14 +368,14 @@ export const systemSlice = createSlice({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (action.payload?.error) {
|
} else if (action.payload?.error) {
|
||||||
errorDescription = action.payload?.error as string;
|
errorDescription = action.payload?.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.toastQueue.push(
|
state.toastQueue.push(
|
||||||
makeToast({
|
makeToast({
|
||||||
title: t('toast.serverError'),
|
title: t('toast.serverError'),
|
||||||
status: 'error',
|
status: 'error',
|
||||||
description: errorDescription,
|
description: get(errorDescription, 'detail', 'Unknown Error'),
|
||||||
duration,
|
duration,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -8,7 +8,16 @@ const invokeAI = defineStyle((props) => {
|
|||||||
if (c === 'base') {
|
if (c === 'base') {
|
||||||
const _disabled = {
|
const _disabled = {
|
||||||
bg: mode('base.150', 'base.700')(props),
|
bg: mode('base.150', 'base.700')(props),
|
||||||
color: mode('base.500', 'base.500')(props),
|
color: mode('base.300', 'base.500')(props),
|
||||||
|
svg: {
|
||||||
|
fill: mode('base.500', 'base.500')(props),
|
||||||
|
},
|
||||||
|
opacity: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const data_progress = {
|
||||||
|
bg: 'none',
|
||||||
|
color: mode('base.300', 'base.500')(props),
|
||||||
svg: {
|
svg: {
|
||||||
fill: mode('base.500', 'base.500')(props),
|
fill: mode('base.500', 'base.500')(props),
|
||||||
},
|
},
|
||||||
@ -31,6 +40,7 @@ const invokeAI = defineStyle((props) => {
|
|||||||
_disabled,
|
_disabled,
|
||||||
},
|
},
|
||||||
_disabled,
|
_disabled,
|
||||||
|
'&[data-progress="true"]': { ...data_progress, _hover: data_progress },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +55,17 @@ const invokeAI = defineStyle((props) => {
|
|||||||
filter: mode(undefined, 'saturate(65%)')(props),
|
filter: mode(undefined, 'saturate(65%)')(props),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const data_progress = {
|
||||||
|
// bg: 'none',
|
||||||
|
color: mode(`${c}.50`, `${c}.500`)(props),
|
||||||
|
svg: {
|
||||||
|
fill: mode(`${c}.50`, `${c}.500`)(props),
|
||||||
|
filter: 'unset',
|
||||||
|
},
|
||||||
|
opacity: 0.7,
|
||||||
|
filter: mode(undefined, 'saturate(65%)')(props),
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bg: mode(`${c}.400`, `${c}.600`)(props),
|
bg: mode(`${c}.400`, `${c}.600`)(props),
|
||||||
color: mode(`base.50`, `base.100`)(props),
|
color: mode(`base.50`, `base.100`)(props),
|
||||||
@ -61,6 +82,7 @@ const invokeAI = defineStyle((props) => {
|
|||||||
},
|
},
|
||||||
_disabled,
|
_disabled,
|
||||||
},
|
},
|
||||||
|
'&[data-progress="true"]': { ...data_progress, _hover: data_progress },
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ const { defineMultiStyleConfig, definePartsStyle } =
|
|||||||
createMultiStyleConfigHelpers(parts.keys);
|
createMultiStyleConfigHelpers(parts.keys);
|
||||||
|
|
||||||
const invokeAIFilledTrack = defineStyle((_props) => ({
|
const invokeAIFilledTrack = defineStyle((_props) => ({
|
||||||
bg: 'accentAlpha.500',
|
bg: 'accentAlpha.700',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const invokeAITrack = defineStyle((_props) => {
|
const invokeAITrack = defineStyle((_props) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user