Skip to content

feat: iOS blue-bubble chat feed anchored to the bottom - #39

Merged
joeblau merged 1 commit into
mainfrom
feat/chat-blue-bubbles-bottom-anchor
Jul 12, 2026
Merged

feat: iOS blue-bubble chat feed anchored to the bottom#39
joeblau merged 1 commit into
mainfrom
feat/chat-blue-bubbles-bottom-anchor

Conversation

@joeblau

@joeblau joeblau commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Summary

Reworks the main-screen chat feed to read like a chat app.

  • Bottom scroll anchor.defaultScrollAnchor(.bottom) on the ScrollView, so the newest message sits at the bottom of the screen on first paint and stays pinned as chat streams in.
  • iOS blue bubbles — each incoming message renders through a new MessageBubble: a secondary author + platform caption above a content-hugging systemBlue bubble (18pt continuous corners, white body text), left-aligned with a trailing Spacer(minLength: 40) so short messages stay short and long ones wrap without truncating.
  • Smarter follow — the old unconditional scroll-to-last is replaced with an isAtBottom-gated animated follow (tracked via .onScrollGeometryChange), so a viewer scrolled up reading history is no longer yanked to the bottom on every new message.
  • Accessibility — each row folds into a single VoiceOver element ("<author> on <platform>: <text>").
  • Empty-state ContentUnavailable overlay and per-row .id(message.id) preserved.

How it was built

A 5-agent workflow: 3 independent designs (faithful-iMessage / modern-clean / robust-a11y) → judged & synthesized (winner grafted the accessibility+follow engine onto the iMessage caption) → adversarial SwiftUI review → SHIP.

Known tradeoffs (reviewed & accepted)

  • White-on-blue body text is ~4.0:1 contrast, just under WCAG AA (4.5:1) — this is Apple's exact iMessage pairing and matches the "blue bubble" request. Easy to nudge darker/bolder if strict AA is wanted.
  • The gated animated follow is occasionally a visual no-op (the anchor already instant-follows); harmless, no fight between the two mechanisms.

Testing

  • xcodebuild build -scheme Stream -destination 'generic/platform=iOS'BUILD SUCCEEDED.
  • Changes are app-target UI only; StreamCore test suite unaffected.
  • Not yet visually verified on device (device-only iOS 26/27 build).

🤖 Generated with Claude Code

The chat feed now reads like a chat app: the ScrollView default-anchors to
the bottom (.defaultScrollAnchor(.bottom)) so the newest message sits at the
bottom of the screen on first paint and stays pinned as messages stream in.

Each incoming message renders through a new MessageBubble: a secondary
author + platform caption above a content-hugging systemBlue bubble (18pt
continuous corners, white body text), left-aligned with a trailing Spacer so
short messages stay short and long ones wrap without truncating. The row folds
into a single VoiceOver element ("<author> on <platform>: <text>").

The previous unconditional scroll-to-last is replaced with an isAtBottom-gated
animated follow (tracked via .onScrollGeometryChange), so a viewer scrolled up
reading history is no longer yanked to the bottom on every new message. The
empty-state ContentUnavailable overlay and per-row .id are preserved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@joeblau
joeblau merged commit ef9fa5b into main Jul 12, 2026
1 check passed
@joeblau
joeblau deleted the feat/chat-blue-bubbles-bottom-anchor branch July 12, 2026 11:49
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.

1 participant