Skip to content

Float a frosted header and composer over the mobile chat, without the iOS 26 dimming - #1889

Merged
DoodleBears merged 5 commits into
mainfrom
claude/mobile-chat-header-3bkg6h
Oct 15, 2026
Merged

DoodleBears merged 5 commits into
mainfrom
claude/mobile-chat-header-3bkg6h

Conversation

@DoodleBears

@DoodleBears DoodleBears commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Vain · project thread

Why the change

Before:

  • On iOS 26 a Bot DM or group Channel opened with its whole message list dimmed. The Simulator queue bisected the dimming to Fade the mobile DM above the composer and move Model and Workspace into the Bot profile #1875's transparent native header (headerTransparent). That header leaves an AdditionalDimmingOverlay as a direct subview of the list's UIScrollView. Setting scrollEdgeEffects to hidden on the screen did not remove it, because react-native-screens applies that setting only to the first scroll view in the screen's first-child chain.
  • The message list stopped at a bar above the composer.
  • Both fades were strong, and the chip and composer were opaque.

After (Vain's follow-ups, Telegram as the reference):

  • Floating header, no native bar. The native stack header is hidden (headerShown: false). The chat draws its own header instead: back on the left, the chip in the middle and the computer button on the right, floating over the messages. Messages run under it and the status bar. With no native navigation bar over the list, UIKit has nothing to dim it with. The swipe back is a screen gesture and still works.
  • Floating composer. The list runs to the bottom of the screen, and the composer floats over it with no bar of its own.
  • Frosted chrome. The chip, the round buttons and the composer pill are frosted: their layer fill at glass.tint (72%) opacity. Messages show faintly through them as they pass under.
  • Lighter fades. Both edge fades are lighter (edgeFade.stops: 80% at the screen edge, 40% at the middle, 0 at the end). The top fade covers the header and edgeFade.top below it. The bottom fade covers the composer and edgeFade.bottom above it.

Special things to note

  • Merge risk: mobile JavaScript only, no new development build needed.
  • There is no live blur behind the frosted fills, only a tint. Real frosted glass needs expo-blur (a native module and a rebuild), and a blur view over a scrolling list re-renders every frame.
  • On iOS 26 the back and computer buttons are now our round frosted buttons, not the system's Liquid Glass bar buttons. The full client button's icon now takes the Bot's accent like the rest of the screen, because it renders inside the screen's AccentProvider.
  • The composer's measured height drives the list inset, the bottom fade and the jump-to-latest button's offset. The KeyboardAvoidingView needs no offset now that there is no native header.
  • Verification:
    • Mobile typecheck and vitest run pass (34 files, 277 tests).
    • pnpm lint, oxfmt --check and changelog:check are clean.
    • node scripts/e2e-mobile-follow-latest-web.mjs passes, including tapping the chip into the Bot profile. The screenshots below come from it.
    • The iOS 26 check is in the Simulator queue.
  • CI test plan: affected.

Change outline

  • src/ui/chat/header-chrome.tsx: ChatHeader and useChatHeaderHeight; the round buttons are frosted; systemGlassBar is removed.
  • src/ui/chat/conversation-screen.tsx: hides the native header and renders ChatHeader; the top fade spans the header; the composer floats in the list wrapper.
  • src/ui/design/theme.tsx: adds frosted(fill).
  • src/ui/chat/chat-title.tsx, channel-title.tsx and composer.tsx: frosted fills; the composer root has no background.
  • src/ui/design/tokens.ts: lighter edgeFade.stops, plus edgeFade.top.
  • DESIGN.md and the Fade the mobile DM above the composer and move Model and Workspace into the Bot profile #1875 change fragment are updated to match.
Light Dark
Scrolled into history
At the latest message

Human QA

  • On iOS 26, in light and dark, open a Bot DM and a group Channel. The list is not dimmed, and the accessibility tree has no AdditionalDimmingOverlay.
  • Scroll up. Messages pass under the status bar and the header chip, showing faintly through the chip and the buttons, and fade lightly.
  • At the bottom, the list runs under the composer and messages show faintly through the pill.
  • Back works, and so does the swipe back from the left edge. Tapping the chip opens the Bot profile.
  • Focus the composer. The keyboard lifts it.
  • Type @ in a group Channel. The mention list shows above the composer.
  • Scroll up. The jump button sits above the composer.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LzUNRQhy85WgjWULziwrxc

With headerTransparent, iOS 26 adds an AdditionalDimmingOverlay inside the
inverted message list's UIScrollView, and scrollEdgeEffects 'hidden' on the
screen does not reach it. The header now has a base fill (the pre-#1875
configuration the Simulator bisect found clean), the list starts below it,
and the top fade sits at the top of the list like the bottom one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LzUNRQhy85WgjWULziwrxc
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 9 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a82a2f3a-4a9d-4de3-87c4-d38fd4773907
📥 Commits

Reviewing files that changed from the base of the PR and between 0bfbc6a and 4eaeba4.

⛔ Files ignored due to path filters: 4
  • .github/pr-screenshots/mobile-dm-no-dim/latest-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/mobile-dm-no-dim/latest-light.png is excluded by !**/*.png
  • .github/pr-screenshots/mobile-dm-no-dim/scrolled-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/mobile-dm-no-dim/scrolled-light.png is excluded by !**/*.png
📒 Files selected for processing: 9
  • apps/mobile/DESIGN.md
  • apps/mobile/src/ui/chat/channel-title.tsx
  • apps/mobile/src/ui/chat/chat-title.tsx
  • apps/mobile/src/ui/chat/composer.tsx
  • apps/mobile/src/ui/chat/conversation-screen.tsx
  • apps/mobile/src/ui/chat/header-chrome.tsx
  • apps/mobile/src/ui/design/theme.tsx
  • apps/mobile/src/ui/design/tokens.ts
  • changes/1875-mobile-chat-header.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…ttom

The message list now runs to the bottom of the screen and the composer
floats over it with no bar, like Telegram. A static base gradient covers
the composer and edgeFade.bottom above it, and the list keeps that much
space below the newest message.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LzUNRQhy85WgjWULziwrxc
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LzUNRQhy85WgjWULziwrxc
@DoodleBears DoodleBears changed the title Stop the mobile DM list from dimming on iOS 26 Stop the mobile DM list from dimming on iOS 26 and float the composer over the chat Oct 15, 2026
The native stack header is hidden and the chat draws its own floating
header, so messages run under the chip without the iOS 26 dimming that a
transparent native header causes. The chip, round buttons and composer
pill are frosted (raised or surface at glass.tint opacity), and both edge
fades are lighter, so messages show faintly through them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LzUNRQhy85WgjWULziwrxc
@DoodleBears DoodleBears changed the title Stop the mobile DM list from dimming on iOS 26 and float the composer over the chat Float a frosted header and composer over the mobile chat, without the iOS 26 dimming Oct 15, 2026
Messages pass around and under the floating composer, but the pill keeps
its opaque surface fill so nothing shows through where the Human types.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LzUNRQhy85WgjWULziwrxc
@DoodleBears
DoodleBears merged commit d4b7096 into main Oct 15, 2026
9 checks passed
@DoodleBears

Copy link
Copy Markdown
Contributor Author

Batch QA — iOS Simulator (PR1800 glass, iOS 26, iPhone 17 Pro), head 4eaeba4

Base: qa/batch-2 c2c15e65c = main 0bfbc6a + #1716 #1874 #1884 #1885 #1886 #1889. QA Host on DeepSeek. Screenshots are redacted (hostnames and local paths blacked out). Chinese text shows as □ because the iOS 26.0 Simulator runtime has no PingFang font; that is an environment issue.

Step Result
1. No AdditionalDimmingOverlay in a Bot DM or in a group Channel; list not dimmed (light + dark) ✅ pass
2. Scrolled up: messages pass under the status bar and the frosted chip and show through it; composer pill opaque, list runs under/around it ✅ pass
3. Back button, left-edge swipe back, chip → Bot profile (Bot settings group still there) ✅ pass
4. Keyboard lifts the composer ✅ pass
5. @ mention list and "Return to latest messages" button sit above the composer ✅ pass
Android untested

Note: the dim root cause was bisected to eb8cf06 (#1875 transparent header); the overlay was a UIScrollView subview (scroll-edge effect), not a nav bar or modal.

DM light DM dark Group light Group dark
Mention list above composer Jump button light Jump button dark

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants