Unified · Split
| @@ -9,6 +9,7 @@ import { · 8 unmodified lines | ||
| 9 | 9 | type ColorValue, |
| 10 | 10 | Pressable, |
| 11 | 11 | ScrollView, |
| 12 | + StyleSheet, | |
| 12 | 13 | View, |
| 13 | 14 | } from "react-native"; |
| 14 | 15 | import Svg, { Defs, LinearGradient, Rect, Stop } from "react-native-svg"; |
| @@ -143,7 +144,7 @@ function ShimmeringWorkContent(props: { · 128 unmodified lines | ||
| 143 | 144 | |
| 144 | 145 | return ( |
| 145 | 146 | <View |
| 146 | − className="min-w-0 flex-1" | |
| 147 | + className="min-w-0 flex-1 overflow-hidden" | |
| 147 | 148 | onLayout={(event) => setAvailableWidth(event.nativeEvent.layout.width)} |
| 148 | 149 | > |
| 149 | 150 | <ShimmerWorkContent |
| @@ -164,7 +165,7 @@ function ShimmeringWorkContent(props: { · 14 unmodified lines | ||
| 164 | 165 | style={[{ width: SHIMMER_WIDTH }, sweepStyle]} |
| 165 | 166 | > |
| 166 | 167 | <MaskedView |
| 167 | − className="absolute inset-0" | |
| 168 | + style={StyleSheet.absoluteFill} | |
| 168 | 169 | maskElement={ |
| 169 | 170 | <Svg width="100%" height="100%"> |
| 170 | 171 | <Defs> |
| @@ -942,8 +942,27 @@ describe("buildThreadFeed", () => { · 941 unmodified lines | ||
| 942 | 942 | summary: "Running pnpm", |
| 943 | 943 | summaryKind: "command", |
| 944 | 944 | live: true, |
| 945 | − shimmer: false, | |
| 945 | + shimmer: true, | |
| 946 | 946 | }); |
| 947 | + expect(rows[0]).toMatchObject({ live: false, shimmer: false }); | |
| 948 | + | |
| 949 | + const stoppedRows = deriveThreadFeedPresentation(feed, latestTurn, new Set()); | |
| 950 | + expect(stoppedRows.filter((entry) => entry.type === "work-toggle")).toMatchObject([ | |
| 951 | + { live: false, shimmer: false }, | |
| 952 | + { live: false, shimmer: false }, | |
| 953 | + ]); | |
| 954 | + | |
| 955 | + const completedRows = deriveThreadFeedPresentation( | |
| 956 | + feed, | |
| 957 | + { ...latestTurn, state: "completed", completedAt: "2026-04-01T00:00:04.000Z" }, | |
| 958 | + new Set([turnId]), | |
| 959 | + new Set(), | |
| 960 | + latestTurn.startedAt, | |
| 961 | + ); | |
| 962 | + expect(completedRows.filter((entry) => entry.type === "work-toggle")).toMatchObject([ | |
| 963 | + { live: false, shimmer: false }, | |
| 964 | + { live: false, shimmer: false }, | |
| 965 | + ]); | |
| 947 | 966 | }); |
| 948 | 967 | |
| 949 | 968 | it("does not revive cached in-progress tools after work stops", () => { |
| @@ -1512,10 +1512,8 @@ function appendToolGroupRows( · 1511 unmodified lines | ||
| 1512 | 1512 | ), |
| 1513 | 1513 | hasFailure: activities.findLast((activity) => activity.toolLike)?.status === "failure", |
| 1514 | 1514 | live, |
| 1515 | − shimmer: | |
| 1516 | − isWorking && | |
| 1517 | − latestActivity.lifecycleStatus === "inProgress" && | |
| 1518 | − latestActivity.turnId === unsettledTurnId, | |
| 1515 | + // Match the live label until the turn or contiguous tool run settles. | |
| 1516 | + shimmer: live, | |
| 1519 | 1517 | }); |
| 1520 | 1518 | if (!expanded) { |
| 1521 | 1519 | return; |