authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-07-27 18:07:40+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-07-27 18:07:40+02:00
logda11342e03dbf2bf46058d66b9c4f4eab8047a5a
tree47ef1fa9106f32087d4c1e0dde10db957c73bf0b
parent180620e43688843e694c6fd155d4e113886698a0
signature Signed by PGP key B5690EEEBB952194

Fix live sidebar resize limits and defer Alchemy runtime context (#4655)


1 files changed, 21 insertions(+), 2 deletions(-)

apps/web/src/components/AppSidebarLayout.tsx+21-2
......@@ -1,6 +1,12 @@
11import { useAtomValue } from "@effect/atom-react";
22import * as Schema from "effect/Schema";
3import { useEffect, useState, type CSSProperties, type ReactNode } from "react";
3import {
4 useEffect,
5 useState,
6 useSyncExternalStore,
7 type CSSProperties,
8 type ReactNode,
9} from "react";
410import { useLocation, useNavigate } from "@tanstack/react-router";
511
612import { isElectron } from "../env";
......@@ -31,6 +37,15 @@ import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip";
3137
3238const MACOS_TRAFFIC_LIGHTS_LEFT_INSET = "90px";
3339
40function subscribeToViewportWidth(onChange: () => void): () => void {
41 window.addEventListener("resize", onChange);
42 return () => window.removeEventListener("resize", onChange);
43}
44
45function readViewportWidth(): number {
46 return window.innerWidth;
47}
48
3449function readInitialThreadSidebarWidth(): number {
3550 try {
3651 return resolveInitialThreadSidebarWidth(
......@@ -109,7 +124,11 @@ export function AppSidebarLayout({ children }: { children: ReactNode }) {
109124 const useSidebarV2Theme = useSidebarV2 || isOnSettings;
110125 const isMacosDesktop = isElectron && isMacPlatform(navigator.platform);
111126 const [sidebarWidth, setSidebarWidth] = useState(readInitialThreadSidebarWidth);
112 const sidebarMaximumWidth = resolveThreadSidebarMaximumWidth(window.innerWidth);
127 // Subscribed rather than read once: the clamp must track live window size,
128 // and a clamped drag ends with an unchanged width, which skips the re-render
129 // that would otherwise refresh a render-time snapshot.
130 const viewportWidth = useSyncExternalStore(subscribeToViewportWidth, readViewportWidth);
131 const sidebarMaximumWidth = resolveThreadSidebarMaximumWidth(viewportWidth);
113132 const [isWindowFullscreen, setIsWindowFullscreen] = useState(() => {
114133 const getWindowFullscreenState = window.desktopBridge?.getWindowFullscreenState;
115134 return isMacosDesktop && typeof getWindowFullscreenState === "function"