Merge branch 'main' into feat/ui/upscale

This commit is contained in:
psychedelicious 2023-07-18 22:08:02 +10:00 committed by GitHub
commit 42c440c73f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 154 additions and 726 deletions

View File

@ -24,7 +24,8 @@ read -e -p "Tag this repo with '${VERSION}' and '${LATEST_TAG}'? [n]: " input
RESPONSE=${input:='n'} RESPONSE=${input:='n'}
if [ "$RESPONSE" == 'y' ]; then if [ "$RESPONSE" == 'y' ]; then
if ! git tag $VERSION ; then git push origin :refs/tags/$VERSION
if ! git tag -fa $VERSION ; then
echo "Existing/invalid tag" echo "Existing/invalid tag"
exit -1 exit -1
fi fi

View File

@ -38,7 +38,7 @@ echo https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist
echo. echo.
echo See %INSTRUCTIONS% for more details. echo See %INSTRUCTIONS% for more details.
echo. echo.
echo "For the best user experience we suggest enlarging or maximizing this window now." echo FOR THE BEST USER EXPERIENCE WE SUGGEST MAXIMIZING THIS WINDOW NOW.
pause pause
@rem ---------------------------- check Python version --------------- @rem ---------------------------- check Python version ---------------

View File

@ -19,7 +19,7 @@ echo 8. Open the developer console
echo 9. Update InvokeAI echo 9. Update InvokeAI
echo 10. Command-line help echo 10. Command-line help
echo Q - Quit echo Q - Quit
set /P choice="Please enter 1-10, Q: [2] " set /P choice="Please enter 1-10, Q: [1] "
if not defined choice set choice=1 if not defined choice set choice=1
IF /I "%choice%" == "1" ( IF /I "%choice%" == "1" (
echo Starting the InvokeAI browser-based UI.. echo Starting the InvokeAI browser-based UI..

View File

@ -130,7 +130,7 @@ class CompelInvocation(BaseInvocation):
text_encoder=text_encoder, text_encoder=text_encoder,
textual_inversion_manager=ti_manager, textual_inversion_manager=ti_manager,
dtype_for_device_getter=torch_dtype, dtype_for_device_getter=torch_dtype,
truncate_long_prompts=False, truncate_long_prompts=True,
) )
conjunction = Compel.parse_prompt_string(self.prompt) conjunction = Compel.parse_prompt_string(self.prompt)

View File

@ -69,7 +69,6 @@ transformers.logging.set_verbosity_error()
config = InvokeAIAppConfig.get_config() config = InvokeAIAppConfig.get_config()
Model_dir = "models" Model_dir = "models"
Weights_dir = "ldm/stable-diffusion-v1/"
Default_config_file = config.model_conf_path Default_config_file = config.model_conf_path
SD_Configs = config.legacy_conf_path SD_Configs = config.legacy_conf_path
@ -634,7 +633,7 @@ def run_console_ui(
# The third argument is needed in the Windows 11 environment to # The third argument is needed in the Windows 11 environment to
# launch a console window running this program. # launch a console window running this program.
set_min_terminal_size(MIN_COLS, MIN_LINES,'invokeai-configure') set_min_terminal_size(MIN_COLS, MIN_LINES)
# the install-models application spawns a subprocess to install # the install-models application spawns a subprocess to install
# models, and will crash unless this is set before running. # models, and will crash unless this is set before running.
@ -711,7 +710,7 @@ def migrate_if_needed(opt: Namespace, root: Path)->bool:
old_init_file = root / 'invokeai.init' old_init_file = root / 'invokeai.init'
new_init_file = root / 'invokeai.yaml' new_init_file = root / 'invokeai.yaml'
old_hub = root / 'models/hub' old_hub = root / 'models/hub'
migration_needed = old_init_file.exists() and not new_init_file.exists() or old_hub.exists() migration_needed = (old_init_file.exists() and not new_init_file.exists()) and old_hub.exists()
if migration_needed: if migration_needed:
if opt.yes_to_all or \ if opt.yes_to_all or \

View File

@ -102,5 +102,6 @@ sd-1/embedding/ahx-beta-453407d:
repo_id: sd-concepts-library/ahx-beta-453407d repo_id: sd-concepts-library/ahx-beta-453407d
sd-1/lora/LowRA: sd-1/lora/LowRA:
path: https://civitai.com/api/download/models/63006 path: https://civitai.com/api/download/models/63006
recommended: True
sd-1/lora/Ink scenery: sd-1/lora/Ink scenery:
path: https://civitai.com/api/download/models/83390 path: https://civitai.com/api/download/models/83390

View File

@ -701,7 +701,7 @@ def select_and_download_models(opt: Namespace):
# the third argument is needed in the Windows 11 environment in # the third argument is needed in the Windows 11 environment in
# order to launch and resize a console window running this program # order to launch and resize a console window running this program
set_min_terminal_size(MIN_COLS, MIN_LINES,'invokeai-model-install') set_min_terminal_size(MIN_COLS, MIN_LINES)
installApp = AddModelApplication(opt) installApp = AddModelApplication(opt)
try: try:
installApp.run() installApp.run()

View File

@ -17,28 +17,20 @@ from shutil import get_terminal_size
from curses import BUTTON2_CLICKED,BUTTON3_CLICKED from curses import BUTTON2_CLICKED,BUTTON3_CLICKED
# minimum size for UIs # minimum size for UIs
MIN_COLS = 130 MIN_COLS = 136
MIN_LINES = 45 MIN_LINES = 45
# ------------------------------------- # -------------------------------------
def set_terminal_size(columns: int, lines: int, launch_command: str=None): def set_terminal_size(columns: int, lines: int):
ts = get_terminal_size() ts = get_terminal_size()
width = max(columns,ts.columns) width = max(columns,ts.columns)
height = max(lines,ts.lines) height = max(lines,ts.lines)
OS = platform.uname().system OS = platform.uname().system
if OS == "Windows": if OS == "Windows":
# The new Windows Terminal doesn't resize, so we relaunch in a CMD window. pass
# Would prefer to use execvpe() here, but somehow it is not working properly # not working reliably - ask user to adjust the window
# in the Windows 10 environment. #_set_terminal_size_powershell(width,height)
if 'IA_RELAUNCHED' not in os.environ:
args=['conhost']
args.extend([launch_command] if launch_command else [sys.argv[0]])
args.extend(sys.argv[1:])
os.environ['IA_RELAUNCHED'] = 'True'
os.execvp('conhost',args)
else:
_set_terminal_size_powershell(width,height)
elif OS in ["Darwin", "Linux"]: elif OS in ["Darwin", "Linux"]:
_set_terminal_size_unix(width,height) _set_terminal_size_unix(width,height)
@ -84,20 +76,14 @@ def _set_terminal_size_unix(width: int, height: int):
sys.stdout.write("\x1b[8;{height};{width}t".format(height=height, width=width)) sys.stdout.write("\x1b[8;{height};{width}t".format(height=height, width=width))
sys.stdout.flush() sys.stdout.flush()
def set_min_terminal_size(min_cols: int, min_lines: int, launch_command: str=None): def set_min_terminal_size(min_cols: int, min_lines: int):
# make sure there's enough room for the ui # make sure there's enough room for the ui
term_cols, term_lines = get_terminal_size() term_cols, term_lines = get_terminal_size()
if term_cols >= min_cols and term_lines >= min_lines: if term_cols >= min_cols and term_lines >= min_lines:
return return
cols = max(term_cols, min_cols) cols = max(term_cols, min_cols)
lines = max(term_lines, min_lines) lines = max(term_lines, min_lines)
set_terminal_size(cols, lines, launch_command) set_terminal_size(cols, lines)
# did it work?
term_cols, term_lines = get_terminal_size()
if term_cols < cols or term_lines < lines:
print(f'This window is too small for optimal display. For best results please enlarge it.')
input('After resizing, press any key to continue...')
class IntSlider(npyscreen.Slider): class IntSlider(npyscreen.Slider):
def translate_value(self): def translate_value(self):

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

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,7 @@
margin: 0; margin: 0;
} }
</style> </style>
<script type="module" crossorigin src="./assets/index-8888b06f.js"></script> <script type="module" crossorigin src="./assets/index-f1a5f9cf.js"></script>
</head> </head>
<body dir="ltr"> <body dir="ltr">

View File

@ -1,7 +1,9 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
import { shiftKeyPressed } from 'features/ui/store/hotkeysSlice'; import { shiftKeyPressed } from 'features/ui/store/hotkeysSlice';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { import {
setActiveTab, setActiveTab,
toggleGalleryPanel, toggleGalleryPanel,
@ -14,10 +16,11 @@ import React, { memo } from 'react';
import { isHotkeyPressed, useHotkeys } from 'react-hotkeys-hook'; import { isHotkeyPressed, useHotkeys } from 'react-hotkeys-hook';
const globalHotkeysSelector = createSelector( const globalHotkeysSelector = createSelector(
(state: RootState) => state.hotkeys, [(state: RootState) => state.hotkeys, (state: RootState) => state.ui],
(hotkeys) => { (hotkeys, ui) => {
const { shift } = hotkeys; const { shift } = hotkeys;
return { shift }; const { shouldPinParametersPanel, shouldPinGallery } = ui;
return { shift, shouldPinGallery, shouldPinParametersPanel };
}, },
{ {
memoizeOptions: { memoizeOptions: {
@ -34,7 +37,10 @@ const globalHotkeysSelector = createSelector(
*/ */
const GlobalHotkeys: React.FC = () => { const GlobalHotkeys: React.FC = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { shift } = useAppSelector(globalHotkeysSelector); const { shift, shouldPinParametersPanel, shouldPinGallery } = useAppSelector(
globalHotkeysSelector
);
const activeTabName = useAppSelector(activeTabNameSelector);
useHotkeys( useHotkeys(
'*', '*',
@ -51,18 +57,30 @@ const GlobalHotkeys: React.FC = () => {
useHotkeys('o', () => { useHotkeys('o', () => {
dispatch(toggleParametersPanel()); dispatch(toggleParametersPanel());
if (activeTabName === 'unifiedCanvas' && shouldPinParametersPanel) {
dispatch(requestCanvasRescale());
}
}); });
useHotkeys(['shift+o'], () => { useHotkeys(['shift+o'], () => {
dispatch(togglePinParametersPanel()); dispatch(togglePinParametersPanel());
if (activeTabName === 'unifiedCanvas') {
dispatch(requestCanvasRescale());
}
}); });
useHotkeys('g', () => { useHotkeys('g', () => {
dispatch(toggleGalleryPanel()); dispatch(toggleGalleryPanel());
if (activeTabName === 'unifiedCanvas' && shouldPinGallery) {
dispatch(requestCanvasRescale());
}
}); });
useHotkeys(['shift+g'], () => { useHotkeys(['shift+g'], () => {
dispatch(togglePinGalleryPanel()); dispatch(togglePinGalleryPanel());
if (activeTabName === 'unifiedCanvas') {
dispatch(requestCanvasRescale());
}
}); });
useHotkeys('1', () => { useHotkeys('1', () => {

View File

@ -11,6 +11,7 @@ import {
setIsMouseOverBoundingBox, setIsMouseOverBoundingBox,
setIsMovingBoundingBox, setIsMovingBoundingBox,
setIsTransformingBoundingBox, setIsTransformingBoundingBox,
setShouldSnapToGrid,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { uiSelector } from 'features/ui/store/uiSelectors'; import { uiSelector } from 'features/ui/store/uiSelectors';
import Konva from 'konva'; import Konva from 'konva';
@ -20,6 +21,7 @@ import { Vector2d } from 'konva/lib/types';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { useCallback, useEffect, useRef, useState } from 'react'; import { useCallback, useEffect, useRef, useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { Group, Rect, Transformer } from 'react-konva'; import { Group, Rect, Transformer } from 'react-konva';
const boundingBoxPreviewSelector = createSelector( const boundingBoxPreviewSelector = createSelector(
@ -91,6 +93,10 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => {
const scaledStep = 64 * stageScale; const scaledStep = 64 * stageScale;
useHotkeys('N', () => {
dispatch(setShouldSnapToGrid(!shouldSnapToGrid));
});
const handleOnDragMove = useCallback( const handleOnDragMove = useCallback(
(e: KonvaEventObject<DragEvent>) => { (e: KonvaEventObject<DragEvent>) => {
if (!shouldSnapToGrid) { if (!shouldSnapToGrid) {

View File

@ -139,7 +139,7 @@ const IAICanvasToolChooserOptions = () => {
); );
useHotkeys( useHotkeys(
['shift+BracketLeft'], ['Shift+BracketLeft'],
() => { () => {
dispatch( dispatch(
setBrushColor({ setBrushColor({
@ -156,7 +156,7 @@ const IAICanvasToolChooserOptions = () => {
); );
useHotkeys( useHotkeys(
['shift+BracketRight'], ['Shift+BracketRight'],
() => { () => {
dispatch( dispatch(
setBrushColor({ setBrushColor({

View File

@ -110,8 +110,11 @@ const SelectItem = forwardRef<HTMLDivElement, ItemProps>(
return ( return (
<div ref={ref} {...others}> <div ref={ref} {...others}>
<div> <div>
<Text>{label}</Text> <Text fontWeight={600}>{label}</Text>
<Text size="xs" color="base.600"> <Text
size="xs"
sx={{ color: 'base.600', _dark: { color: 'base.500' } }}
>
{description} {description}
</Text> </Text>
</div> </div>

View File

@ -20,8 +20,8 @@ const IAINodeHeader = (props: IAINodeHeaderProps) => {
justifyContent: 'space-between', justifyContent: 'space-between',
px: 2, px: 2,
py: 1, py: 1,
bg: 'base.300', bg: 'base.100',
_dark: { bg: 'base.700' }, _dark: { bg: 'base.900' },
}} }}
> >
<Tooltip label={nodeId}> <Tooltip label={nodeId}>
@ -30,7 +30,7 @@ const IAINodeHeader = (props: IAINodeHeaderProps) => {
sx={{ sx={{
fontWeight: 600, fontWeight: 600,
color: 'base.900', color: 'base.900',
_dark: { color: 'base.100' }, _dark: { color: 'base.200' },
}} }}
> >
{title} {title}

View File

@ -59,7 +59,7 @@ export const InvocationComponent = memo((props: NodeProps<InvocationValue>) => {
flexDirection: 'column', flexDirection: 'column',
borderBottomRadius: 'md', borderBottomRadius: 'md',
py: 2, py: 2,
bg: 'base.200', bg: 'base.150',
_dark: { bg: 'base.800' }, _dark: { bg: 'base.800' },
}} }}
> >

View File

@ -1,9 +1,9 @@
import 'reactflow/dist/style.css';
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { ReactFlowProvider } from 'reactflow'; import { ReactFlowProvider } from 'reactflow';
import 'reactflow/dist/style.css';
import { Flow } from './Flow';
import { memo } from 'react'; import { memo } from 'react';
import { Flow } from './Flow';
const NodeEditor = () => { const NodeEditor = () => {
return ( return (

View File

@ -1,9 +1,9 @@
import { Box, useToken } from '@chakra-ui/react'; import { Box, useToken } from '@chakra-ui/react';
import { NODE_MIN_WIDTH } from 'app/constants'; import { NODE_MIN_WIDTH } from 'app/constants';
import { useAppSelector } from 'app/store/storeHooks';
import { PropsWithChildren } from 'react'; import { PropsWithChildren } from 'react';
import { DRAG_HANDLE_CLASSNAME } from '../hooks/useBuildInvocation'; import { DRAG_HANDLE_CLASSNAME } from '../hooks/useBuildInvocation';
import { useAppSelector } from 'app/store/storeHooks';
type NodeWrapperProps = PropsWithChildren & { type NodeWrapperProps = PropsWithChildren & {
selected: boolean; selected: boolean;

View File

@ -36,7 +36,7 @@ const ParamMainModelSelect = () => {
const data: SelectItem[] = []; const data: SelectItem[] = [];
forEach(mainModels.entities, (model, id) => { forEach(mainModels.entities, (model, id) => {
if (!model) { if (!model || ['sdxl', 'sdxl-refiner'].includes(model.base_model)) {
return; return;
} }

View File

@ -15,7 +15,7 @@ import {
ModalOverlay, ModalOverlay,
useDisclosure, useDisclosure,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { cloneElement, ReactElement } from 'react'; import { ReactElement, cloneElement } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import HotkeysModalItem from './HotkeysModalItem'; import HotkeysModalItem from './HotkeysModalItem';
@ -65,11 +65,6 @@ export default function HotkeysModal({ children }: HotkeysModalProps) {
desc: t('hotkeys.pinOptions.desc'), desc: t('hotkeys.pinOptions.desc'),
hotkey: 'Shift+O', hotkey: 'Shift+O',
}, },
{
title: t('hotkeys.toggleViewer.title'),
desc: t('hotkeys.toggleViewer.desc'),
hotkey: 'Z',
},
{ {
title: t('hotkeys.toggleGallery.title'), title: t('hotkeys.toggleGallery.title'),
desc: t('hotkeys.toggleGallery.desc'), desc: t('hotkeys.toggleGallery.desc'),
@ -85,12 +80,6 @@ export default function HotkeysModal({ children }: HotkeysModalProps) {
desc: t('hotkeys.changeTabs.desc'), desc: t('hotkeys.changeTabs.desc'),
hotkey: '1-5', hotkey: '1-5',
}, },
{
title: t('hotkeys.consoleToggle.title'),
desc: t('hotkeys.consoleToggle.desc'),
hotkey: '`',
},
]; ];
const generalHotkeys = [ const generalHotkeys = [
@ -109,11 +98,6 @@ export default function HotkeysModal({ children }: HotkeysModalProps) {
desc: t('hotkeys.setParameters.desc'), desc: t('hotkeys.setParameters.desc'),
hotkey: 'A', hotkey: 'A',
}, },
{
title: t('hotkeys.restoreFaces.title'),
desc: t('hotkeys.restoreFaces.desc'),
hotkey: 'Shift+R',
},
{ {
title: t('hotkeys.upscale.title'), title: t('hotkeys.upscale.title'),
desc: t('hotkeys.upscale.desc'), desc: t('hotkeys.upscale.desc'),

View File

@ -183,7 +183,7 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
> >
<ModalOverlay /> <ModalOverlay />
<ModalContent> <ModalContent>
<ModalHeader>{t('common.settingsLabel')}</ModalHeader> <ModalHeader bg="none">{t('common.settingsLabel')}</ModalHeader>
<ModalCloseButton /> <ModalCloseButton />
<ModalBody> <ModalBody>
<Flex sx={{ gap: 4, flexDirection: 'column' }}> <Flex sx={{ gap: 4, flexDirection: 'column' }}>
@ -331,12 +331,15 @@ export default SettingsModal;
const StyledFlex = (props: PropsWithChildren) => { const StyledFlex = (props: PropsWithChildren) => {
return ( return (
<Flex <Flex
layerStyle="second"
sx={{ sx={{
flexDirection: 'column', flexDirection: 'column',
gap: 2, gap: 2,
p: 4, p: 4,
borderRadius: 'base', borderRadius: 'base',
bg: 'base.100',
_dark: {
bg: 'base.900',
},
}} }}
> >
{props.children} {props.children}

View File

@ -3,7 +3,7 @@ import { EntityState } from '@reduxjs/toolkit';
import IAIButton from 'common/components/IAIButton'; import IAIButton from 'common/components/IAIButton';
import IAIInput from 'common/components/IAIInput'; import IAIInput from 'common/components/IAIInput';
import { forEach } from 'lodash-es'; import { forEach } from 'lodash-es';
import type { ChangeEvent } from 'react'; import type { ChangeEvent, PropsWithChildren } from 'react';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { import {
@ -44,13 +44,7 @@ const ModelList = (props: ModelListProps) => {
return ( return (
<Flex flexDirection="column" rowGap={4} width="50%" minWidth="50%"> <Flex flexDirection="column" rowGap={4} width="50%" minWidth="50%">
<Flex <Flex flexDirection="column" gap={4} paddingInlineEnd={4}>
flexDirection="column"
gap={4}
maxHeight={window.innerHeight - 240}
overflow="scroll"
paddingInlineEnd={4}
>
<ButtonGroup isAttached> <ButtonGroup isAttached>
<IAIButton <IAIButton
onClick={() => setModelFormatFilter('all')} onClick={() => setModelFormatFilter('all')}
@ -83,35 +77,39 @@ const ModelList = (props: ModelListProps) => {
{['all', 'diffusers'].includes(modelFormatFilter) && {['all', 'diffusers'].includes(modelFormatFilter) &&
filteredDiffusersModels.length > 0 && ( filteredDiffusersModels.length > 0 && (
<Flex sx={{ gap: 2, flexDir: 'column' }}> <StyledModelContainer>
<Text variant="subtext" fontSize="sm"> <Flex sx={{ gap: 2, flexDir: 'column' }}>
Diffusers <Text variant="subtext" fontSize="sm">
</Text> Diffusers
{filteredDiffusersModels.map((model) => ( </Text>
<ModelListItem {filteredDiffusersModels.map((model) => (
key={model.id} <ModelListItem
model={model} key={model.id}
isSelected={selectedModelId === model.id} model={model}
setSelectedModelId={setSelectedModelId} isSelected={selectedModelId === model.id}
/> setSelectedModelId={setSelectedModelId}
))} />
</Flex> ))}
</Flex>
</StyledModelContainer>
)} )}
{['all', 'checkpoint'].includes(modelFormatFilter) && {['all', 'checkpoint'].includes(modelFormatFilter) &&
filteredCheckpointModels.length > 0 && ( filteredCheckpointModels.length > 0 && (
<Flex sx={{ gap: 2, flexDir: 'column' }}> <StyledModelContainer>
<Text variant="subtext" fontSize="sm"> <Flex sx={{ gap: 2, flexDir: 'column' }}>
Checkpoint <Text variant="subtext" fontSize="sm">
</Text> Checkpoint
{filteredCheckpointModels.map((model) => ( </Text>
<ModelListItem {filteredCheckpointModels.map((model) => (
key={model.id} <ModelListItem
model={model} key={model.id}
isSelected={selectedModelId === model.id} model={model}
setSelectedModelId={setSelectedModelId} isSelected={selectedModelId === model.id}
/> setSelectedModelId={setSelectedModelId}
))} />
</Flex> ))}
</Flex>
</StyledModelContainer>
)} )}
</Flex> </Flex>
</Flex> </Flex>
@ -143,3 +141,24 @@ const modelsFilter = (
}); });
return filteredModels; return filteredModels;
}; };
const StyledModelContainer = (props: PropsWithChildren) => {
return (
<Flex
flexDirection="column"
maxHeight={window.innerHeight - 280}
overflow="scroll"
gap={4}
borderRadius={4}
p={4}
sx={{
bg: 'base.200',
_dark: {
bg: 'base.800',
},
}}
>
{props.children}
</Flex>
);
};

View File

@ -1,5 +1,5 @@
import { DeleteIcon } from '@chakra-ui/icons'; import { DeleteIcon } from '@chakra-ui/icons';
import { Flex, Text, Tooltip } from '@chakra-ui/react'; import { Badge, Flex, Text, Tooltip } from '@chakra-ui/react';
import { makeToast } from 'app/components/Toaster'; import { makeToast } from 'app/components/Toaster';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIAlertDialog from 'common/components/IAIAlertDialog'; import IAIAlertDialog from 'common/components/IAIAlertDialog';
@ -20,6 +20,13 @@ type ModelListItemProps = {
setSelectedModelId: (v: string | undefined) => void; setSelectedModelId: (v: string | undefined) => void;
}; };
const modelBaseTypeMap = {
'sd-1': 'SD1',
'sd-2': 'SD2',
sdxl: 'SDXL',
'sdxl-refiner': 'SDXLR',
};
export default function ModelListItem(props: ModelListItemProps) { export default function ModelListItem(props: ModelListItemProps) {
const isBusy = useAppSelector(selectIsBusy); const isBusy = useAppSelector(selectIsBusy);
const { t } = useTranslation(); const { t } = useTranslation();
@ -76,7 +83,7 @@ export default function ModelListItem(props: ModelListItemProps) {
bg: isSelected ? 'accent.400' : 'base.100', bg: isSelected ? 'accent.400' : 'base.100',
color: isSelected ? 'base.50' : 'base.800', color: isSelected ? 'base.50' : 'base.800',
_hover: { _hover: {
bg: isSelected ? 'accent.500' : 'base.200', bg: isSelected ? 'accent.500' : 'base.300',
color: isSelected ? 'base.50' : 'base.800', color: isSelected ? 'base.50' : 'base.800',
}, },
_dark: { _dark: {
@ -84,15 +91,33 @@ export default function ModelListItem(props: ModelListItemProps) {
bg: isSelected ? 'accent.600' : 'base.850', bg: isSelected ? 'accent.600' : 'base.850',
_hover: { _hover: {
color: isSelected ? 'base.50' : 'base.100', color: isSelected ? 'base.50' : 'base.100',
bg: isSelected ? 'accent.550' : 'base.800', bg: isSelected ? 'accent.550' : 'base.700',
}, },
}, },
}} }}
onClick={handleSelectModel} onClick={handleSelectModel}
> >
<Tooltip label={model.description} hasArrow placement="bottom"> <Flex gap={4} alignItems="center">
<Text sx={{ fontWeight: 500 }}>{model.model_name}</Text> <Badge
</Tooltip> minWidth={14}
p={1}
fontSize="sm"
sx={{
bg: 'base.350',
color: 'base.900',
_dark: { bg: 'base.500' },
}}
>
{
modelBaseTypeMap[
model.base_model as keyof typeof modelBaseTypeMap
]
}
</Badge>
<Tooltip label={model.description} hasArrow placement="bottom">
<Text sx={{ fontWeight: 500 }}>{model.model_name}</Text>
</Tooltip>
</Flex>
</Flex> </Flex>
<IAIAlertDialog <IAIAlertDialog
title={t('modelManager.deleteModel')} title={t('modelManager.deleteModel')}

View File

@ -13,13 +13,13 @@ import { popoverTheme } from './components/popover';
import { progressTheme } from './components/progress'; import { progressTheme } from './components/progress';
import { no_scrollbar } from './components/scrollbar'; import { no_scrollbar } from './components/scrollbar';
import { selectTheme } from './components/select'; import { selectTheme } from './components/select';
import { skeletonTheme } from './components/skeleton';
import { sliderTheme } from './components/slider'; import { sliderTheme } from './components/slider';
import { switchTheme } from './components/switch'; import { switchTheme } from './components/switch';
import { tabsTheme } from './components/tabs'; import { tabsTheme } from './components/tabs';
import { textTheme } from './components/text'; import { textTheme } from './components/text';
import { textareaTheme } from './components/textarea'; import { textareaTheme } from './components/textarea';
import { tooltipTheme } from './components/tooltip'; import { tooltipTheme } from './components/tooltip';
import { skeletonTheme } from './components/skeleton';
export const theme: ThemeOverride = { export const theme: ThemeOverride = {
config: { config: {
@ -74,7 +74,7 @@ export const theme: ThemeOverride = {
'0px 0px 0px 1px var(--invokeai-colors-base-150), 0px 0px 0px 4px var(--invokeai-colors-accent-400)', '0px 0px 0px 1px var(--invokeai-colors-base-150), 0px 0px 0px 4px var(--invokeai-colors-accent-400)',
dark: '0px 0px 0px 1px var(--invokeai-colors-base-900), 0px 0px 0px 4px var(--invokeai-colors-accent-400)', dark: '0px 0px 0px 1px var(--invokeai-colors-base-900), 0px 0px 0px 4px var(--invokeai-colors-accent-400)',
}, },
nodeSelectedOutline: `0 0 0 2px var(--invokeai-colors-base-500)`, nodeSelectedOutline: `0 0 0 2px var(--invokeai-colors-accent-450)`,
}, },
colors: InvokeAIColors, colors: InvokeAIColors,
components: { components: {

View File

@ -1 +1 @@
__version__ = "3.0.0+b6" __version__ = "3.0.0+b7"

View File

@ -38,7 +38,7 @@ dependencies = [
"albumentations", "albumentations",
"click", "click",
"clip_anytorch", # replacing "clip @ https://github.com/openai/CLIP/archive/eaa22acb90a5876642d0507623e859909230a52d.zip", "clip_anytorch", # replacing "clip @ https://github.com/openai/CLIP/archive/eaa22acb90a5876642d0507623e859909230a52d.zip",
"compel==2.0.0rc2", "compel==2.0.0",
"controlnet-aux>=0.0.6", "controlnet-aux>=0.0.6",
"timm==0.6.13", # needed to override timm latest in controlnet_aux, see https://github.com/isl-org/ZoeDepth/issues/26 "timm==0.6.13", # needed to override timm latest in controlnet_aux, see https://github.com/isl-org/ZoeDepth/issues/26
"datasets", "datasets",