Skip to content

fix(app): Fixes #16141 overlay happen in first user message.#16146

Open
Eric-Guo wants to merge 83 commits intoanomalyco:betafrom
Eric-Guo:app_message_overlap_2
Open

fix(app): Fixes #16141 overlay happen in first user message.#16146
Eric-Guo wants to merge 83 commits intoanomalyco:betafrom
Eric-Guo:app_message_overlap_2

Conversation

@Eric-Guo
Copy link
Contributor

@Eric-Guo Eric-Guo commented Mar 5, 2026

Issue for this PR

Fixes #16141, bug introduced at PR #15863

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Just fix UI issue

How did you verify your code works?

Manually tested and see UI screen shot.

Screenshots / recordings

Before:

Image

After

企业微信截图_17727019397734

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

If you do not follow this template your PR will be automatically rejected.

…ions

Add spring-based animations to the prompt input composer:
- Mode toggle (shell/conversation) indicator uses spring cubic-bezier
- Submit and plus buttons animate with individual scale, opacity, and blur
- Tray items (agent, model, variant selectors) crossfade with spring
- Shell label animates in/out opposite to normal mode controls
- Add TextStrikethrough component for todo item completion
- Add truncate support to TextReveal
- Wire up count mask/height/width props through composer region
…ometer with TextReveal

- Shell submessage now uses Motion's animate() with width: "auto" for
  spring-driven width reveal instead of CSS grid 0fr→1fr transition
- Skip animation on page load (sawPending flag), only animate live tool calls
- Fix baseline alignment with overflow: clip instead of overflow: hidden
- Replace TextOdometer with TextReveal in production (session-turn, todo-dock)
- Remove TextOdometer component, CSS, and stories
- Add TextReveal to thinking-heading story
- Update shell submessage story with visualDuration/bounce sliders
…submessage fade to JS

- Fix 6 instances where TextShimmer was destroyed/recreated via <Show>
  swap instead of toggling active prop (bash, webfetch, edit, write,
  context tools, basic-tool fallback)
- Move shell submessage opacity/blur from CSS transitions to animate()
  so they respect the animate prop and don't fire on page load
- Remove data-visible attribute pattern, all animation now driven by
  Motion's animate() when animate=true
- Remove Math.ceil rounding from spring animation frames to eliminate
  1px oscillation during height transitions
- Add will-change:height and contain:layout style during active springs
  for better compositor performance
- Replace blanket ResizeObserver gate with spring target deduplication
  so genuine content changes can re-target mid-flight without feedback loops
- Apply same Math.ceil removal and will-change/contain hints to the
  thinking box show/hide animations in session-turn
Remove rAF debounce from ResizeObserver callback in createAutoScroll
so scrollToBottom fires in the same frame as layout changes (no 1-frame
lag). Add GPU layer promotion (translateZ) on GrowBox and layout
containment on assistant content to reduce cross-element repaint.
Switch the scroll viewport to flex-direction: column-reverse so the
browser natively anchors to the bottom (scrollTop=0 = bottom). This
eliminates the 1-frame jitter between content height changes and scroll
position updates. Update all scrollTop math across auto-scroll, scroll
spy, gesture detection, hash scroll, and custom thumb to account for
the inverted coordinate system.
- Pass props.animate (not live()) to Message so user message GrowBox
  mounts with animate=true and properly runs height + fade animation
- Remove Math.ceil from BasicTool height spring to prevent 1px jitter
- Remove rAF debounce from BasicTool ResizeObserver for same-frame updates
- Use live() for AssistantParts to defer animation until streaming starts
Disable browser scroll anchoring (overflow-anchor: none) which
interferes with column-reverse, and restore scrollTop synchronously
before paint instead of in rAF with delta math.
Use splitProps instead of JS destructuring in ToolCallRoot to preserve
reactivity on forwarded props. Extract fade helpers in GrowBox to
deduplicate opacity/filter/blur patterns across mount and toggle paths
(also fixes mount fade-in cleanup not checking open() state). Simplify
redundant getDirectory ternary guards and contextToolSummary iteration.
Standardize all turn rows (tool calls, thinking, diff summary) to 36px
height with zero gaps between them. Previously rows were 32px with
varying gaps (2px/6px/8px/12px) causing inconsistent spacing and a
margin-top pop when the thinking indicator's gap changed reactively.

- Collapsible trigger: 32px -> 36px
- Thinking box: min-height 32px -> height 36px, gap removed (was 12px)
- Diff summary trigger: min-height 24px -> height 36px, gap removed
- Part gaps: removed all inter-part padding-top (was 0/2/6px)
- User message GrowBox: removed 8px gap
- Thread working prop to text parts for copy button visibility
- Wrap copy button in animated GrowBox with open/close transitions
- Simplify thinking show/hide by removing delay timer and using
  entry gate to prevent animation before live signal
- Batch optimistic message updates to prevent animate race condition
Copilot AI review requested due to automatic review settings March 5, 2026 09:28
@Eric-Guo Eric-Guo requested a review from adamdotdevin as a code owner March 5, 2026 09:28
@github-actions github-actions bot added needs:compliance This means the issue will auto-close after 2 hours. needs:title labels Mar 5, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Hey! Your PR title Fix(app): overlay happen in first user message. doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@Eric-Guo Eric-Guo changed the title Fix(app): overlay happen in first user message. fix(app): overlay happen in first user message. Mar 5, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions github-actions bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Mar 5, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@Eric-Guo Eric-Guo changed the title fix(app): overlay happen in first user message. fix(app): Fixes #16141 overlay happen in first user message. Mar 5, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a layout issue where the session title/header overlays the first user message by changing the timeline container to a flex-column layout and making the header participate in normal flow above the scroll viewport.

Changes:

  • Convert the timeline root container to flex flex-col with min-h-0 to support proper scroll sizing.
  • Move session header styling onto the header container (removing the extra wrapper) so it no longer overlays content.
  • Make the ScrollView a flex child (flex-1 min-h-0) so it takes the remaining height beneath the header.
Comments suppressed due to low confidence (1)

packages/app/src/pages/session/message-timeline.tsx:893

  • Now that the session title/header is no longer absolutely positioned over the scroll viewport (it’s a normal flex item above ScrollView), the scroll offsets exposed via --session-title-height / --sticky-accordion-top likely shouldn’t still be 40px / 48px. These vars are consumed for hash scrolling (use-session-hash-scroll.ts) and sticky tool headers (var(--sticky-accordion-top) in UI CSS), and keeping the old values will introduce an extra top gap / mis-position sticky headers and in-page scroll-to behavior. Consider setting both vars to 0px in this layout (or only setting non-zero values when the header actually overlays the scroll viewport).
          class="flex-1 min-h-0 relative min-w-0 w-full h-full"
          style={{
            "--session-title-height": showHeader() ? "40px" : "0px",
            "--sticky-accordion-top": showHeader() ? "48px" : "0px",
          }}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Eric-Guo Eric-Guo force-pushed the app_message_overlap_2 branch from 6367016 to 6267b97 Compare March 5, 2026 09:40
@opencode-agent opencode-agent bot force-pushed the beta branch 6 times, most recently from 04d6011 to 1aa0b18 Compare March 5, 2026 15:28
@kitlangton
Copy link
Contributor

Oh shit, sorry! I didn't see this and I made a bunch more changes. I might have fixed this though. Do you still see it on the newest version of my branch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants