fix(app): retain sidebar width across window resizes

This commit is contained in:
Mohamed Boudra
2026-07-14 22:44:03 +02:00
parent e366dae367
commit 6fc6ff7b7e
3 changed files with 28 additions and 24 deletions
@@ -10,5 +10,7 @@ describe("desktop sidebar width", () => {
const atBreakpoint = resolveDesktopSidebarWidth({ requestedWidth: 600, viewportWidth: 720 });
expect(atBreakpoint).toBe(320);
expect(720 - atBreakpoint).toBe(400);
expect(resolveDesktopSidebarWidth({ requestedWidth: 600, viewportWidth: 1440 })).toBe(600);
});
});
+11 -15
View File
@@ -713,29 +713,25 @@ function DesktopSidebar({
const sidebarWidth = usePanelStore((state) => state.sidebarWidth);
const setSidebarWidth = usePanelStore((state) => state.setSidebarWidth);
const { width: viewportWidth } = useWindowDimensions();
const visibleSidebarWidth = resolveDesktopSidebarWidth({
requestedWidth: sidebarWidth,
viewportWidth,
});
const startWidthRef = useRef(sidebarWidth);
const resizeWidth = useSharedValue(sidebarWidth);
const startWidthRef = useRef(visibleSidebarWidth);
const resizeWidth = useSharedValue(visibleSidebarWidth);
useEffect(() => {
resizeWidth.value = sidebarWidth;
}, [sidebarWidth, resizeWidth]);
useEffect(() => {
const clampedWidth = resolveDesktopSidebarWidth({
requestedWidth: sidebarWidth,
viewportWidth,
});
if (sidebarWidth !== clampedWidth) setSidebarWidth(clampedWidth);
}, [setSidebarWidth, sidebarWidth, viewportWidth]);
resizeWidth.value = visibleSidebarWidth;
}, [resizeWidth, visibleSidebarWidth]);
const resizeGesture = useMemo(
() =>
Gesture.Pan()
.hitSlop({ left: 8, right: 8, top: 0, bottom: 0 })
.onStart(() => {
startWidthRef.current = sidebarWidth;
resizeWidth.value = sidebarWidth;
startWidthRef.current = visibleSidebarWidth;
resizeWidth.value = visibleSidebarWidth;
})
.onUpdate((event) => {
// Dragging right (positive translationX) increases width
@@ -748,7 +744,7 @@ function DesktopSidebar({
.onEnd(() => {
runOnJS(setSidebarWidth)(resizeWidth.value);
}),
[sidebarWidth, resizeWidth, setSidebarWidth, viewportWidth],
[resizeWidth, setSidebarWidth, viewportWidth, visibleSidebarWidth],
);
const resizeAnimatedStyle = useAnimatedStyle(() => ({
+15 -9
View File
@@ -95,8 +95,14 @@ export function WindowChromeProvider({ children }: { children: ReactNode }) {
let retryCount = 0;
let retryTimer: ReturnType<typeof setTimeout> | undefined;
function scheduleRetry() {
if (!active || dispose || retryTimer || retryCount >= 40) return;
function scheduleRetry(warnOnExhaustion = false) {
if (!active || dispose || retryTimer) return;
if (retryCount >= 40) {
if (warnOnExhaustion) {
console.warn("[DesktopWindow] Chrome bridge unavailable; window controls may overlap UI");
}
return;
}
retryCount += 1;
retryTimer = setTimeout(() => {
retryTimer = undefined;
@@ -107,15 +113,15 @@ export function WindowChromeProvider({ children }: { children: ReactNode }) {
function connect() {
if (!active || dispose || connecting) return;
if (!getIsElectronRuntime()) return scheduleRetry();
const window = getDesktopWindow();
const desktopWindow = getDesktopWindow();
if (
!window ||
typeof window.isFullscreen !== "function" ||
typeof window.onResized !== "function"
!desktopWindow ||
typeof desktopWindow.isFullscreen !== "function" ||
typeof desktopWindow.onResized !== "function"
)
return scheduleRetry();
const readFullscreen = window.isFullscreen;
const subscribeToResized = window.onResized;
return scheduleRetry(true);
const readFullscreen = desktopWindow.isFullscreen;
const subscribeToResized = desktopWindow.onResized;
connecting = true;
void (async () => {
async function syncFullscreen() {