mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-02-13 18:25:28 -05:00
refactor(ui): navigation api
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import 'dockview/dist/styles/dockview.css';
|
||||
import 'features/ui/styles/dockview-theme-invoke.css';
|
||||
|
||||
import { TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library';
|
||||
import { Flex } from '@invoke-ai/ui-library';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import Loading from 'common/components/Loading/Loading';
|
||||
import { useDndMonitor } from 'features/dnd/useDndMonitor';
|
||||
import {
|
||||
selectWithCanvasTab,
|
||||
@@ -17,15 +18,16 @@ import { CanvasTabAutoLayout } from 'features/ui/layouts/canvas-tab-auto-layout'
|
||||
import { GenerateTabAutoLayout } from 'features/ui/layouts/generate-tab-auto-layout';
|
||||
import { UpscalingTabAutoLayout } from 'features/ui/layouts/upscaling-tab-auto-layout';
|
||||
import { WorkflowsTabAutoLayout } from 'features/ui/layouts/workflows-tab-auto-layout';
|
||||
import { selectActiveTabIndex } from 'features/ui/store/uiSelectors';
|
||||
import { memo } from 'react';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { memo, useState } from 'react';
|
||||
|
||||
import ModelManagerTab from './tabs/ModelManagerTab';
|
||||
import QueueTab from './tabs/QueueTab';
|
||||
|
||||
export const AppContent = memo(() => {
|
||||
useDndMonitor();
|
||||
const tabIndex = useAppSelector(selectActiveTabIndex);
|
||||
const tab = useAppSelector(selectActiveTab);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const withGenerateTab = useAppSelector(selectWithGenerateTab);
|
||||
const withCanvasTab = useAppSelector(selectWithCanvasTab);
|
||||
const withUpscalingTab = useAppSelector(selectWithUpscalingTab);
|
||||
@@ -34,41 +36,18 @@ export const AppContent = memo(() => {
|
||||
const withQueueTab = useAppSelector(selectWithQueueTab);
|
||||
|
||||
return (
|
||||
<Tabs index={tabIndex} display="flex" w="full" h="full" p={0} overflow="hidden">
|
||||
<Flex position="relative" w="full" h="full" overflow="hidden">
|
||||
<VerticalNavBar />
|
||||
<TabPanels w="full" h="full" p={0}>
|
||||
{withGenerateTab && (
|
||||
<TabPanel w="full" h="full" p={0}>
|
||||
<GenerateTabAutoLayout />
|
||||
</TabPanel>
|
||||
)}
|
||||
{withCanvasTab && (
|
||||
<TabPanel w="full" h="full" p={0}>
|
||||
<CanvasTabAutoLayout />
|
||||
</TabPanel>
|
||||
)}
|
||||
{withUpscalingTab && (
|
||||
<TabPanel w="full" h="full" p={0}>
|
||||
<UpscalingTabAutoLayout />
|
||||
</TabPanel>
|
||||
)}
|
||||
{withWorkflowsTab && (
|
||||
<TabPanel w="full" h="full" p={0}>
|
||||
<WorkflowsTabAutoLayout />
|
||||
</TabPanel>
|
||||
)}
|
||||
{withModelsTab && (
|
||||
<TabPanel w="full" h="full" p={0}>
|
||||
<ModelManagerTab />
|
||||
</TabPanel>
|
||||
)}
|
||||
{withQueueTab && (
|
||||
<TabPanel w="full" h="full" p={0}>
|
||||
<QueueTab />
|
||||
</TabPanel>
|
||||
)}
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
<Flex position="relative" w="full" h="full" overflow="hidden">
|
||||
{withGenerateTab && tab === 'generate' && <GenerateTabAutoLayout setIsLoading={setIsLoading} />}
|
||||
{withCanvasTab && tab === 'canvas' && <CanvasTabAutoLayout setIsLoading={setIsLoading} />}
|
||||
{withUpscalingTab && tab === 'upscaling' && <UpscalingTabAutoLayout setIsLoading={setIsLoading} />}
|
||||
{withWorkflowsTab && tab === 'workflows' && <WorkflowsTabAutoLayout setIsLoading={setIsLoading} />}
|
||||
{withModelsTab && tab === 'models' && <ModelManagerTab />}
|
||||
{withQueueTab && tab === 'queue' && <QueueTab />}
|
||||
{isLoading && <Loading />}
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
});
|
||||
AppContent.displayName = 'AppContent';
|
||||
|
||||
@@ -56,7 +56,6 @@ import {
|
||||
} from './shared';
|
||||
import { TabWithLaunchpadIcon } from './TabWithLaunchpadIcon';
|
||||
import { TabWithoutCloseButtonAndWithProgressIndicator } from './TabWithoutCloseButtonAndWithProgressIndicator';
|
||||
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
|
||||
|
||||
const tabComponents = {
|
||||
[DEFAULT_TAB_ID]: TabWithoutCloseButton,
|
||||
@@ -326,28 +325,30 @@ export const initializeRootPanelLayout = (api: GridviewApi) => {
|
||||
return { main, left, right } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
|
||||
export const CanvasTabAutoLayout = memo(() => {
|
||||
export const CanvasTabAutoLayout = memo(({ setIsLoading }: { setIsLoading: (isLoading: boolean) => void }) => {
|
||||
const rootRef = useRef<HTMLDivElement>(null);
|
||||
const [rootApi, setRootApi] = useState<GridviewApi | null>(null);
|
||||
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
|
||||
setRootApi(api);
|
||||
}, []);
|
||||
|
||||
useResizeMainPanelOnFirstVisit(rootApi, rootRef);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
|
||||
if (!rootApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
initializeRootPanelLayout(rootApi);
|
||||
|
||||
// Focus the launchpad panel once it's ready
|
||||
navigationApi.focusPanel('canvas', LAUNCHPAD_PANEL_ID);
|
||||
setTimeout(() => {
|
||||
setIsLoading(false);
|
||||
}, 300);
|
||||
|
||||
return () => {
|
||||
navigationApi.unregisterTab('canvas');
|
||||
};
|
||||
}, [rootApi]);
|
||||
}, [rootApi, setIsLoading]);
|
||||
|
||||
return (
|
||||
<AutoLayoutProvider tab="canvas" rootRef={rootRef}>
|
||||
|
||||
@@ -51,7 +51,6 @@ import {
|
||||
} from './shared';
|
||||
import { TabWithLaunchpadIcon } from './TabWithLaunchpadIcon';
|
||||
import { TabWithoutCloseButtonAndWithProgressIndicator } from './TabWithoutCloseButtonAndWithProgressIndicator';
|
||||
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
|
||||
|
||||
const tabComponents = {
|
||||
[DEFAULT_TAB_ID]: TabWithoutCloseButton,
|
||||
@@ -288,28 +287,30 @@ export const initializeRootPanelLayout = (layoutApi: GridviewApi) => {
|
||||
return { main, left, right } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
|
||||
export const GenerateTabAutoLayout = memo(() => {
|
||||
export const GenerateTabAutoLayout = memo(({ setIsLoading }: { setIsLoading: (isLoading: boolean) => void }) => {
|
||||
const rootRef = useRef<HTMLDivElement>(null);
|
||||
const [rootApi, setRootApi] = useState<GridviewApi | null>(null);
|
||||
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
|
||||
setRootApi(api);
|
||||
}, []);
|
||||
|
||||
useResizeMainPanelOnFirstVisit(rootApi, rootRef);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
|
||||
if (!rootApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
initializeRootPanelLayout(rootApi);
|
||||
|
||||
// Focus the launchpad panel once it's ready
|
||||
navigationApi.focusPanel('generate', LAUNCHPAD_PANEL_ID);
|
||||
setTimeout(() => {
|
||||
setIsLoading(false);
|
||||
}, 300);
|
||||
|
||||
return () => {
|
||||
navigationApi.unregisterTab('generate');
|
||||
};
|
||||
}, [rootApi]);
|
||||
}, [rootApi, setIsLoading]);
|
||||
|
||||
return (
|
||||
<AutoLayoutProvider tab="generate" rootRef={rootRef}>
|
||||
|
||||
@@ -14,7 +14,7 @@ type Waiter = {
|
||||
timeoutId: ReturnType<typeof setTimeout> | null;
|
||||
};
|
||||
|
||||
const PANEL_ENABLED_TABS: TabName[] = ['canvas', 'generate', 'workflows', 'queue'];
|
||||
const PANEL_ENABLED_TABS: TabName[] = ['canvas', 'generate', 'workflows', 'upscaling'];
|
||||
|
||||
export class NavigationApi {
|
||||
private panels: Map<string, PanelType> = new Map();
|
||||
|
||||
@@ -51,7 +51,6 @@ import {
|
||||
import { TabWithLaunchpadIcon } from './TabWithLaunchpadIcon';
|
||||
import { TabWithoutCloseButtonAndWithProgressIndicator } from './TabWithoutCloseButtonAndWithProgressIndicator';
|
||||
import { UpscalingTabLeftPanel } from './UpscalingTabLeftPanel';
|
||||
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
|
||||
|
||||
const tabComponents = {
|
||||
[DEFAULT_TAB_ID]: TabWithoutCloseButton,
|
||||
@@ -288,28 +287,29 @@ export const initializeRootPanelLayout = (layoutApi: GridviewApi) => {
|
||||
return { main, left, right } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
|
||||
export const UpscalingTabAutoLayout = memo(() => {
|
||||
export const UpscalingTabAutoLayout = memo(({ setIsLoading }: { setIsLoading: (isLoading: boolean) => void }) => {
|
||||
const rootRef = useRef<HTMLDivElement>(null);
|
||||
const [rootApi, setRootApi] = useState<GridviewApi | null>(null);
|
||||
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
|
||||
setRootApi(api);
|
||||
}, []);
|
||||
|
||||
useResizeMainPanelOnFirstVisit(rootApi, rootRef);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
|
||||
if (!rootApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
initializeRootPanelLayout(rootApi);
|
||||
|
||||
// Focus the launchpad panel once it's ready
|
||||
navigationApi.focusPanel('upscaling', LAUNCHPAD_PANEL_ID);
|
||||
|
||||
setTimeout(() => {
|
||||
setIsLoading(false);
|
||||
}, 300);
|
||||
return () => {
|
||||
navigationApi.unregisterTab('upscaling');
|
||||
};
|
||||
}, [rootApi]);
|
||||
}, [rootApi, setIsLoading]);
|
||||
|
||||
return (
|
||||
<AutoLayoutProvider tab="upscaling" rootRef={rootRef}>
|
||||
|
||||
@@ -53,7 +53,6 @@ import {
|
||||
} from './shared';
|
||||
import { TabWithLaunchpadIcon } from './TabWithLaunchpadIcon';
|
||||
import { TabWithoutCloseButtonAndWithProgressIndicator } from './TabWithoutCloseButtonAndWithProgressIndicator';
|
||||
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
|
||||
|
||||
const tabComponents = {
|
||||
[DEFAULT_TAB_ID]: TabWithoutCloseButton,
|
||||
@@ -305,28 +304,30 @@ export const initializeRootPanelLayout = (api: GridviewApi) => {
|
||||
return { main, left, right } satisfies Record<string, IGridviewPanel>;
|
||||
};
|
||||
|
||||
export const WorkflowsTabAutoLayout = memo(() => {
|
||||
export const WorkflowsTabAutoLayout = memo(({ setIsLoading }: { setIsLoading: (isLoading: boolean) => void }) => {
|
||||
const rootRef = useRef<HTMLDivElement>(null);
|
||||
const [rootApi, setRootApi] = useState<GridviewApi | null>(null);
|
||||
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
|
||||
setRootApi(api);
|
||||
}, []);
|
||||
|
||||
useResizeMainPanelOnFirstVisit(rootApi, rootRef);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
|
||||
if (!rootApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
initializeRootPanelLayout(rootApi);
|
||||
|
||||
// Focus the launchpad panel once it's ready
|
||||
navigationApi.focusPanel('workflows', LAUNCHPAD_PANEL_ID);
|
||||
setTimeout(() => {
|
||||
setIsLoading(false);
|
||||
}, 300);
|
||||
|
||||
return () => {
|
||||
navigationApi.unregisterTab('workflows');
|
||||
};
|
||||
}, [rootApi]);
|
||||
}, [rootApi, setIsLoading]);
|
||||
|
||||
return (
|
||||
<AutoLayoutProvider tab="workflows" rootRef={rootRef}>
|
||||
|
||||
Reference in New Issue
Block a user