mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat: Remove Header
Remove header and incorporate everything else into the side bar and other areas
This commit is contained in:
parent
4ce39a5974
commit
2250bca8d9
@ -156,6 +156,7 @@
|
||||
"save": "Save",
|
||||
"saveAs": "Save As",
|
||||
"settingsLabel": "Settings",
|
||||
"preferencesLabel": "Preferences",
|
||||
"simple": "Simple",
|
||||
"somethingWentWrong": "Something went wrong",
|
||||
"statusConnected": "Connected",
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { Flex, Grid } from '@chakra-ui/react';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useSocketIO } from 'app/hooks/useSocketIO';
|
||||
import { useLogger } from 'app/logging/useLogger';
|
||||
import { appStarted } from 'app/store/middleware/listenerMiddleware/listeners/appStarted';
|
||||
import { $headerComponent } from 'app/store/nanostores/headerComponent';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import type { PartialAppConfig } from 'app/types/invokeai';
|
||||
import ImageUploader from 'common/components/ImageUploader';
|
||||
@ -13,7 +11,6 @@ import { useGlobalModifiersInit } from 'common/hooks/useGlobalModifiers';
|
||||
import ChangeBoardModal from 'features/changeBoardModal/components/ChangeBoardModal';
|
||||
import DeleteImageModal from 'features/deleteImageModal/components/DeleteImageModal';
|
||||
import { DynamicPromptsModal } from 'features/dynamicPrompts/components/DynamicPromptsPreviewModal';
|
||||
import SiteHeader from 'features/system/components/SiteHeader';
|
||||
import { configChanged } from 'features/system/store/configSlice';
|
||||
import { languageSelector } from 'features/system/store/systemSelectors';
|
||||
import InvokeTabs from 'features/ui/components/InvokeTabs';
|
||||
@ -68,8 +65,6 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage }: Props) => {
|
||||
dispatch(appStarted());
|
||||
}, [dispatch]);
|
||||
|
||||
const headerComponent = useStore($headerComponent);
|
||||
|
||||
return (
|
||||
<ErrorBoundary
|
||||
onReset={handleReset}
|
||||
@ -77,12 +72,9 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage }: Props) => {
|
||||
>
|
||||
<Grid w="100vw" h="100vh" position="relative" overflow="hidden">
|
||||
<ImageUploader>
|
||||
<Grid p={4} gridAutoRows="min-content auto" w="full" h="full">
|
||||
{headerComponent || <SiteHeader />}
|
||||
<Flex gap={4} w="full" h="full">
|
||||
<InvokeTabs />
|
||||
</Flex>
|
||||
</Grid>
|
||||
<Flex gap={4} p={4} w="full" h="full">
|
||||
<InvokeTabs />
|
||||
</Flex>
|
||||
</ImageUploader>
|
||||
</Grid>
|
||||
<DeleteImageModal />
|
||||
|
@ -3,6 +3,7 @@ import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup'
|
||||
import ClearQueueButton from 'features/queue/components/ClearQueueButton';
|
||||
import QueueFrontButton from 'features/queue/components/QueueFrontButton';
|
||||
import ProgressBar from 'features/system/components/ProgressBar';
|
||||
import StatusIndicator from 'features/system/components/StatusIndicator';
|
||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||
import { memo } from 'react';
|
||||
|
||||
@ -29,8 +30,9 @@ const QueueControls = () => {
|
||||
{isPauseEnabled && <PauseProcessorButton asIconButton />} */}
|
||||
<ClearQueueButton asIconButton />
|
||||
</InvButtonGroup>
|
||||
<Flex h={2} w="full">
|
||||
<ProgressBar />
|
||||
<Flex h={5} w="full" alignItems="center">
|
||||
<StatusIndicator />
|
||||
<ProgressBar height={2} />
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
|
@ -2,6 +2,7 @@
|
||||
import { Flex, Image } from '@chakra-ui/react';
|
||||
import InvokeLogoYellow from 'assets/images/invoke-key-ylw-sm.svg';
|
||||
import { InvText } from 'common/components/InvText/wrapper';
|
||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||
import type { AnimationProps } from 'framer-motion';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { memo, useRef } from 'react';
|
||||
@ -14,8 +15,29 @@ const InvokeAILogoComponent = () => {
|
||||
const isHovered = useHoverDirty(ref);
|
||||
|
||||
return (
|
||||
<Flex alignItems="center" gap={5} ps={1} ref={ref}>
|
||||
<InvTooltip
|
||||
placement="right"
|
||||
label={
|
||||
<Flex gap={3} alignItems="center">
|
||||
<AnimatePresence>
|
||||
{isHovered && appVersion && (
|
||||
<motion.div
|
||||
key="statusText"
|
||||
initial={initial}
|
||||
animate={animate}
|
||||
exit={exit}
|
||||
>
|
||||
<InvText fontWeight="semibold" marginTop={1} color="base.900">
|
||||
v{appVersion.version}
|
||||
</InvText>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</Flex>
|
||||
}
|
||||
>
|
||||
<Image
|
||||
ref={ref}
|
||||
src={InvokeLogoYellow}
|
||||
alt="invoke-logo"
|
||||
w="24px"
|
||||
@ -24,23 +46,7 @@ const InvokeAILogoComponent = () => {
|
||||
minH="24px"
|
||||
userSelect="none"
|
||||
/>
|
||||
<Flex gap={3} alignItems="center">
|
||||
<AnimatePresence>
|
||||
{isHovered && appVersion && (
|
||||
<motion.div
|
||||
key="statusText"
|
||||
initial={initial}
|
||||
animate={animate}
|
||||
exit={exit}
|
||||
>
|
||||
<InvText fontWeight="semibold" marginTop={1} color="base.300">
|
||||
v{appVersion.version}
|
||||
</InvText>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</InvTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,12 @@ const progressBarSelector = createMemoizedSelector(
|
||||
}
|
||||
);
|
||||
|
||||
const ProgressBar = () => {
|
||||
type ProgressBarProps = {
|
||||
height?: number | string;
|
||||
};
|
||||
|
||||
const ProgressBar = (props: ProgressBarProps) => {
|
||||
const { height = 'full' } = props;
|
||||
const { t } = useTranslation();
|
||||
const { data: queueStatus } = useGetQueueStatusQuery();
|
||||
const { hasSteps, value, isConnected } = useAppSelector(progressBarSelector);
|
||||
@ -29,7 +34,7 @@ const ProgressBar = () => {
|
||||
isIndeterminate={
|
||||
isConnected && Boolean(queueStatus?.queue.in_progress) && !hasSteps
|
||||
}
|
||||
h="full"
|
||||
h={height}
|
||||
w="full"
|
||||
colorScheme="invokeYellow"
|
||||
/>
|
||||
|
@ -0,0 +1,101 @@
|
||||
import { useDisclosure } from '@chakra-ui/react';
|
||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||
import { InvMenuItem } from 'common/components/InvMenu/InvMenuItem';
|
||||
import { InvMenuList } from 'common/components/InvMenu/InvMenuList';
|
||||
import {
|
||||
InvMenu,
|
||||
InvMenuButton,
|
||||
InvMenuGroup,
|
||||
} from 'common/components/InvMenu/wrapper';
|
||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||
import { useGlobalMenuCloseTrigger } from 'common/hooks/useGlobalMenuCloseTrigger';
|
||||
import HotkeysModal from 'features/system/components/HotkeysModal/HotkeysModal';
|
||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
FaBars,
|
||||
FaBug,
|
||||
FaCog,
|
||||
FaDiscord,
|
||||
FaGithub,
|
||||
FaKeyboard,
|
||||
} from 'react-icons/fa';
|
||||
|
||||
import SettingsModal from './SettingsModal';
|
||||
|
||||
const SettingsMenu = () => {
|
||||
const { t } = useTranslation();
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
useGlobalMenuCloseTrigger(onClose);
|
||||
|
||||
const isBugLinkEnabled = useFeatureStatus('bugLink').isFeatureEnabled;
|
||||
const isDiscordLinkEnabled = useFeatureStatus('discordLink').isFeatureEnabled;
|
||||
const isGithubLinkEnabled = useFeatureStatus('githubLink').isFeatureEnabled;
|
||||
|
||||
const githubLink = 'http://github.com/invoke-ai/InvokeAI';
|
||||
const discordLink = 'https://discord.gg/ZmtBAhwWhy';
|
||||
|
||||
return (
|
||||
<InvMenu isOpen={isOpen} onOpen={onOpen} onClose={onClose}>
|
||||
<InvTooltip label={t('common.preferencesLabel')} placement="right">
|
||||
<InvMenuButton
|
||||
as={InvIconButton}
|
||||
variant="link"
|
||||
aria-label={t('accessibility.menu')}
|
||||
icon={<FaCog fontSize={20} />}
|
||||
boxSize={8}
|
||||
/>
|
||||
</InvTooltip>
|
||||
|
||||
<InvMenuList>
|
||||
<InvMenuGroup title={t('common.communityLabel')}>
|
||||
{isGithubLinkEnabled && (
|
||||
<InvMenuItem
|
||||
as="a"
|
||||
href={githubLink}
|
||||
target="_blank"
|
||||
icon={<FaGithub />}
|
||||
>
|
||||
{t('common.githubLabel')}
|
||||
</InvMenuItem>
|
||||
)}
|
||||
{isBugLinkEnabled && (
|
||||
<InvMenuItem
|
||||
as="a"
|
||||
href={`${githubLink}/issues`}
|
||||
target="_blank"
|
||||
icon={<FaBug />}
|
||||
>
|
||||
{t('common.reportBugLabel')}
|
||||
</InvMenuItem>
|
||||
)}
|
||||
{isDiscordLinkEnabled && (
|
||||
<InvMenuItem
|
||||
as="a"
|
||||
href={discordLink}
|
||||
target="_blank"
|
||||
icon={<FaDiscord />}
|
||||
>
|
||||
{t('common.discordLabel')}
|
||||
</InvMenuItem>
|
||||
)}
|
||||
</InvMenuGroup>
|
||||
<InvMenuGroup title={t('common.settingsLabel')}>
|
||||
<HotkeysModal>
|
||||
<InvMenuItem as="button" icon={<FaKeyboard />}>
|
||||
{t('common.hotkeysLabel')}
|
||||
</InvMenuItem>
|
||||
</HotkeysModal>
|
||||
<SettingsModal>
|
||||
<InvMenuItem as="button" icon={<FaBars />}>
|
||||
{t('common.settingsLabel')}
|
||||
</InvMenuItem>
|
||||
</SettingsModal>
|
||||
</InvMenuGroup>
|
||||
</InvMenuList>
|
||||
</InvMenu>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(SettingsMenu);
|
@ -1,105 +0,0 @@
|
||||
import { Flex, Spacer, useDisclosure } from '@chakra-ui/react';
|
||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||
import { InvMenuItem } from 'common/components/InvMenu/InvMenuItem';
|
||||
import { InvMenuList } from 'common/components/InvMenu/InvMenuList';
|
||||
import {
|
||||
InvMenu,
|
||||
InvMenuButton,
|
||||
InvMenuGroup,
|
||||
} from 'common/components/InvMenu/wrapper';
|
||||
import { useGlobalMenuCloseTrigger } from 'common/hooks/useGlobalMenuCloseTrigger';
|
||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
FaBars,
|
||||
FaBug,
|
||||
FaCog,
|
||||
FaDiscord,
|
||||
FaGithub,
|
||||
FaKeyboard,
|
||||
} from 'react-icons/fa';
|
||||
|
||||
import HotkeysModal from './HotkeysModal/HotkeysModal';
|
||||
import InvokeAILogoComponent from './InvokeAILogoComponent';
|
||||
import SettingsModal from './SettingsModal/SettingsModal';
|
||||
import StatusIndicator from './StatusIndicator';
|
||||
|
||||
const SiteHeader = () => {
|
||||
const { t } = useTranslation();
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
useGlobalMenuCloseTrigger(onClose);
|
||||
|
||||
const isBugLinkEnabled = useFeatureStatus('bugLink').isFeatureEnabled;
|
||||
const isDiscordLinkEnabled = useFeatureStatus('discordLink').isFeatureEnabled;
|
||||
const isGithubLinkEnabled = useFeatureStatus('githubLink').isFeatureEnabled;
|
||||
|
||||
const githubLink = 'http://github.com/invoke-ai/InvokeAI';
|
||||
const discordLink = 'https://discord.gg/ZmtBAhwWhy';
|
||||
|
||||
return (
|
||||
<Flex gap={2} alignItems="center">
|
||||
<InvokeAILogoComponent />
|
||||
<Spacer />
|
||||
<StatusIndicator />
|
||||
|
||||
<InvMenu isOpen={isOpen} onOpen={onOpen} onClose={onClose}>
|
||||
<InvMenuButton
|
||||
as={InvIconButton}
|
||||
variant="link"
|
||||
aria-label={t('accessibility.menu')}
|
||||
icon={<FaBars />}
|
||||
boxSize={8}
|
||||
/>
|
||||
<InvMenuList>
|
||||
<InvMenuGroup title={t('common.communityLabel')}>
|
||||
{isGithubLinkEnabled && (
|
||||
<InvMenuItem
|
||||
as="a"
|
||||
href={githubLink}
|
||||
target="_blank"
|
||||
icon={<FaGithub />}
|
||||
>
|
||||
{t('common.githubLabel')}
|
||||
</InvMenuItem>
|
||||
)}
|
||||
{isBugLinkEnabled && (
|
||||
<InvMenuItem
|
||||
as="a"
|
||||
href={`${githubLink}/issues`}
|
||||
target="_blank"
|
||||
icon={<FaBug />}
|
||||
>
|
||||
{t('common.reportBugLabel')}
|
||||
</InvMenuItem>
|
||||
)}
|
||||
{isDiscordLinkEnabled && (
|
||||
<InvMenuItem
|
||||
as="a"
|
||||
href={discordLink}
|
||||
target="_blank"
|
||||
icon={<FaDiscord />}
|
||||
>
|
||||
{t('common.discordLabel')}
|
||||
</InvMenuItem>
|
||||
)}
|
||||
</InvMenuGroup>
|
||||
<InvMenuGroup title={t('common.settingsLabel')}>
|
||||
<HotkeysModal>
|
||||
<InvMenuItem as="button" icon={<FaKeyboard />}>
|
||||
{t('common.hotkeysLabel')}
|
||||
</InvMenuItem>
|
||||
</HotkeysModal>
|
||||
<SettingsModal>
|
||||
<InvMenuItem as="button" icon={<FaCog />}>
|
||||
{t('common.settingsLabel')}
|
||||
</InvMenuItem>
|
||||
</SettingsModal>
|
||||
</InvMenuGroup>
|
||||
</InvMenuList>
|
||||
</InvMenu>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(SiteHeader);
|
@ -3,9 +3,8 @@ import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { stateSelector } from 'app/store/store';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { InvText } from 'common/components/InvText/wrapper';
|
||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||
import { STATUS_TRANSLATION_KEYS } from 'features/system/store/types';
|
||||
import type { AnimationProps } from 'framer-motion';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import type { ResourceKey } from 'i18next';
|
||||
import { memo, useMemo, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -54,15 +53,13 @@ const StatusIndicator = () => {
|
||||
const isHovered = useHoverDirty(ref);
|
||||
|
||||
return (
|
||||
<Flex ref={ref} h="full" px={2} alignItems="center" gap={5}>
|
||||
<AnimatePresence>
|
||||
{isHovered && (
|
||||
<motion.div
|
||||
key="statusText"
|
||||
initial={initial}
|
||||
animate={animate}
|
||||
exit={exit}
|
||||
>
|
||||
<Flex ref={ref} alignItems="center" p={2} pl={0}>
|
||||
<InvTooltip
|
||||
left={10}
|
||||
bottom={-24}
|
||||
background="base.800"
|
||||
label={
|
||||
isHovered && (
|
||||
<InvText
|
||||
fontSize="sm"
|
||||
fontWeight="semibold"
|
||||
@ -72,24 +69,13 @@ const StatusIndicator = () => {
|
||||
>
|
||||
{t(statusTranslationKey as ResourceKey)}
|
||||
</InvText>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
<Icon as={FaCircle} boxSize="0.5rem" color={COLOR_MAP[statusColor]} />
|
||||
)
|
||||
}
|
||||
>
|
||||
<Icon as={FaCircle} boxSize="0.6rem" color={COLOR_MAP[statusColor]} />
|
||||
</InvTooltip>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(StatusIndicator);
|
||||
|
||||
const initial: AnimationProps['initial'] = {
|
||||
opacity: 0,
|
||||
};
|
||||
const animate: AnimationProps['animate'] = {
|
||||
opacity: 1,
|
||||
transition: { duration: 0.1 },
|
||||
};
|
||||
const exit: AnimationProps['exit'] = {
|
||||
opacity: 0,
|
||||
transition: { delay: 0.8 },
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Spacer } from '@chakra-ui/react';
|
||||
import { Flex, Spacer } from '@chakra-ui/react';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { stateSelector } from 'app/store/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
@ -13,6 +13,8 @@ import {
|
||||
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||
import ImageGalleryContent from 'features/gallery/components/ImageGalleryContent';
|
||||
import NodeEditorPanelGroup from 'features/nodes/components/sidePanel/NodeEditorPanelGroup';
|
||||
import InvokeAILogoComponent from 'features/system/components/InvokeAILogoComponent';
|
||||
import SettingsMenu from 'features/system/components/SettingsModal/SettingsMenu';
|
||||
import type { UsePanelOptions } from 'features/ui/hooks/usePanel';
|
||||
import { usePanel } from 'features/ui/hooks/usePanel';
|
||||
import { usePanelStorage } from 'features/ui/hooks/usePanelStorage';
|
||||
@ -249,10 +251,14 @@ const InvokeTabs = () => {
|
||||
gap={4}
|
||||
isLazy
|
||||
>
|
||||
<InvTabList gap={4} pt={4} flexDir="column">
|
||||
{tabs}
|
||||
<Spacer />
|
||||
</InvTabList>
|
||||
<Flex flexDir="column" alignItems="center" pt={2}>
|
||||
<InvokeAILogoComponent />
|
||||
<InvTabList gap={4} pt={8} pb={4} h="full" flexDir="column">
|
||||
{tabs}
|
||||
<Spacer />
|
||||
<SettingsMenu />
|
||||
</InvTabList>
|
||||
</Flex>
|
||||
<PanelGroup
|
||||
ref={panelGroupRef}
|
||||
id={appPanelGroupId}
|
||||
@ -272,7 +278,6 @@ const InvokeTabs = () => {
|
||||
onCollapse={onCollapseOptionsPanel}
|
||||
onExpand={onExpandOptionsPanel}
|
||||
collapsible
|
||||
style={paddingTop4}
|
||||
>
|
||||
{activeTabName === 'nodes' ? (
|
||||
<NodeEditorPanelGroup />
|
||||
@ -287,7 +292,7 @@ const InvokeTabs = () => {
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Panel id="main-panel" order={1} minSize={20} style={paddingTop4}>
|
||||
<Panel id="main-panel" order={1} minSize={20}>
|
||||
<InvTabPanels w="full" h="full">
|
||||
{tabPanels}
|
||||
</InvTabPanels>
|
||||
@ -308,7 +313,6 @@ const InvokeTabs = () => {
|
||||
onCollapse={onCollapseGalleryPanel}
|
||||
onExpand={onExpandGalleryPanel}
|
||||
collapsible
|
||||
style={paddingTop4}
|
||||
>
|
||||
<ImageGalleryContent />
|
||||
</Panel>
|
||||
@ -320,5 +324,3 @@ const InvokeTabs = () => {
|
||||
};
|
||||
|
||||
export default memo(InvokeTabs);
|
||||
|
||||
const paddingTop4: CSSProperties = { paddingTop: '8px' };
|
||||
|
Loading…
Reference in New Issue
Block a user