Reduce workspace rerenders during explorer resize
This commit is contained in:
@@ -0,0 +1,56 @@
|
|||||||
|
// @vitest-environment jsdom
|
||||||
|
|
||||||
|
import { act, renderHook } from "@testing-library/react";
|
||||||
|
import type { LayoutChangeEvent } from "react-native";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { useContainerWidthBelow } from "./use-container-width";
|
||||||
|
|
||||||
|
function layoutEvent(width: number): LayoutChangeEvent {
|
||||||
|
return {
|
||||||
|
nativeEvent: {
|
||||||
|
layout: {
|
||||||
|
width,
|
||||||
|
height: 48,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as LayoutChangeEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("useContainerWidthBelow", () => {
|
||||||
|
it("does not re-render for width changes that stay in the same threshold bucket", () => {
|
||||||
|
let renderCount = 0;
|
||||||
|
const { result } = renderHook(() => {
|
||||||
|
renderCount += 1;
|
||||||
|
return useContainerWidthBelow(700);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.isBelow).toBe(true);
|
||||||
|
expect(renderCount).toBe(1);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.onLayout(layoutEvent(650));
|
||||||
|
result.current.onLayout(layoutEvent(620));
|
||||||
|
result.current.onLayout(layoutEvent(699));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.isBelow).toBe(true);
|
||||||
|
expect(renderCount).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("re-renders when the width crosses the threshold", () => {
|
||||||
|
let renderCount = 0;
|
||||||
|
const { result } = renderHook(() => {
|
||||||
|
renderCount += 1;
|
||||||
|
return useContainerWidthBelow(700);
|
||||||
|
});
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.onLayout(layoutEvent(760));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.isBelow).toBe(false);
|
||||||
|
expect(renderCount).toBe(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -16,3 +16,25 @@ export function useContainerWidth(): {
|
|||||||
width,
|
width,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks only whether a container is narrower than a threshold.
|
||||||
|
*/
|
||||||
|
export function useContainerWidthBelow(threshold: number): {
|
||||||
|
onLayout: (e: LayoutChangeEvent) => void;
|
||||||
|
isBelow: boolean;
|
||||||
|
} {
|
||||||
|
const [isBelow, setIsBelow] = useState(true);
|
||||||
|
return {
|
||||||
|
onLayout: useCallback(
|
||||||
|
(e: LayoutChangeEvent) => {
|
||||||
|
const nextIsBelow = e.nativeEvent.layout.width < threshold;
|
||||||
|
setIsBelow((currentIsBelow) =>
|
||||||
|
currentIsBelow === nextIsBelow ? currentIsBelow : nextIsBelow,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[threshold],
|
||||||
|
),
|
||||||
|
isBelow,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ import { findAdjacentPane } from "@/utils/split-navigation";
|
|||||||
import { isAbsolutePath } from "@/utils/path";
|
import { isAbsolutePath } from "@/utils/path";
|
||||||
import { useIsCompactFormFactor, supportsDesktopPaneSplits } from "@/constants/layout";
|
import { useIsCompactFormFactor, supportsDesktopPaneSplits } from "@/constants/layout";
|
||||||
import { isWeb, isNative } from "@/constants/platform";
|
import { isWeb, isNative } from "@/constants/platform";
|
||||||
import { useContainerWidth } from "@/hooks/use-container-width";
|
import { useContainerWidthBelow } from "@/hooks/use-container-width";
|
||||||
|
|
||||||
const TERMINALS_QUERY_STALE_TIME = 5_000;
|
const TERMINALS_QUERY_STALE_TIME = 5_000;
|
||||||
const WORKSPACE_SETUP_AUTO_OPEN_WINDOW_MS = 30_000;
|
const WORKSPACE_SETUP_AUTO_OPEN_WINDOW_MS = 30_000;
|
||||||
@@ -1051,8 +1051,8 @@ function WorkspaceScreenContent({
|
|||||||
);
|
);
|
||||||
const pendingByDraftId = useCreateFlowStore((state) => state.pendingByDraftId);
|
const pendingByDraftId = useCreateFlowStore((state) => state.pendingByDraftId);
|
||||||
const { closingTabIds, closeTab } = useCloseTabs();
|
const { closingTabIds, closeTab } = useCloseTabs();
|
||||||
const { onLayout: onHeaderLayout, width: headerWidth } = useContainerWidth();
|
const { onLayout: onHeaderLayout, isBelow: showCompactButtonLabels } =
|
||||||
const showCompactButtonLabels = headerWidth < 700;
|
useContainerWidthBelow(700);
|
||||||
const closeWorkspaceTabWithCleanup = useCallback(
|
const closeWorkspaceTabWithCleanup = useCallback(
|
||||||
function closeWorkspaceTabWithCleanup(input: {
|
function closeWorkspaceTabWithCleanup(input: {
|
||||||
tabId: string;
|
tabId: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user