feat(ui): restore all panel hotkeys

This commit is contained in:
psychedelicious
2025-06-20 13:33:09 +10:00
parent 2f3b2f1fce
commit 2f94952af8
10 changed files with 206 additions and 336 deletions

View File

@@ -24,53 +24,9 @@ const onLeftPanelCollapse = (isCollapsed: boolean) => $isLeftPanelOpen.set(!isCo
const onRightPanelCollapse = (isCollapsed: boolean) => $isRightPanelOpen.set(!isCollapsed);
export const AppContent = memo(() => {
// const tab = useAppSelector(selectActiveTab);
const tabIndex = useAppSelector(selectActiveTabIndex);
// const imperativePanelGroupRef = useRef<ImperativePanelGroupHandle>(null);
useDndMonitor();
// const withLeftPanel = useAppSelector(selectWithLeftPanel);
// const leftPanelUsePanelOptions = useMemo<UsePanelOptions>(
// () => ({
// id: 'left-panel',
// minSizePx: LEFT_PANEL_MIN_SIZE_PX,
// defaultSizePx: LEFT_PANEL_MIN_SIZE_PX,
// imperativePanelGroupRef,
// panelGroupDirection: 'horizontal',
// onCollapse: onLeftPanelCollapse,
// }),
// []
// );
// const leftPanel = usePanel(leftPanelUsePanelOptions);
// useRegisteredHotkeys({
// id: 'toggleLeftPanel',
// category: 'app',
// callback: leftPanel.toggle,
// options: { enabled: withLeftPanel },
// dependencies: [leftPanel.toggle, withLeftPanel],
// });
// const withRightPanel = useAppSelector(selectWithRightPanel);
// const rightPanelUsePanelOptions = useMemo<UsePanelOptions>(
// () => ({
// id: 'right-panel',
// minSizePx: RIGHT_PANEL_MIN_SIZE_PX,
// defaultSizePx: RIGHT_PANEL_MIN_SIZE_PX,
// imperativePanelGroupRef,
// panelGroupDirection: 'horizontal',
// onCollapse: onRightPanelCollapse,
// }),
// []
// );
// const rightPanel = usePanel(rightPanelUsePanelOptions);
// useRegisteredHotkeys({
// id: 'toggleRightPanel',
// category: 'app',
// callback: rightPanel.toggle,
// options: { enabled: withRightPanel },
// dependencies: [rightPanel.toggle, withRightPanel],
// });
// useRegisteredHotkeys({
// id: 'resetPanelLayout',
// category: 'app',

View File

@@ -5,7 +5,6 @@ import { useDeleteAllExceptCurrentQueueItemDialog } from 'features/queue/compone
import { InvokeButtonTooltip } from 'features/queue/components/InvokeButtonTooltip/InvokeButtonTooltip';
import { useDeleteCurrentQueueItem } from 'features/queue/hooks/useDeleteCurrentQueueItem';
import { useInvoke } from 'features/queue/hooks/useInvoke';
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
import { useAutoLayoutContext } from 'features/ui/layouts/auto-layout-context';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
@@ -54,11 +53,6 @@ FloatingCanvasLeftPanelButtons.displayName = 'FloatingCanvasLeftPanelButtons';
const ToggleLeftPanelButton = memo(() => {
const { toggleLeftPanel } = useAutoLayoutContext();
useRegisteredHotkeys({
category: 'app',
id: 'toggleLeftPanel',
callback: toggleLeftPanel,
});
const { t } = useTranslation();
return (
<Tooltip label={t('accessibility.toggleLeftPanel')} placement="end">

View File

@@ -1,5 +1,4 @@
import { Flex, IconButton, Tooltip } from '@invoke-ai/ui-library';
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
import { useAutoLayoutContext } from 'features/ui/layouts/auto-layout-context';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
@@ -17,11 +16,6 @@ FloatingRightPanelButtons.displayName = 'FloatingRightPanelButtons';
const ToggleRightPanelButton = memo(() => {
const { t } = useTranslation();
const { toggleRightPanel } = useAutoLayoutContext();
useRegisteredHotkeys({
category: 'app',
id: 'toggleRightPanel',
callback: toggleRightPanel,
});
return (
<Tooltip label={t('accessibility.toggleRightPanel')} placement="start">

View File

@@ -1,24 +1,106 @@
import type { GridviewApi } from 'dockview';
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
import type { Atom } from 'nanostores';
import type { PropsWithChildren } from 'react';
import { createContext, useContext, useMemo } from 'react';
import { createContext, memo, useCallback, useContext, useMemo } from 'react';
import { LEFT_PANEL_ID, LEFT_PANEL_MIN_SIZE_PX, RIGHT_PANEL_ID, RIGHT_PANEL_MIN_SIZE_PX } from './shared';
type AutoLayoutContextValue = {
$api: Atom<GridviewApi | null>;
toggleLeftPanel: () => void;
toggleRightPanel: () => void;
toggleBothPanels: () => void;
resetPanels: () => void;
};
const AutoLayoutContext = createContext<AutoLayoutContextValue | null>(null);
export const AutoLayoutProvider = (props: PropsWithChildren<AutoLayoutContextValue>) => {
const expandPanel = (api: GridviewApi, panelId: string, width: number) => {
const panel = api.getPanel(panelId);
if (!panel) {
return;
}
panel.api.setConstraints({ maximumWidth: Number.MAX_SAFE_INTEGER, minimumWidth: width });
panel.api.setSize({ width: width });
};
const collapsePanel = (api: GridviewApi, panelId: string) => {
const panel = api.getPanel(panelId);
if (!panel) {
return;
}
panel.api.setConstraints({ maximumWidth: 0, minimumWidth: 0 });
panel.api.setSize({ width: 0 });
};
const getIsCollapsed = (api: GridviewApi, panelId: string) => {
const panel = api.getPanel(panelId);
if (!panel) {
return true; // ??
}
return panel.maximumWidth === 0;
};
export const AutoLayoutProvider = (props: PropsWithChildren<{ $api: Atom<GridviewApi | null> }>) => {
const toggleLeftPanel = useCallback(() => {
const api = props.$api.get();
if (!api) {
return;
}
if (getIsCollapsed(api, LEFT_PANEL_ID)) {
expandPanel(api, LEFT_PANEL_ID, LEFT_PANEL_MIN_SIZE_PX);
} else {
collapsePanel(api, LEFT_PANEL_ID);
}
}, [props.$api]);
const toggleRightPanel = useCallback(() => {
const api = props.$api.get();
if (!api) {
return;
}
if (getIsCollapsed(api, RIGHT_PANEL_ID)) {
expandPanel(api, RIGHT_PANEL_ID, RIGHT_PANEL_MIN_SIZE_PX);
} else {
collapsePanel(api, RIGHT_PANEL_ID);
}
}, [props.$api]);
const toggleBothPanels = useCallback(() => {
const api = props.$api.get();
if (!api) {
return;
}
requestAnimationFrame(() => {
if (getIsCollapsed(api, RIGHT_PANEL_ID) || getIsCollapsed(api, LEFT_PANEL_ID)) {
expandPanel(api, LEFT_PANEL_ID, LEFT_PANEL_MIN_SIZE_PX);
expandPanel(api, RIGHT_PANEL_ID, RIGHT_PANEL_MIN_SIZE_PX);
} else {
collapsePanel(api, LEFT_PANEL_ID);
collapsePanel(api, RIGHT_PANEL_ID);
}
});
}, [props.$api]);
const resetPanels = useCallback(() => {
const api = props.$api.get();
if (!api) {
return;
}
expandPanel(api, LEFT_PANEL_ID, LEFT_PANEL_MIN_SIZE_PX);
expandPanel(api, RIGHT_PANEL_ID, RIGHT_PANEL_MIN_SIZE_PX);
}, [props.$api]);
const value = useMemo<AutoLayoutContextValue>(
() => ({
$api: props.$api,
toggleLeftPanel: props.toggleLeftPanel,
toggleRightPanel: props.toggleRightPanel,
toggleLeftPanel,
toggleRightPanel,
toggleBothPanels,
resetPanels,
}),
[props.$api, props.toggleLeftPanel, props.toggleRightPanel]
[props.$api, resetPanels, toggleBothPanels, toggleLeftPanel, toggleRightPanel]
);
return <AutoLayoutContext.Provider value={value}>{props.children}</AutoLayoutContext.Provider>;
};
@@ -30,3 +112,30 @@ export const useAutoLayoutContext = () => {
}
return value;
};
export const PanelHotkeysLogical = memo(() => {
const { toggleBothPanels, resetPanels, toggleLeftPanel, toggleRightPanel } = useAutoLayoutContext();
useRegisteredHotkeys({
category: 'app',
id: 'toggleLeftPanel',
callback: toggleLeftPanel,
});
useRegisteredHotkeys({
category: 'app',
id: 'toggleRightPanel',
callback: toggleRightPanel,
});
useRegisteredHotkeys({
category: 'app',
id: 'resetPanelLayout',
callback: resetPanels,
});
useRegisteredHotkeys({
category: 'app',
id: 'togglePanels',
callback: toggleBothPanels,
});
return null;
});
PanelHotkeysLogical.displayName = 'PanelHotkeysLogical';

View File

@@ -6,18 +6,24 @@ import { BoardsPanel } from 'features/gallery/components/BoardsListPanelContent'
import { GalleryPanel } from 'features/gallery/components/Gallery';
import { GenerationProgressPanel } from 'features/gallery/components/ImageViewer/GenerationProgressPanel';
import { ImageViewerPanel } from 'features/gallery/components/ImageViewer/ImageViewerPanel';
import { FloatingLeftPanelButtons } from 'features/ui/components/FloatingLeftPanelButtons';
import { FloatingCanvasLeftPanelButtons } from 'features/ui/components/FloatingLeftPanelButtons';
import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightPanelButtons';
import { AutoLayoutProvider } from 'features/ui/layouts/auto-layout-context';
import { AutoLayoutProvider, PanelHotkeysLogical } from 'features/ui/layouts/auto-layout-context';
import { TabWithoutCloseButton } from 'features/ui/layouts/TabWithoutCloseButton';
import { LEFT_PANEL_MIN_SIZE_PX, RIGHT_PANEL_MIN_SIZE_PX } from 'features/ui/store/uiSlice';
import { dockviewTheme } from 'features/ui/styles/theme';
import { atom } from 'nanostores';
import { memo, useCallback, useRef, useState } from 'react';
import { CanvasTabLeftPanel } from './CanvasTabLeftPanel';
import { CanvasWorkspacePanel } from './CanvasWorkspacePanel';
import { useOnFirstVisible } from './use-on-first-visible';
import {
LEFT_PANEL_ID,
LEFT_PANEL_MIN_SIZE_PX,
MAIN_PANEL_ID,
RIGHT_PANEL_ID,
RIGHT_PANEL_MIN_SIZE_PX,
} from './shared';
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
const LAUNCHPAD_PANEL_ID = 'launchpad';
const WORKSPACE_PANEL_ID = 'workspace';
@@ -97,8 +103,9 @@ const MainPanel = memo(() => {
onReady={onReadyMainPanel}
theme={dockviewTheme}
/>
<FloatingLeftPanelButtons />
<FloatingCanvasLeftPanelButtons />
<FloatingRightPanelButtons />
<PanelHotkeysLogical />
</>
);
});
@@ -160,10 +167,6 @@ const RightPanel = memo(() => {
});
RightPanel.displayName = 'RightPanel';
const LEFT_PANEL_ID = 'left';
const MAIN_PANEL_ID = 'main';
const RIGHT_PANEL_ID = 'right';
export const rootComponents: IGridviewReactProps['components'] = {
[LEFT_PANEL_ID]: CanvasTabLeftPanel,
[MAIN_PANEL_ID]: MainPanel,
@@ -209,69 +212,10 @@ export const CanvasTabAutoLayout = memo(() => {
},
[$api]
);
const resizeMainPanelOnFirstVisible = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const mainPanel = api.getPanel(MAIN_PANEL_ID);
if (!mainPanel) {
return;
}
if (mainPanel.width !== 0) {
return;
}
let count = 0;
const setSize = () => {
if (count++ > 50) {
return;
}
mainPanel.api.setSize({ width: Number.MAX_SAFE_INTEGER });
if (mainPanel.width === 0) {
requestAnimationFrame(setSize);
return;
}
};
setSize();
}, [$api]);
useOnFirstVisible(ref, resizeMainPanelOnFirstVisible);
const toggleLeftPanel = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const left = api.getPanel(LEFT_PANEL_ID);
if (!left) {
return;
}
if (left.maximumWidth === 0) {
left.api.setConstraints({ maximumWidth: Number.MAX_SAFE_INTEGER, minimumWidth: LEFT_PANEL_MIN_SIZE_PX });
left.api.setSize({ width: LEFT_PANEL_MIN_SIZE_PX });
} else {
left.api.setConstraints({ maximumWidth: 0, minimumWidth: 0 });
left.api.setSize({ width: 0 });
}
}, [$api]);
const toggleRightPanel = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const right = api.getPanel(RIGHT_PANEL_ID);
if (!right) {
return;
}
if (right.maximumWidth === 0) {
right.api.setConstraints({ maximumWidth: Number.MAX_SAFE_INTEGER, minimumWidth: RIGHT_PANEL_MIN_SIZE_PX });
right.api.setSize({ width: RIGHT_PANEL_MIN_SIZE_PX });
} else {
right.api.setConstraints({ maximumWidth: 0, minimumWidth: 0 });
right.api.setSize({ width: 0 });
}
}, [$api]);
useResizeMainPanelOnFirstVisit($api, ref);
return (
<AutoLayoutProvider $api={$api} toggleLeftPanel={toggleLeftPanel} toggleRightPanel={toggleRightPanel}>
<AutoLayoutProvider $api={$api}>
<GridviewReact
ref={ref}
className="dockview-theme-invoke"

View File

@@ -7,15 +7,21 @@ import { GenerationProgressPanel } from 'features/gallery/components/ImageViewer
import { ImageViewerPanel } from 'features/gallery/components/ImageViewer/ImageViewerPanel';
import { FloatingLeftPanelButtons } from 'features/ui/components/FloatingLeftPanelButtons';
import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightPanelButtons';
import { AutoLayoutProvider } from 'features/ui/layouts/auto-layout-context';
import { AutoLayoutProvider, PanelHotkeysLogical } from 'features/ui/layouts/auto-layout-context';
import { TabWithoutCloseButton } from 'features/ui/layouts/TabWithoutCloseButton';
import { LEFT_PANEL_MIN_SIZE_PX, RIGHT_PANEL_MIN_SIZE_PX } from 'features/ui/store/uiSlice';
import { dockviewTheme } from 'features/ui/styles/theme';
import { atom } from 'nanostores';
import { memo, useCallback, useRef, useState } from 'react';
import { GenerateTabLeftPanel } from './GenerateTabLeftPanel';
import { useOnFirstVisible } from './use-on-first-visible';
import {
LEFT_PANEL_ID,
LEFT_PANEL_MIN_SIZE_PX,
MAIN_PANEL_ID,
RIGHT_PANEL_ID,
RIGHT_PANEL_MIN_SIZE_PX,
} from './shared';
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
const LAUNCHPAD_PANEL_ID = 'launchpad';
const VIEWER_PANEL_ID = 'viewer';
@@ -86,6 +92,7 @@ const MainPanel = memo(() => {
/>
<FloatingLeftPanelButtons />
<FloatingRightPanelButtons />
<PanelHotkeysLogical />
</>
);
});
@@ -136,10 +143,6 @@ const RightPanel = memo(() => {
});
RightPanel.displayName = 'RightPanel';
const LEFT_PANEL_ID = 'left';
const MAIN_PANEL_ID = 'main';
const RIGHT_PANEL_ID = 'right';
export const rootComponents: IGridviewReactProps['components'] = {
[LEFT_PANEL_ID]: GenerateTabLeftPanel,
[MAIN_PANEL_ID]: MainPanel,
@@ -185,68 +188,10 @@ export const GenerateTabAutoLayout = memo(() => {
},
[$api]
);
const resizeMainPanelOnFirstVisible = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const mainPanel = api.getPanel(MAIN_PANEL_ID);
if (!mainPanel) {
return;
}
if (mainPanel.width !== 0) {
return;
}
let count = 0;
const setSize = () => {
if (count++ > 50) {
return;
}
mainPanel.api.setSize({ width: Number.MAX_SAFE_INTEGER });
if (mainPanel.width === 0) {
requestAnimationFrame(setSize);
return;
}
};
setSize();
}, [$api]);
useOnFirstVisible(ref, resizeMainPanelOnFirstVisible);
const toggleLeftPanel = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const left = api.getPanel(LEFT_PANEL_ID);
if (!left) {
return;
}
if (left.maximumWidth === 0) {
left.api.setConstraints({ maximumWidth: Number.MAX_SAFE_INTEGER, minimumWidth: LEFT_PANEL_MIN_SIZE_PX });
left.api.setSize({ width: LEFT_PANEL_MIN_SIZE_PX });
} else {
left.api.setConstraints({ maximumWidth: 0, minimumWidth: 0 });
left.api.setSize({ width: 0 });
}
}, [$api]);
const toggleRightPanel = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const right = api.getPanel(RIGHT_PANEL_ID);
if (!right) {
return;
}
if (right.maximumWidth === 0) {
right.api.setConstraints({ maximumWidth: Number.MAX_SAFE_INTEGER, minimumWidth: RIGHT_PANEL_MIN_SIZE_PX });
right.api.setSize({ width: RIGHT_PANEL_MIN_SIZE_PX });
} else {
right.api.setConstraints({ maximumWidth: 0, minimumWidth: 0 });
right.api.setSize({ width: 0 });
}
}, [$api]);
useResizeMainPanelOnFirstVisit($api, ref);
return (
<AutoLayoutProvider $api={$api} toggleLeftPanel={toggleLeftPanel} toggleRightPanel={toggleRightPanel}>
<AutoLayoutProvider $api={$api}>
<GridviewReact
ref={ref}
className="dockview-theme-invoke"

View File

@@ -0,0 +1,6 @@
export const LEFT_PANEL_ID = 'left';
export const MAIN_PANEL_ID = 'main';
export const RIGHT_PANEL_ID = 'right';
export const LEFT_PANEL_MIN_SIZE_PX = 420;
export const RIGHT_PANEL_MIN_SIZE_PX = 420;

View File

@@ -7,15 +7,21 @@ import { GenerationProgressPanel } from 'features/gallery/components/ImageViewer
import { ImageViewerPanel } from 'features/gallery/components/ImageViewer/ImageViewerPanel';
import { FloatingLeftPanelButtons } from 'features/ui/components/FloatingLeftPanelButtons';
import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightPanelButtons';
import { AutoLayoutProvider } from 'features/ui/layouts/auto-layout-context';
import { AutoLayoutProvider, PanelHotkeysLogical } from 'features/ui/layouts/auto-layout-context';
import { TabWithoutCloseButton } from 'features/ui/layouts/TabWithoutCloseButton';
import { LEFT_PANEL_MIN_SIZE_PX, RIGHT_PANEL_MIN_SIZE_PX } from 'features/ui/store/uiSlice';
import { dockviewTheme } from 'features/ui/styles/theme';
import { atom } from 'nanostores';
import { memo, useCallback, useRef, useState } from 'react';
import {
LEFT_PANEL_ID,
LEFT_PANEL_MIN_SIZE_PX,
MAIN_PANEL_ID,
RIGHT_PANEL_ID,
RIGHT_PANEL_MIN_SIZE_PX,
} from './shared';
import { UpscalingTabLeftPanel } from './UpscalingTabLeftPanel';
import { useOnFirstVisible } from './use-on-first-visible';
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
const LAUNCHPAD_PANEL_ID = 'launchpad';
const VIEWER_PANEL_ID = 'viewer';
@@ -86,6 +92,7 @@ const MainPanel = memo(() => {
/>
<FloatingLeftPanelButtons />
<FloatingRightPanelButtons />
<PanelHotkeysLogical />
</>
);
});
@@ -136,10 +143,6 @@ const RightPanel = memo(() => {
});
RightPanel.displayName = 'RightPanel';
const LEFT_PANEL_ID = 'left';
const MAIN_PANEL_ID = 'main';
const RIGHT_PANEL_ID = 'right';
export const rootComponents: IGridviewReactProps['components'] = {
[LEFT_PANEL_ID]: UpscalingTabLeftPanel,
[MAIN_PANEL_ID]: MainPanel,
@@ -185,68 +188,10 @@ export const UpscalingTabAutoLayout = memo(() => {
},
[$api]
);
const resizeMainPanelOnFirstVisible = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const mainPanel = api.getPanel(MAIN_PANEL_ID);
if (!mainPanel) {
return;
}
if (mainPanel.width !== 0) {
return;
}
let count = 0;
const setSize = () => {
if (count++ > 50) {
return;
}
mainPanel.api.setSize({ width: Number.MAX_SAFE_INTEGER });
if (mainPanel.width === 0) {
requestAnimationFrame(setSize);
return;
}
};
setSize();
}, [$api]);
useOnFirstVisible(ref, resizeMainPanelOnFirstVisible);
const toggleLeftPanel = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const left = api.getPanel(LEFT_PANEL_ID);
if (!left) {
return;
}
if (left.maximumWidth === 0) {
left.api.setConstraints({ maximumWidth: Number.MAX_SAFE_INTEGER, minimumWidth: LEFT_PANEL_MIN_SIZE_PX });
left.api.setSize({ width: LEFT_PANEL_MIN_SIZE_PX });
} else {
left.api.setConstraints({ maximumWidth: 0, minimumWidth: 0 });
left.api.setSize({ width: 0 });
}
}, [$api]);
const toggleRightPanel = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const right = api.getPanel(RIGHT_PANEL_ID);
if (!right) {
return;
}
if (right.maximumWidth === 0) {
right.api.setConstraints({ maximumWidth: Number.MAX_SAFE_INTEGER, minimumWidth: RIGHT_PANEL_MIN_SIZE_PX });
right.api.setSize({ width: RIGHT_PANEL_MIN_SIZE_PX });
} else {
right.api.setConstraints({ maximumWidth: 0, minimumWidth: 0 });
right.api.setSize({ width: 0 });
}
}, [$api]);
useResizeMainPanelOnFirstVisit($api, ref);
return (
<AutoLayoutProvider $api={$api} toggleLeftPanel={toggleLeftPanel} toggleRightPanel={toggleRightPanel}>
<AutoLayoutProvider $api={$api}>
<GridviewReact
ref={ref}
className="dockview-theme-invoke"

View File

@@ -1,5 +1,9 @@
import type { GridviewApi } from 'dockview';
import type { Atom } from 'nanostores';
import type { RefObject } from 'react';
import { useEffect } from 'react';
import { useCallback, useEffect } from 'react';
import { MAIN_PANEL_ID } from './shared';
export const useOnFirstVisible = (elementRef: RefObject<HTMLElement>, callback: () => void): void => {
useEffect(() => {
@@ -46,3 +50,32 @@ export const useOnFirstVisible = (elementRef: RefObject<HTMLElement>, callback:
};
}, [elementRef, callback]);
};
export const useResizeMainPanelOnFirstVisit = ($api: Atom<GridviewApi | null>, ref: RefObject<HTMLElement>) => {
const resizeMainPanelOnFirstVisible = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const mainPanel = api.getPanel(MAIN_PANEL_ID);
if (!mainPanel) {
return;
}
if (mainPanel.width !== 0) {
return;
}
let count = 0;
const setSize = () => {
if (count++ > 50) {
return;
}
mainPanel.api.setSize({ width: Number.MAX_SAFE_INTEGER });
if (mainPanel.width === 0) {
requestAnimationFrame(setSize);
return;
}
};
setSize();
}, [$api]);
useOnFirstVisible(ref, resizeMainPanelOnFirstVisible);
};

View File

@@ -9,14 +9,20 @@ import NodeEditor from 'features/nodes/components/NodeEditor';
import WorkflowsTabLeftPanel from 'features/nodes/components/sidePanel/WorkflowsTabLeftPanel';
import { FloatingLeftPanelButtons } from 'features/ui/components/FloatingLeftPanelButtons';
import { FloatingRightPanelButtons } from 'features/ui/components/FloatingRightPanelButtons';
import { AutoLayoutProvider } from 'features/ui/layouts/auto-layout-context';
import { AutoLayoutProvider, PanelHotkeysLogical } from 'features/ui/layouts/auto-layout-context';
import { TabWithoutCloseButton } from 'features/ui/layouts/TabWithoutCloseButton';
import { LEFT_PANEL_MIN_SIZE_PX, RIGHT_PANEL_MIN_SIZE_PX } from 'features/ui/store/uiSlice';
import { dockviewTheme } from 'features/ui/styles/theme';
import { atom } from 'nanostores';
import { memo, useCallback, useRef, useState } from 'react';
import { useOnFirstVisible } from './use-on-first-visible';
import {
LEFT_PANEL_ID,
LEFT_PANEL_MIN_SIZE_PX,
MAIN_PANEL_ID,
RIGHT_PANEL_ID,
RIGHT_PANEL_MIN_SIZE_PX,
} from './shared';
import { useResizeMainPanelOnFirstVisit } from './use-on-first-visible';
const LAUNCHPAD_PANEL_ID = 'launchpad';
const WORKSPACE_PANEL_ID = 'workspace';
@@ -98,6 +104,7 @@ const MainPanel = memo(() => {
/>
<FloatingLeftPanelButtons />
<FloatingRightPanelButtons />
<PanelHotkeysLogical />
</>
);
});
@@ -148,10 +155,6 @@ const RightPanel = memo(() => {
});
RightPanel.displayName = 'RightPanel';
const LEFT_PANEL_ID = 'left';
const MAIN_PANEL_ID = 'main';
const RIGHT_PANEL_ID = 'right';
export const rootComponents: IGridviewReactProps['components'] = {
[LEFT_PANEL_ID]: WorkflowsTabLeftPanel,
[MAIN_PANEL_ID]: MainPanel,
@@ -197,69 +200,10 @@ export const WorkflowsTabAutoLayout = memo(() => {
},
[$api]
);
const resizeMainPanelOnFirstVisible = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const mainPanel = api.getPanel(MAIN_PANEL_ID);
if (!mainPanel) {
return;
}
if (mainPanel.width !== 0) {
return;
}
let count = 0;
const setSize = () => {
if (count++ > 50) {
return;
}
mainPanel.api.setSize({ width: Number.MAX_SAFE_INTEGER });
if (mainPanel.width === 0) {
requestAnimationFrame(setSize);
return;
}
};
setSize();
}, [$api]);
useOnFirstVisible(ref, resizeMainPanelOnFirstVisible);
const toggleLeftPanel = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const left = api.getPanel(LEFT_PANEL_ID);
if (!left) {
return;
}
if (left.maximumWidth === 0) {
left.api.setConstraints({ maximumWidth: Number.MAX_SAFE_INTEGER, minimumWidth: LEFT_PANEL_MIN_SIZE_PX });
left.api.setSize({ width: LEFT_PANEL_MIN_SIZE_PX });
} else {
left.api.setConstraints({ maximumWidth: 0, minimumWidth: 0 });
left.api.setSize({ width: 0 });
}
}, [$api]);
const toggleRightPanel = useCallback(() => {
const api = $api.get();
if (!api) {
return;
}
const right = api.getPanel(RIGHT_PANEL_ID);
if (!right) {
return;
}
if (right.maximumWidth === 0) {
right.api.setConstraints({ maximumWidth: Number.MAX_SAFE_INTEGER, minimumWidth: RIGHT_PANEL_MIN_SIZE_PX });
right.api.setSize({ width: RIGHT_PANEL_MIN_SIZE_PX });
} else {
right.api.setConstraints({ maximumWidth: 0, minimumWidth: 0 });
right.api.setSize({ width: 0 });
}
}, [$api]);
useResizeMainPanelOnFirstVisit($api, ref);
return (
<AutoLayoutProvider $api={$api} toggleLeftPanel={toggleLeftPanel} toggleRightPanel={toggleRightPanel}>
<AutoLayoutProvider $api={$api}>
<GridviewReact
ref={ref}
className="dockview-theme-invoke"