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 @@...@@ -1,6 +1,12 @@
1import { useAtomValue } from "@effect/atom-react";1import { useAtomValue } from "@effect/atom-react";
2import * as Schema from "effect/Schema";2import * 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";
4import { useLocation, useNavigate } from "@tanstack/react-router";10import { useLocation, useNavigate } from "@tanstack/react-router";
511
6import { isElectron } from "../env";12import { isElectron } from "../env";
...@@ -31,6 +37,15 @@ import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip";...@@ -31,6 +37,15 @@ import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip";
3137
32const MACOS_TRAFFIC_LIGHTS_LEFT_INSET = "90px";38const 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
34function readInitialThreadSidebarWidth(): number {49function readInitialThreadSidebarWidth(): number {
35 try {50 try {
36 return resolveInitialThreadSidebarWidth(51 return resolveInitialThreadSidebarWidth(
...@@ -109,7 +124,11 @@ export function AppSidebarLayout({ children }: { children: ReactNode }) {...@@ -109,7 +124,11 @@ export function AppSidebarLayout({ children }: { children: ReactNode }) {
109 const useSidebarV2Theme = useSidebarV2 || isOnSettings;124 const useSidebarV2Theme = useSidebarV2 || isOnSettings;
110 const isMacosDesktop = isElectron && isMacPlatform(navigator.platform);125 const isMacosDesktop = isElectron && isMacPlatform(navigator.platform);
111 const [sidebarWidth, setSidebarWidth] = useState(readInitialThreadSidebarWidth);126 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);
113 const [isWindowFullscreen, setIsWindowFullscreen] = useState(() => {132 const [isWindowFullscreen, setIsWindowFullscreen] = useState(() => {
114 const getWindowFullscreenState = window.desktopBridge?.getWindowFullscreenState;133 const getWindowFullscreenState = window.desktopBridge?.getWindowFullscreenState;
115 return isMacosDesktop && typeof getWindowFullscreenState === "function"134 return isMacosDesktop && typeof getWindowFullscreenState === "function"