Skip to content

Commit 20ce8b5

Browse files
fix(mothership): suppress shimmer over executing tool rows and seed chase interrupt baseline
1 parent 6bddf6f commit 20ce8b5

2 files changed

Lines changed: 17 additions & 6 deletions

File tree

apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -857,12 +857,14 @@ function MessageContentInner({
857857
// output actually arrives: hidden while the trailing text is visibly
858858
// revealing or any lane streamed within the quiet period, shown otherwise.
859859
// Immediately on an empty turn — nothing has arrived yet. A null label means
860-
// a just-opened lane's delegating shimmer owns the state.
860+
// a just-opened lane's delegating shimmer owns the state, and a visible
861+
// executing tool row already spins — the turn-level shimmer would double it.
861862
const thinkingLabel = deriveThinkingLabel(blocks)
863+
const hasExecutingTool = assistantMessageHasVisibleExecutingTool(blocks)
862864
const showShimmer =
863865
thinkingExpanded &&
864866
thinkingLabel !== null &&
865-
(segments.length === 0 || (isStreamIdle && !trailingStreamActivity))
867+
(segments.length === 0 || (isStreamIdle && !trailingStreamActivity && !hasExecutingTool))
866868

867869
return (
868870
<div>

apps/sim/lib/core/utils/smooth-bottom-chase.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,23 @@ export function createSmoothBottomChase(
9898
raf = requestAnimationFrame(step)
9999
}
100100

101+
// Seed the upward-move interrupt baseline at (re)start so a user scroll-up
102+
// between the kick and the first frame parks the loop immediately — without
103+
// it the first step has no baseline and writes one downward frame against
104+
// the user (relevant on the teardown kickUntil, where the gesture listeners
105+
// are already gone).
106+
const start = () => {
107+
if (raf !== null) return
108+
lastTop = target.getTop()
109+
raf = requestAnimationFrame(step)
110+
}
111+
101112
return {
102113
isActive: () => raf !== null,
103-
kick: () => {
104-
if (raf === null) raf = requestAnimationFrame(step)
105-
},
114+
kick: start,
106115
kickUntil: (durationMs: number) => {
107116
deadline = Math.max(deadline, performance.now() + durationMs)
108-
if (raf === null) raf = requestAnimationFrame(step)
117+
start()
109118
},
110119
cancel: park,
111120
}

0 commit comments

Comments
 (0)