mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Styling changes and settings modal minor refactor
This commit is contained in:
parent
1e51c39928
commit
cefe12f1df
1
frontend/dist/assets/index.14c578ee.css
vendored
1
frontend/dist/assets/index.14c578ee.css
vendored
File diff suppressed because one or more lines are too long
517
frontend/dist/assets/index.552c95d8.js
vendored
Normal file
517
frontend/dist/assets/index.552c95d8.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
frontend/dist/assets/index.67342d6d.css
vendored
Normal file
1
frontend/dist/assets/index.67342d6d.css
vendored
Normal file
File diff suppressed because one or more lines are too long
501
frontend/dist/assets/index.ae6d2a5e.js
vendored
501
frontend/dist/assets/index.ae6d2a5e.js
vendored
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" />
|
<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.ae6d2a5e.js"></script>
|
<script type="module" crossorigin src="./assets/index.552c95d8.js"></script>
|
||||||
<link rel="stylesheet" href="./assets/index.14c578ee.css">
|
<link rel="stylesheet" href="./assets/index.67342d6d.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -3,11 +3,7 @@ import {
|
|||||||
IconButton,
|
IconButton,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipProps,
|
TooltipProps,
|
||||||
ResponsiveValue,
|
|
||||||
ThemingProps,
|
|
||||||
isChakraTheme,
|
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { Variant } from 'framer-motion';
|
|
||||||
|
|
||||||
interface Props extends IconButtonProps {
|
interface Props extends IconButtonProps {
|
||||||
styleClass?: string;
|
styleClass?: string;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
@use '../../styles/Mixins/' as *;
|
@use '../../styles/Mixins/' as *;
|
||||||
|
|
||||||
.invokeai__select {
|
.invokeai__select {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: repeat(2, max-content);
|
|
||||||
column-gap: 1rem;
|
column-gap: 1rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
import { FormControl, FormLabel, Select, SelectProps } from '@chakra-ui/react';
|
import { FormControl, FormLabel, Select, SelectProps } from '@chakra-ui/react';
|
||||||
import { MouseEvent } from 'react';
|
import { MouseEvent } from 'react';
|
||||||
|
|
||||||
interface Props extends SelectProps {
|
type IAISelectProps = SelectProps & {
|
||||||
label: string;
|
label: string;
|
||||||
styleClass?: string;
|
styleClass?: string;
|
||||||
validValues:
|
validValues:
|
||||||
| Array<number | string>
|
| Array<number | string>
|
||||||
| Array<{ key: string; value: string | number }>;
|
| Array<{ key: string; value: string | number }>;
|
||||||
}
|
};
|
||||||
/**
|
/**
|
||||||
* Customized Chakra FormControl + Select multi-part component.
|
* Customized Chakra FormControl + Select multi-part component.
|
||||||
*/
|
*/
|
||||||
const IAISelect = (props: Props) => {
|
const IAISelect = (props: IAISelectProps) => {
|
||||||
const {
|
const {
|
||||||
label,
|
label,
|
||||||
isDisabled,
|
isDisabled,
|
||||||
@ -33,19 +33,19 @@ const IAISelect = (props: Props) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FormLabel
|
<FormLabel
|
||||||
|
className="invokeai__select-label"
|
||||||
fontSize={fontSize}
|
fontSize={fontSize}
|
||||||
marginBottom={1}
|
marginBottom={1}
|
||||||
flexGrow={2}
|
flexGrow={2}
|
||||||
whiteSpace="nowrap"
|
whiteSpace="nowrap"
|
||||||
className="invokeai__select-label"
|
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<Select
|
<Select
|
||||||
|
className="invokeai__select-picker"
|
||||||
fontSize={fontSize}
|
fontSize={fontSize}
|
||||||
size={size}
|
size={size}
|
||||||
{...rest}
|
{...rest}
|
||||||
className="invokeai__select-picker"
|
|
||||||
>
|
>
|
||||||
{validValues.map((opt) => {
|
{validValues.map((opt) => {
|
||||||
return typeof opt === 'string' || typeof opt === 'number' ? (
|
return typeof opt === 'string' || typeof opt === 'number' ? (
|
||||||
@ -53,7 +53,11 @@ const IAISelect = (props: Props) => {
|
|||||||
{opt}
|
{opt}
|
||||||
</option>
|
</option>
|
||||||
) : (
|
) : (
|
||||||
<option key={opt.value} value={opt.value}>
|
<option
|
||||||
|
key={opt.value}
|
||||||
|
value={opt.value}
|
||||||
|
className="invokeai__select-option"
|
||||||
|
>
|
||||||
{opt.key}
|
{opt.key}
|
||||||
</option>
|
</option>
|
||||||
);
|
);
|
||||||
|
@ -22,8 +22,6 @@ const IAISwitch = (props: Props) => {
|
|||||||
const {
|
const {
|
||||||
label,
|
label,
|
||||||
isDisabled = false,
|
isDisabled = false,
|
||||||
// fontSize = 'md',
|
|
||||||
// size = 'md',
|
|
||||||
width = 'auto',
|
width = 'auto',
|
||||||
formControlProps,
|
formControlProps,
|
||||||
formLabelProps,
|
formLabelProps,
|
||||||
@ -39,17 +37,11 @@ const IAISwitch = (props: Props) => {
|
|||||||
>
|
>
|
||||||
<FormLabel
|
<FormLabel
|
||||||
className="invokeai__switch-form-label"
|
className="invokeai__switch-form-label"
|
||||||
// fontSize={fontSize}
|
|
||||||
whiteSpace="nowrap"
|
whiteSpace="nowrap"
|
||||||
{...formLabelProps}
|
{...formLabelProps}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
<Switch
|
<Switch className="invokeai__switch-root" {...rest} />
|
||||||
className="invokeai__switch-root"
|
|
||||||
// size={size}
|
|
||||||
// className="switch-button"
|
|
||||||
{...rest}
|
|
||||||
/>
|
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
row-gap: 1rem;
|
row-gap: 1rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
background-color: var(--background-color);
|
||||||
|
|
||||||
&.is-drag-accept {
|
&.is-drag-accept {
|
||||||
box-shadow: inset 0 0 20rem 1rem var(--accent-color);
|
box-shadow: inset 0 0 20rem 1rem var(--accent-color);
|
||||||
|
@ -6,6 +6,7 @@ import { uploadImage } from '../../app/socketio/actions';
|
|||||||
import { ImageUploadDestination, UploadImagePayload } from '../../app/invokeai';
|
import { ImageUploadDestination, UploadImagePayload } from '../../app/invokeai';
|
||||||
import { ImageUploaderTriggerContext } from '../../app/contexts/ImageUploaderTriggerContext';
|
import { ImageUploaderTriggerContext } from '../../app/contexts/ImageUploaderTriggerContext';
|
||||||
import { activeTabNameSelector } from '../../features/options/optionsSelectors';
|
import { activeTabNameSelector } from '../../features/options/optionsSelectors';
|
||||||
|
import { tabDict } from '../../features/tabs/InvokeTabs';
|
||||||
|
|
||||||
type ImageUploaderProps = {
|
type ImageUploaderProps = {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@ -128,6 +129,12 @@ const ImageUploader = (props: ImageUploaderProps) => {
|
|||||||
};
|
};
|
||||||
}, [dispatch, toast, activeTabName]);
|
}, [dispatch, toast, activeTabName]);
|
||||||
|
|
||||||
|
const overlaySecondaryText = ['img2img', 'inpainting'].includes(
|
||||||
|
activeTabName
|
||||||
|
)
|
||||||
|
? ` to ${tabDict[activeTabName as keyof typeof tabDict].tooltip}`
|
||||||
|
: ``;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ImageUploaderTriggerContext.Provider value={open}>
|
<ImageUploaderTriggerContext.Provider value={open}>
|
||||||
<div {...getRootProps({ style: {} })}>
|
<div {...getRootProps({ style: {} })}>
|
||||||
@ -137,7 +144,7 @@ const ImageUploader = (props: ImageUploaderProps) => {
|
|||||||
<div className="dropzone-container">
|
<div className="dropzone-container">
|
||||||
{isDragAccept && (
|
{isDragAccept && (
|
||||||
<div className="dropzone-overlay is-drag-accept">
|
<div className="dropzone-overlay is-drag-accept">
|
||||||
<Heading size={'lg'}>Drop Images</Heading>
|
<Heading size={'lg'}>Upload Image{overlaySecondaryText}</Heading>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isDragReject && (
|
{isDragReject && (
|
||||||
|
@ -26,6 +26,9 @@ export const imagesSelector = createSelector(
|
|||||||
isOnLastImage:
|
isOnLastImage:
|
||||||
!isNaN(currentImageIndex) && currentImageIndex === imagesLength - 1,
|
!isNaN(currentImageIndex) && currentImageIndex === imagesLength - 1,
|
||||||
shouldShowImageDetails,
|
shouldShowImageDetails,
|
||||||
|
shouldShowPrevImageButton: currentImageIndex === 0,
|
||||||
|
shouldShowNextImageButton:
|
||||||
|
!isNaN(currentImageIndex) && currentImageIndex === imagesLength - 1,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.image-gallery-wrapper {
|
.image-gallery-wrapper {
|
||||||
z-index: 100;
|
|
||||||
|
|
||||||
&[data-pinned='false'] {
|
&[data-pinned='false'] {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
@ -261,6 +261,7 @@ export default function ImageGallery() {
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="image-gallery-wrapper"
|
className="image-gallery-wrapper"
|
||||||
|
style={{ zIndex: shouldPinGallery ? 1 : 100 }}
|
||||||
data-pinned={shouldPinGallery}
|
data-pinned={shouldPinGallery}
|
||||||
ref={galleryRef}
|
ref={galleryRef}
|
||||||
onMouseLeave={!shouldPinGallery ? setCloseGalleryTimer : undefined}
|
onMouseLeave={!shouldPinGallery ? setCloseGalleryTimer : undefined}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
.main-option-block {
|
.main-option-block {
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
|
display: grid !important;
|
||||||
grid-template-columns: auto !important;
|
grid-template-columns: auto !important;
|
||||||
row-gap: 0.4rem;
|
row-gap: 0.4rem;
|
||||||
|
|
||||||
|
@ -1,24 +1,37 @@
|
|||||||
.model-list {
|
// .chakra-accordion {
|
||||||
.chakra-accordion {
|
// display: grid;
|
||||||
display: grid;
|
// row-gap: 0.5rem;
|
||||||
row-gap: 0.5rem;
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
.chakra-accordion__item {
|
// .chakra-accordion__item {
|
||||||
border: none;
|
// border: none;
|
||||||
border-radius: 0.3rem;
|
// }
|
||||||
background-color: var(--tab-hover-color);
|
|
||||||
}
|
// button {
|
||||||
|
// border-radius: 0.3rem !important;
|
||||||
|
|
||||||
|
// &[aria-expanded='true'] {
|
||||||
|
// // background-color: var(--tab-hover-color);
|
||||||
|
// border-radius: 0.3rem;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
.model-list-accordion {
|
||||||
|
outline: none;
|
||||||
|
padding: 0.25rem;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border-radius: 0.3rem !important;
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
&[aria-expanded='true'] {
|
&:hover {
|
||||||
background-color: var(--tab-hover-color);
|
background-color: unset;
|
||||||
border-radius: 0.3rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.model-list-button {
|
.model-list-button {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -64,6 +77,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.model-list-item-load-btn {
|
.model-list-item-load-btn {
|
||||||
|
button {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,31 +73,33 @@ const ModelList = () => {
|
|||||||
const { models } = useAppSelector(modelListSelector);
|
const { models } = useAppSelector(modelListSelector);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="model-list">
|
<Accordion
|
||||||
<Accordion allowToggle>
|
allowToggle
|
||||||
<AccordionItem>
|
className="model-list-accordion"
|
||||||
<AccordionButton>
|
variant={'unstyled'}
|
||||||
<div className="model-list-button">
|
>
|
||||||
<h2>Models</h2>
|
<AccordionItem>
|
||||||
<AccordionIcon />
|
<AccordionButton>
|
||||||
</div>
|
<div className="model-list-button">
|
||||||
</AccordionButton>
|
<h2>Models</h2>
|
||||||
|
<AccordionIcon />
|
||||||
|
</div>
|
||||||
|
</AccordionButton>
|
||||||
|
|
||||||
<AccordionPanel>
|
<AccordionPanel>
|
||||||
<div className="model-list-list">
|
<div className="model-list-list">
|
||||||
{models.map((model, i) => (
|
{models.map((model, i) => (
|
||||||
<ModelListItem
|
<ModelListItem
|
||||||
key={i}
|
key={i}
|
||||||
name={model.name}
|
name={model.name}
|
||||||
status={model.status}
|
status={model.status}
|
||||||
description={model.description}
|
description={model.description}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,18 +14,18 @@ import {
|
|||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import _, { isEqual } from 'lodash';
|
import _, { isEqual } from 'lodash';
|
||||||
import { cloneElement, ReactElement } from 'react';
|
import { ChangeEvent, cloneElement, ReactElement } from 'react';
|
||||||
import { RootState, useAppSelector } from '../../../app/store';
|
import { RootState, useAppDispatch, useAppSelector } from '../../../app/store';
|
||||||
import { persistor } from '../../../main';
|
import { persistor } from '../../../main';
|
||||||
import {
|
import {
|
||||||
setShouldConfirmOnDelete,
|
setShouldConfirmOnDelete,
|
||||||
setShouldDisplayGuides,
|
setShouldDisplayGuides,
|
||||||
setShouldDisplayInProgressType,
|
|
||||||
SystemState,
|
SystemState,
|
||||||
} from '../systemSlice';
|
} from '../systemSlice';
|
||||||
import ModelList from './ModelList';
|
import ModelList from './ModelList';
|
||||||
import { SettingsModalItem, SettingsModalSelectItem } from './SettingsModalItem';
|
|
||||||
import { IN_PROGRESS_IMAGE_TYPES } from '../../../app/constants';
|
import { IN_PROGRESS_IMAGE_TYPES } from '../../../app/constants';
|
||||||
|
import IAISwitch from '../../../common/components/IAISwitch';
|
||||||
|
import IAISelect from '../../../common/components/IAISelect';
|
||||||
|
|
||||||
const systemSelector = createSelector(
|
const systemSelector = createSelector(
|
||||||
(state: RootState) => state.system,
|
(state: RootState) => state.system,
|
||||||
@ -60,6 +60,8 @@ type SettingsModalProps = {
|
|||||||
* Secondary post-reset modal is included here.
|
* Secondary post-reset modal is included here.
|
||||||
*/
|
*/
|
||||||
const SettingsModal = ({ children }: SettingsModalProps) => {
|
const SettingsModal = ({ children }: SettingsModalProps) => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen: isSettingsModalOpen,
|
isOpen: isSettingsModalOpen,
|
||||||
onOpen: onSettingsModalOpen,
|
onOpen: onSettingsModalOpen,
|
||||||
@ -101,26 +103,32 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
|
|||||||
<ModalHeader className="settings-modal-header">Settings</ModalHeader>
|
<ModalHeader className="settings-modal-header">Settings</ModalHeader>
|
||||||
<ModalCloseButton />
|
<ModalCloseButton />
|
||||||
<ModalBody className="settings-modal-content">
|
<ModalBody className="settings-modal-content">
|
||||||
<ModelList />
|
|
||||||
<div className="settings-modal-items">
|
<div className="settings-modal-items">
|
||||||
|
<div className="settings-modal-item">
|
||||||
<SettingsModalSelectItem
|
<ModelList />
|
||||||
settingTitle="Display In-Progress Images"
|
</div>
|
||||||
|
<IAISelect
|
||||||
|
styleClass="settings-modal-item"
|
||||||
|
label={'Display In-Progress Images'}
|
||||||
validValues={IN_PROGRESS_IMAGE_TYPES}
|
validValues={IN_PROGRESS_IMAGE_TYPES}
|
||||||
defaultValue={shouldDisplayInProgressType}
|
value={shouldDisplayInProgressType}
|
||||||
dispatcher={setShouldDisplayInProgressType}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SettingsModalItem
|
<IAISwitch
|
||||||
settingTitle="Confirm on Delete"
|
styleClass="settings-modal-item"
|
||||||
|
label={'Confirm on Delete'}
|
||||||
isChecked={shouldConfirmOnDelete}
|
isChecked={shouldConfirmOnDelete}
|
||||||
dispatcher={setShouldConfirmOnDelete}
|
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||||
|
dispatch(setShouldConfirmOnDelete(e.target.checked))
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
<IAISwitch
|
||||||
<SettingsModalItem
|
styleClass="settings-modal-item"
|
||||||
settingTitle="Display Help Icons"
|
label={'Display Help Icons'}
|
||||||
isChecked={shouldDisplayGuides}
|
isChecked={shouldDisplayGuides}
|
||||||
dispatcher={setShouldDisplayGuides}
|
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||||
|
dispatch(setShouldDisplayGuides(e.target.checked))
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
import { useAppDispatch } from '../../../app/store';
|
|
||||||
import IAISelect from '../../../common/components/IAISelect';
|
|
||||||
import IAISwitch from '../../../common/components/IAISwitch';
|
|
||||||
|
|
||||||
export function SettingsModalItem({
|
|
||||||
settingTitle,
|
|
||||||
isChecked,
|
|
||||||
dispatcher,
|
|
||||||
}: {
|
|
||||||
settingTitle: string;
|
|
||||||
isChecked: boolean;
|
|
||||||
dispatcher: any;
|
|
||||||
}) {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
return (
|
|
||||||
<IAISwitch
|
|
||||||
styleClass="settings-modal-item"
|
|
||||||
label={settingTitle}
|
|
||||||
isChecked={isChecked}
|
|
||||||
onChange={(e) => dispatch(dispatcher(e.target.checked))}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function SettingsModalSelectItem({
|
|
||||||
settingTitle,
|
|
||||||
validValues,
|
|
||||||
defaultValue,
|
|
||||||
dispatcher,
|
|
||||||
}: {
|
|
||||||
settingTitle: string;
|
|
||||||
validValues:
|
|
||||||
Array<number | string>
|
|
||||||
| Array<{ key: string; value: string | number }>;
|
|
||||||
defaultValue: string;
|
|
||||||
dispatcher: any;
|
|
||||||
}) {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
return (
|
|
||||||
<IAISelect
|
|
||||||
styleClass="settings-modal-item"
|
|
||||||
label={settingTitle}
|
|
||||||
validValues={validValues}
|
|
||||||
defaultValue={defaultValue}
|
|
||||||
onChange={(e) => dispatch(dispatcher(e.target.value))}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
import { IconButton, Link, Tooltip, useColorMode } from '@chakra-ui/react';
|
import { Link, useColorMode } from '@chakra-ui/react';
|
||||||
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
|
||||||
import { FaSun, FaMoon, FaGithub, FaDiscord, FaBug } from 'react-icons/fa';
|
import { FaSun, FaMoon, FaGithub, FaDiscord, FaBug } from 'react-icons/fa';
|
||||||
import { MdHelp, MdKeyboard, MdSettings } from 'react-icons/md';
|
import { MdKeyboard, MdSettings } from 'react-icons/md';
|
||||||
|
|
||||||
import InvokeAILogo from '../../assets/images/logo.png';
|
import InvokeAILogo from '../../assets/images/logo.png';
|
||||||
import IAIIconButton from '../../common/components/IAIIconButton';
|
import IAIIconButton from '../../common/components/IAIIconButton';
|
||||||
@ -91,18 +91,18 @@ const SiteHeader = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
aria-label="Link to Discord Server"
|
aria-label="Link to Discord Server"
|
||||||
tooltip="Discord"
|
tooltip="Discord"
|
||||||
variant="link"
|
variant="link"
|
||||||
fontSize={20}
|
fontSize={20}
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
icon={
|
icon={
|
||||||
<Link isExternal href="https://discord.gg/ZmtBAhwWhy">
|
<Link isExternal href="https://discord.gg/ZmtBAhwWhy">
|
||||||
<FaDiscord />
|
<FaDiscord />
|
||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SettingsModal>
|
<SettingsModal>
|
||||||
<IAIIconButton
|
<IAIIconButton
|
||||||
|
@ -17,7 +17,7 @@ import ImageToImageWorkarea from './ImageToImage';
|
|||||||
import InpaintingWorkarea from './Inpainting';
|
import InpaintingWorkarea from './Inpainting';
|
||||||
import TextToImageWorkarea from './TextToImage';
|
import TextToImageWorkarea from './TextToImage';
|
||||||
|
|
||||||
export const tab_dict = {
|
export const tabDict = {
|
||||||
txt2img: {
|
txt2img: {
|
||||||
title: <TextToImageIcon fill={'black'} boxSize={'2.5rem'} />,
|
title: <TextToImageIcon fill={'black'} boxSize={'2.5rem'} />,
|
||||||
workarea: <TextToImageWorkarea />,
|
workarea: <TextToImageWorkarea />,
|
||||||
@ -50,8 +50,8 @@ export const tab_dict = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Array where index maps to the key of tab_dict
|
// Array where index maps to the key of tabDict
|
||||||
export const tabMap = _.map(tab_dict, (tab, key) => key);
|
export const tabMap = _.map(tabDict, (tab, key) => key);
|
||||||
|
|
||||||
// Use tabMap to generate a union type of tab names
|
// Use tabMap to generate a union type of tab names
|
||||||
const tabMapTypes = [...tabMap] as const;
|
const tabMapTypes = [...tabMap] as const;
|
||||||
@ -89,15 +89,15 @@ export default function InvokeTabs() {
|
|||||||
|
|
||||||
const renderTabs = () => {
|
const renderTabs = () => {
|
||||||
const tabsToRender: ReactElement[] = [];
|
const tabsToRender: ReactElement[] = [];
|
||||||
Object.keys(tab_dict).forEach((key) => {
|
Object.keys(tabDict).forEach((key) => {
|
||||||
tabsToRender.push(
|
tabsToRender.push(
|
||||||
<Tooltip
|
<Tooltip
|
||||||
key={key}
|
key={key}
|
||||||
hasArrow
|
hasArrow
|
||||||
label={tab_dict[key as keyof typeof tab_dict].tooltip}
|
label={tabDict[key as keyof typeof tabDict].tooltip}
|
||||||
placement={'right'}
|
placement={'right'}
|
||||||
>
|
>
|
||||||
<Tab>{tab_dict[key as keyof typeof tab_dict].title}</Tab>
|
<Tab>{tabDict[key as keyof typeof tabDict].title}</Tab>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -106,10 +106,10 @@ export default function InvokeTabs() {
|
|||||||
|
|
||||||
const renderTabPanels = () => {
|
const renderTabPanels = () => {
|
||||||
const tabPanelsToRender: ReactElement[] = [];
|
const tabPanelsToRender: ReactElement[] = [];
|
||||||
Object.keys(tab_dict).forEach((key) => {
|
Object.keys(tabDict).forEach((key) => {
|
||||||
tabPanelsToRender.push(
|
tabPanelsToRender.push(
|
||||||
<TabPanel className="app-tabs-panel" key={key}>
|
<TabPanel className="app-tabs-panel" key={key}>
|
||||||
{tab_dict[key as keyof typeof tab_dict].workarea}
|
{tabDict[key as keyof typeof tabDict].workarea}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user