Skip to content

Commit 5f198dd

Browse files
refactor(ui): navigation api
1 parent 1c288b3 commit 5f198dd

File tree

6 files changed

+50
-68
lines changed

6 files changed

+50
-68
lines changed
Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import 'dockview/dist/styles/dockview.css';
22
import 'features/ui/styles/dockview-theme-invoke.css';
33

4-
import { TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library';
4+
import { Flex } from '@invoke-ai/ui-library';
55
import { useAppSelector } from 'app/store/storeHooks';
6+
import Loading from 'common/components/Loading/Loading';
67
import { useDndMonitor } from 'features/dnd/useDndMonitor';
78
import {
89
selectWithCanvasTab,
@@ -17,15 +18,16 @@ import { CanvasTabAutoLayout } from 'features/ui/layouts/canvas-tab-auto-layout'
1718
import { GenerateTabAutoLayout } from 'features/ui/layouts/generate-tab-auto-layout';
1819
import { UpscalingTabAutoLayout } from 'features/ui/layouts/upscaling-tab-auto-layout';
1920
import { WorkflowsTabAutoLayout } from 'features/ui/layouts/workflows-tab-auto-layout';
20-
import { selectActiveTabIndex } from 'features/ui/store/uiSelectors';
21-
import { memo } from 'react';
21+
import { selectActiveTab } from 'features/ui/store/uiSelectors';
22+
import { memo, useState } from 'react';
2223

2324
import ModelManagerTab from './tabs/ModelManagerTab';
2425
import QueueTab from './tabs/QueueTab';
2526

2627
export const AppContent = memo(() => {
2728
useDndMonitor();
28-
const tabIndex = useAppSelector(selectActiveTabIndex);
29+
const tab = useAppSelector(selectActiveTab);
30+
const [isLoading, setIsLoading] = useState(true);
2931
const withGenerateTab = useAppSelector(selectWithGenerateTab);
3032
const withCanvasTab = useAppSelector(selectWithCanvasTab);
3133
const withUpscalingTab = useAppSelector(selectWithUpscalingTab);
@@ -34,41 +36,18 @@ export const AppContent = memo(() => {
3436
const withQueueTab = useAppSelector(selectWithQueueTab);
3537

3638
return (
37-
<Tabs index={tabIndex} display="flex" w="full" h="full" p={0} overflow="hidden">
39+
<Flex position="relative" w="full" h="full" overflow="hidden">
3840
<VerticalNavBar />
39-
<TabPanels w="full" h="full" p={0}>
40-
{withGenerateTab && (
41-
<TabPanel w="full" h="full" p={0}>
42-
<GenerateTabAutoLayout />
43-
</TabPanel>
44-
)}
45-
{withCanvasTab && (
46-
<TabPanel w="full" h="full" p={0}>
47-
<CanvasTabAutoLayout />
48-
</TabPanel>
49-
)}
50-
{withUpscalingTab && (
51-
<TabPanel w="full" h="full" p={0}>
52-
<UpscalingTabAutoLayout />
53-
</TabPanel>
54-
)}
55-
{withWorkflowsTab && (
56-
<TabPanel w="full" h="full" p={0}>
57-
<WorkflowsTabAutoLayout />
58-
</TabPanel>
59-
)}
60-
{withModelsTab && (
61-
<TabPanel w="full" h="full" p={0}>
62-
<ModelManagerTab />
63-
</TabPanel>
64-
)}
65-
{withQueueTab && (
66-
<TabPanel w="full" h="full" p={0}>
67-
<QueueTab />
68-
</TabPanel>
69-
)}
70-
</TabPanels>
71-
</Tabs>
41+
<Flex position="relative" w="full" h="full" overflow="hidden">
42+
{withGenerateTab && tab === 'generate' && <GenerateTabAutoLayout setIsLoading={setIsLoading} />}
43+
{withCanvasTab && tab === 'canvas' && <CanvasTabAutoLayout setIsLoading={setIsLoading} />}
44+
{withUpscalingTab && tab === 'upscaling' && <UpscalingTabAutoLayout setIsLoading={setIsLoading} />}
45+
{withWorkflowsTab && tab === 'workflows' && <WorkflowsTabAutoLayout setIsLoading={setIsLoading} />}
46+
{withModelsTab && tab === 'models' && <ModelManagerTab />}
47+
{withQueueTab && tab === 'queue' && <QueueTab />}
48+
{isLoading && <Loading />}
49+
</Flex>
50+
</Flex>
7251
);
7352
});
7453
AppContent.displayName = 'AppContent';

invokeai/frontend/web/src/features/ui/layouts/canvas-tab-auto-layout.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ import {
5656
} from './shared';
5757
import { TabWithLaunchpadIcon } from './TabWithLaunchpadIcon';
5858
import { TabWithoutCloseButtonAndWithProgressIndicator } from './TabWithoutCloseButtonAndWithProgressIndicator';
59-
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
6059

6160
const tabComponents = {
6261
[DEFAULT_TAB_ID]: TabWithoutCloseButton,
@@ -326,28 +325,30 @@ export const initializeRootPanelLayout = (api: GridviewApi) => {
326325
return { main, left, right } satisfies Record<string, IGridviewPanel>;
327326
};
328327

329-
export const CanvasTabAutoLayout = memo(() => {
328+
export const CanvasTabAutoLayout = memo(({ setIsLoading }: { setIsLoading: (isLoading: boolean) => void }) => {
330329
const rootRef = useRef<HTMLDivElement>(null);
331330
const [rootApi, setRootApi] = useState<GridviewApi | null>(null);
332331
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
333332
setRootApi(api);
334333
}, []);
335334

336-
useResizeMainPanelOnFirstVisit(rootApi, rootRef);
337-
338335
useEffect(() => {
336+
setIsLoading(true);
337+
339338
if (!rootApi) {
340339
return;
341340
}
341+
342342
initializeRootPanelLayout(rootApi);
343343

344-
// Focus the launchpad panel once it's ready
345-
navigationApi.focusPanel('canvas', LAUNCHPAD_PANEL_ID);
344+
setTimeout(() => {
345+
setIsLoading(false);
346+
}, 300);
346347

347348
return () => {
348349
navigationApi.unregisterTab('canvas');
349350
};
350-
}, [rootApi]);
351+
}, [rootApi, setIsLoading]);
351352

352353
return (
353354
<AutoLayoutProvider tab="canvas" rootRef={rootRef}>

invokeai/frontend/web/src/features/ui/layouts/generate-tab-auto-layout.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ import {
5151
} from './shared';
5252
import { TabWithLaunchpadIcon } from './TabWithLaunchpadIcon';
5353
import { TabWithoutCloseButtonAndWithProgressIndicator } from './TabWithoutCloseButtonAndWithProgressIndicator';
54-
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
5554

5655
const tabComponents = {
5756
[DEFAULT_TAB_ID]: TabWithoutCloseButton,
@@ -288,28 +287,30 @@ export const initializeRootPanelLayout = (layoutApi: GridviewApi) => {
288287
return { main, left, right } satisfies Record<string, IGridviewPanel>;
289288
};
290289

291-
export const GenerateTabAutoLayout = memo(() => {
290+
export const GenerateTabAutoLayout = memo(({ setIsLoading }: { setIsLoading: (isLoading: boolean) => void }) => {
292291
const rootRef = useRef<HTMLDivElement>(null);
293292
const [rootApi, setRootApi] = useState<GridviewApi | null>(null);
294293
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
295294
setRootApi(api);
296295
}, []);
297296

298-
useResizeMainPanelOnFirstVisit(rootApi, rootRef);
299-
300297
useEffect(() => {
298+
setIsLoading(true);
299+
301300
if (!rootApi) {
302301
return;
303302
}
303+
304304
initializeRootPanelLayout(rootApi);
305305

306-
// Focus the launchpad panel once it's ready
307-
navigationApi.focusPanel('generate', LAUNCHPAD_PANEL_ID);
306+
setTimeout(() => {
307+
setIsLoading(false);
308+
}, 300);
308309

309310
return () => {
310311
navigationApi.unregisterTab('generate');
311312
};
312-
}, [rootApi]);
313+
}, [rootApi, setIsLoading]);
313314

314315
return (
315316
<AutoLayoutProvider tab="generate" rootRef={rootRef}>

invokeai/frontend/web/src/features/ui/layouts/navigation-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type Waiter = {
1414
timeoutId: ReturnType<typeof setTimeout> | null;
1515
};
1616

17-
const PANEL_ENABLED_TABS: TabName[] = ['canvas', 'generate', 'workflows', 'queue'];
17+
const PANEL_ENABLED_TABS: TabName[] = ['canvas', 'generate', 'workflows', 'upscaling'];
1818

1919
export class NavigationApi {
2020
private panels: Map<string, PanelType> = new Map();

invokeai/frontend/web/src/features/ui/layouts/upscaling-tab-auto-layout.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ import {
5151
import { TabWithLaunchpadIcon } from './TabWithLaunchpadIcon';
5252
import { TabWithoutCloseButtonAndWithProgressIndicator } from './TabWithoutCloseButtonAndWithProgressIndicator';
5353
import { UpscalingTabLeftPanel } from './UpscalingTabLeftPanel';
54-
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
5554

5655
const tabComponents = {
5756
[DEFAULT_TAB_ID]: TabWithoutCloseButton,
@@ -288,28 +287,29 @@ export const initializeRootPanelLayout = (layoutApi: GridviewApi) => {
288287
return { main, left, right } satisfies Record<string, IGridviewPanel>;
289288
};
290289

291-
export const UpscalingTabAutoLayout = memo(() => {
290+
export const UpscalingTabAutoLayout = memo(({ setIsLoading }: { setIsLoading: (isLoading: boolean) => void }) => {
292291
const rootRef = useRef<HTMLDivElement>(null);
293292
const [rootApi, setRootApi] = useState<GridviewApi | null>(null);
294293
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
295294
setRootApi(api);
296295
}, []);
297296

298-
useResizeMainPanelOnFirstVisit(rootApi, rootRef);
299-
300297
useEffect(() => {
298+
setIsLoading(true);
299+
301300
if (!rootApi) {
302301
return;
303302
}
304-
initializeRootPanelLayout(rootApi);
305303

306-
// Focus the launchpad panel once it's ready
307-
navigationApi.focusPanel('upscaling', LAUNCHPAD_PANEL_ID);
304+
initializeRootPanelLayout(rootApi);
308305

306+
setTimeout(() => {
307+
setIsLoading(false);
308+
}, 300);
309309
return () => {
310310
navigationApi.unregisterTab('upscaling');
311311
};
312-
}, [rootApi]);
312+
}, [rootApi, setIsLoading]);
313313

314314
return (
315315
<AutoLayoutProvider tab="upscaling" rootRef={rootRef}>

invokeai/frontend/web/src/features/ui/layouts/workflows-tab-auto-layout.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ import {
5353
} from './shared';
5454
import { TabWithLaunchpadIcon } from './TabWithLaunchpadIcon';
5555
import { TabWithoutCloseButtonAndWithProgressIndicator } from './TabWithoutCloseButtonAndWithProgressIndicator';
56-
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
5756

5857
const tabComponents = {
5958
[DEFAULT_TAB_ID]: TabWithoutCloseButton,
@@ -305,28 +304,30 @@ export const initializeRootPanelLayout = (api: GridviewApi) => {
305304
return { main, left, right } satisfies Record<string, IGridviewPanel>;
306305
};
307306

308-
export const WorkflowsTabAutoLayout = memo(() => {
307+
export const WorkflowsTabAutoLayout = memo(({ setIsLoading }: { setIsLoading: (isLoading: boolean) => void }) => {
309308
const rootRef = useRef<HTMLDivElement>(null);
310309
const [rootApi, setRootApi] = useState<GridviewApi | null>(null);
311310
const onReady = useCallback<IGridviewReactProps['onReady']>(({ api }) => {
312311
setRootApi(api);
313312
}, []);
314313

315-
useResizeMainPanelOnFirstVisit(rootApi, rootRef);
316-
317314
useEffect(() => {
315+
setIsLoading(true);
316+
318317
if (!rootApi) {
319318
return;
320319
}
320+
321321
initializeRootPanelLayout(rootApi);
322322

323-
// Focus the launchpad panel once it's ready
324-
navigationApi.focusPanel('workflows', LAUNCHPAD_PANEL_ID);
323+
setTimeout(() => {
324+
setIsLoading(false);
325+
}, 300);
325326

326327
return () => {
327328
navigationApi.unregisterTab('workflows');
328329
};
329-
}, [rootApi]);
330+
}, [rootApi, setIsLoading]);
330331

331332
return (
332333
<AutoLayoutProvider tab="workflows" rootRef={rootRef}>

0 commit comments

Comments
 (0)