diff --git a/apps/web/src/components/chat/MessagesTimeline.tsx b/apps/web/src/components/chat/MessagesTimeline.tsx index d09005323bac2..e9cc2141e82c6 100644 --- a/apps/web/src/components/chat/MessagesTimeline.tsx +++ b/apps/web/src/components/chat/MessagesTimeline.tsx @@ -604,7 +604,7 @@ const ConversationTimeline = memo(function ConversationTimeline({ const list = listRef.current; if (list) { list.cancelScroll(); - list.anchorVisibleContent({ key: "working-indicator-row" }); + if (workingHistoryKey !== key) list.anchorVisibleContent({ key: "working-indicator-row" }); } setWorkingHistoryKey((current) => (current === key ? null : key)); }; @@ -1691,6 +1691,7 @@ const ConversationTimeline = memo(function ConversationTimeline({ : maintainVisibleContentPosition } maintainScrollAtEndThreshold={1} + immediateWebShrinks={workingHistoryCollapsing} onScroll={handleScroll} onItemSizeChanged={scheduleMinimapRefresh} onMetricsChange={scheduleMinimapRefresh} diff --git a/patches/@legendapp__list@3.7.2.patch b/patches/@legendapp__list@3.7.2.patch index 216f21114a1c8..5055dac08d6fe 100644 --- a/patches/@legendapp__list@3.7.2.patch +++ b/patches/@legendapp__list@3.7.2.patch @@ -1,5 +1,17 @@ +diff --git a/react.d.ts b/react.d.ts +index 358fcd7..e3c7de6 100644 +--- a/react.d.ts ++++ b/react.d.ts +@@ -314,6 +314,7 @@ interface LegendListSpecificProps { + * @default 0.1 + */ + maintainScrollAtEndThreshold?: number; ++ immediateWebShrinks?: boolean; + /** + * Maintains visibility of content. + * - size (default: true) stabilizes during size/layout changes while scrolling. diff --git a/react.js b/react.js -index 5155454..2885128 100644 +index 5155454..b63bce6 100644 --- a/react.js +++ b/react.js @@ -3489,6 +3489,12 @@ function abortBootstrapInitialScroll(ctx) { @@ -42,7 +54,14 @@ index 5155454..2885128 100644 const previousRect = prevRect != null ? prevRect : getContainerLayoutBaseline(element); const didSizeChange = previousRect === void 0 || rectObserved.width !== previousRect.width || rectObserved.height !== previousRect.height; prevRect = rectObserved; -@@ -6296,7 +6302,7 @@ function processContainerLayout({ containerId, ctx, rectangle, ref, state }) { +@@ -6290,13 +6296,13 @@ function processContainerLayout({ containerId, ctx, rectangle, ref, state }) { + size: layout + }); + }; +- const shouldDeferWebShrinkLayoutUpdate = !isInMVCPActiveMode(listState) && previousSize !== void 0 && size + 1 < previousSize; ++ const shouldDeferWebShrinkLayoutUpdate = !listState.props.immediateWebShrinks && !isInMVCPActiveMode(listState) && previousSize !== void 0 && size + 1 < previousSize; + if (shouldDeferWebShrinkLayoutUpdate) { + scheduleWebShrinkMeasurement(state, () => { var _a4; if (state.itemKey === currentItemKey) { const element = ref.current; @@ -51,8 +70,24 @@ index 5155454..2885128 100644 if (rect) { layout = { height: rect.height, width: rect.width }; } +@@ -9133,6 +9139,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded + getFixedItemSize, + getItemType, + horizontal, ++ immediateWebShrinks, + rtl, + estimatedHeaderSize, + initialScrollAtEnd = false, +@@ -9431,6 +9438,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded + hasExternalScroll, + hideItemsUntilMeasured: experimental_hideItemsUntilMeasured, + horizontal: !!horizontal, ++ immediateWebShrinks: !!immediateWebShrinks, + itemsAreEqual, + keyExtractor: useWrapIfItem(keyExtractor), + maintainScrollAtEnd: maintainScrollAtEndConfig, diff --git a/react.mjs b/react.mjs -index ce08abe..2c764cb 100644 +index ce08abe..294988d 100644 --- a/react.mjs +++ b/react.mjs @@ -3468,6 +3468,12 @@ function abortBootstrapInitialScroll(ctx) { @@ -95,7 +130,14 @@ index ce08abe..2c764cb 100644 const previousRect = prevRect != null ? prevRect : getContainerLayoutBaseline(element); const didSizeChange = previousRect === void 0 || rectObserved.width !== previousRect.width || rectObserved.height !== previousRect.height; prevRect = rectObserved; -@@ -6275,7 +6281,7 @@ function processContainerLayout({ containerId, ctx, rectangle, ref, state }) { +@@ -6269,13 +6275,13 @@ function processContainerLayout({ containerId, ctx, rectangle, ref, state }) { + size: layout + }); + }; +- const shouldDeferWebShrinkLayoutUpdate = !isInMVCPActiveMode(listState) && previousSize !== void 0 && size + 1 < previousSize; ++ const shouldDeferWebShrinkLayoutUpdate = !listState.props.immediateWebShrinks && !isInMVCPActiveMode(listState) && previousSize !== void 0 && size + 1 < previousSize; + if (shouldDeferWebShrinkLayoutUpdate) { + scheduleWebShrinkMeasurement(state, () => { var _a4; if (state.itemKey === currentItemKey) { const element = ref.current; @@ -104,6 +146,22 @@ index ce08abe..2c764cb 100644 if (rect) { layout = { height: rect.height, width: rect.width }; } +@@ -9112,6 +9118,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded + getFixedItemSize, + getItemType, + horizontal, ++ immediateWebShrinks, + rtl, + estimatedHeaderSize, + initialScrollAtEnd = false, +@@ -9410,6 +9417,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded + hasExternalScroll, + hideItemsUntilMeasured: experimental_hideItemsUntilMeasured, + horizontal: !!horizontal, ++ immediateWebShrinks: !!immediateWebShrinks, + itemsAreEqual, + keyExtractor: useWrapIfItem(keyExtractor), + maintainScrollAtEnd: maintainScrollAtEndConfig, diff --git a/react-native.js b/react-native.js index 4af685dfb961eb0c8a4bf1ae9132c9304cf4fa4d..df4ead7ae4f03cd0fbcd99a3df7d95e15b1852b1 100644 --- a/react-native.js diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a700d9ba446e3..6213dab66f182 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -361,7 +361,7 @@ patchedDependencies: '@cursor/sdk@1.2.0': b9966f50182358ded9d1a72f39d9cd850f2e7471e7b8224d3d618bdbbe00e055 '@effect/vitest@4.1.2': 299510b71c36537a832a67e9d160a5f112a5f326a29e95c41cb45fc8234e47c7 '@ff-labs/fff-node@0.11.0': cc71fcec015f4d39bc96ae2e2bf6b0ca678124c722c66a7841efce9d34b5983c - '@legendapp/list@3.7.2': 1b69ae7ff8d3fd8af2ff9f0a23e16e8fdf5821108ac3fa645844a749e3f11dee + '@legendapp/list@3.7.2': 7c04cd8d87432d6f5af0f66d069d09e61fa4ea1f3d26ac0b29795e24f6d5a01e '@muse-code/sdk@1.4.6': 7b495b607fc5d76b444c7c4d58821e839726a30e6f3c53564f0d59f2d5b42101 '@pierre/diffs@1.7.0-beta.3': aea143f4a2e59744371219c4e7ae675ec739c9ba16f1732e2f11748b496ea05e '@pierre/trees@1.0.0-beta.6': a8aee792a9c8195bd88648982be72c108346bc06f7e013dbe1d65aaa572470b6 @@ -558,7 +558,7 @@ importers: version: 4.2.13 '@legendapp/list': specifier: 3.7.2 - version: 3.7.2(patch_hash=1b69ae7ff8d3fd8af2ff9f0a23e16e8fdf5821108ac3fa645844a749e3f11dee)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(bufferutil@4.1.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(react@19.3.0) + version: 3.7.2(patch_hash=7c04cd8d87432d6f5af0f66d069d09e61fa4ea1f3d26ac0b29795e24f6d5a01e)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(bufferutil@4.1.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(react@19.3.0) '@material/material-color-utilities': specifier: 0.3.0 version: 0.3.0 @@ -1079,7 +1079,7 @@ importers: version: 5.3.0 '@legendapp/list': specifier: 3.7.2 - version: 3.7.2(patch_hash=1b69ae7ff8d3fd8af2ff9f0a23e16e8fdf5821108ac3fa645844a749e3f11dee)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(bufferutil@4.1.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(react@19.3.0) + version: 3.7.2(patch_hash=7c04cd8d87432d6f5af0f66d069d09e61fa4ea1f3d26ac0b29795e24f6d5a01e)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(bufferutil@4.1.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(react@19.3.0) '@noble/hashes': specifier: 'catalog:' version: 1.8.0 @@ -15522,7 +15522,7 @@ snapshots: '@koromix/koffi-win32-x64@3.3.6': optional: true - '@legendapp/list@3.7.2(patch_hash=1b69ae7ff8d3fd8af2ff9f0a23e16e8fdf5821108ac3fa645844a749e3f11dee)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(bufferutil@4.1.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(react@19.3.0)': + '@legendapp/list@3.7.2(patch_hash=7c04cd8d87432d6f5af0f66d069d09e61fa4ea1f3d26ac0b29795e24f6d5a01e)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(@react-native/metro-config@0.88.1(@babel/core@7.29.7(supports-color@8.1.1))(bufferutil@4.1.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(supports-color@8.1.1)(utf-8-validate@6.0.6))(react@19.3.0)': dependencies: react: 19.3.0 use-sync-external-store: 1.7.0(react@19.3.0)