Repository navigation
iOS: nest composer attachment preview inside the field bubble (iMessage-style) - #6813
austinywang wants to merge 12 commits into
Conversation
…ge-style) Fixes #6643. When an image is attached to the iOS terminal composer, the thumbnail chip rendered as a detached row ABOVE the rounded glass field, anchored only by an ad-hoc `.padding(.leading, controlHeight + 8)` (48pt). That inset matched neither the paperclip column (12pt) nor the field/text column (~108pt), so the thumbnail floated above the gap between the paperclip and mic buttons and read as a stray square. Match iMessage: render the staged thumbnails INSIDE the same rounded `.mobileGlassField` container as the text field, stacked above the text and sharing the field's leading text inset. The bubble grows to wrap the image and the send button stays pinned bottom-trailing. - `MobileComposerFieldContainer` (shared by the terminal composer and GUI chat) gains an optional `header` slot rendered inside the glass, above the field row, at the field's 14pt leading inset. A two-closure convenience initializer (`Header == EmptyView`) keeps every existing call site (ChatComposerView) compiling and laying out exactly as before. - `TerminalComposerView.composerBar` moves the attachment chip row from a sibling above the input HStack into the field container's header, dropping the hand-tuned 48pt leading inset. The chip row hugs its content height via `fixedSize(vertical:)` so the bubble grows by exactly the chip row. Layout-only change (no behavior or string changes); not cleanly unit-testable without composer snapshot infrastructure, which the repo does not have. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe iOS composer now uses a container that can render a header above the text field row. ChangesComposer bubble layout
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 25✅ Passed checks (25 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Greptile SummaryThis PR fixes the floating attachment chip row in the iOS terminal composer by nesting thumbnails inside the same rounded glass field container — matching iMessage's layout — instead of rendering them as a detached sibling view with a hand-tuned 48pt leading inset.
Confidence Score: 5/5Safe to merge — purely a layout reorganization with no behavioral, state, or API changes outside the composer surface. All three files contain straightforward layout changes: the generic Header slot in MobileComposerFieldContainer is backward-compatible via a constrained extension initializer, the fixedSize modifier and isEmpty onChange are both standard SwiftUI patterns applied correctly, and no logic paths, concurrency, persistence, or external APIs are touched. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[composerBar HStack / .bottom] --> B[MobileComposerIconButton paperclip]
A --> C[micButton]
A --> D[MobileComposerFieldContainer]
D --> E[VStack / .leading / spacing 6]
E --> F{pendingAttachments.isEmpty?}
F -- false --> G[attachmentChipRow ScrollView horizontal fixedSize vertical true]
F -- true --> H[EmptyView / collapses]
E --> I[HStack / .bottom / spacing 8]
I --> J[TextField multi-line grows 1-14 lines]
I --> K[Send Button circle bottom-trailing]
subgraph HeightRemeasure
L[onChange terminalInputText] --> M[requestHeightRemeasure]
N[onChange pendingAttachments.isEmpty] --> M
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[composerBar HStack / .bottom] --> B[MobileComposerIconButton paperclip]
A --> C[micButton]
A --> D[MobileComposerFieldContainer]
D --> E[VStack / .leading / spacing 6]
E --> F{pendingAttachments.isEmpty?}
F -- false --> G[attachmentChipRow ScrollView horizontal fixedSize vertical true]
F -- true --> H[EmptyView / collapses]
E --> I[HStack / .bottom / spacing 8]
I --> J[TextField multi-line grows 1-14 lines]
I --> K[Send Button circle bottom-trailing]
subgraph HeightRemeasure
L[onChange terminalInputText] --> M[requestHeightRemeasure]
N[onChange pendingAttachments.isEmpty] --> M
end
Reviews (9): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/TerminalComposerView.swift`:
- Around line 285-291: The composer height is driven by staged attachments in
TerminalComposerView, but requestHeightRemeasure() only runs from text and local
picker/remove/send actions. Add a change hook tied to pendingAttachments (or
their count/IDs) so any attachment added through the store, including
paste-driven staging, triggers a remeasure. Wire it in the same view where
attachmentChipRow is shown and keep the existing text-based remeasure paths
intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 73e4c982-2630-4735-86ed-beb417665280
📒 Files selected for processing (2)
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/TerminalComposerView.swiftPackages/iOS/CmuxMobileSupport/Sources/CmuxMobileSupport/MobileComposerFieldContainer.swift
This comment has been minimized.
This comment has been minimized.
Satisfies the Aziz DocC policy: the public extension declaration needs a triple-slash doc comment, not only its member initializer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drive the band re-measure off pendingAttachments.count (symmetric with the existing terminalInputText height driver) so the bubble grows for any staging route instead of relying on each mutation path to call requestHeightRemeasure(). Addresses CodeRabbit review feedback on #6813. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The added onChange comment pushed TerminalComposerView.swift to 827 lines (budget 825). Condense the comment; the file is back to 824, under budget, with no logic change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ed-image-preview-is-misaligned # Conflicts: # Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/TerminalComposerView.swift
…ed-image-preview-is-misaligned
…ed-image-preview-is-misaligned
…ed-image-preview-is-misaligned
…ed-image-preview-is-misaligned
…ed-image-preview-is-misaligned
…ed-image-preview-is-misaligned # Conflicts: # .github/swift-file-length-budget.tsv
Fixes #6643.
Problem
On the iOS app, attaching an image to the terminal composer rendered the thumbnail chip as a detached row above the rounded glass field, anchored only by an ad-hoc
.padding(.leading, controlHeight + 8)= 48pt. That inset matched neither the paperclip column (12pt) nor the field/text column (~108pt), so the thumbnail floated above the gap between the paperclip and mic buttons and read as a stray square rather than part of the composer.Fix
Match iMessage: render the staged thumbnail(s) inside the same rounded
.mobileGlassFieldcontainer as the text field — stacked above the text, sharing the field's true leading text inset. The bubble grows to wrap the image and the send button stays pinned bottom-trailing.MobileComposerFieldContainer(the shared shell used by both the terminal composer and GUI chat) gains an optionalheaderslot rendered inside the glass, above the field row, at the field's 14pt leading inset. A two-closure convenience initializer (Header == EmptyView) keeps every existing call site (ChatComposerView) compiling and laying out exactly as before — no behavior change for callers that pass no header.TerminalComposerView.composerBarmoves the attachment chip row from a sibling above the inputHStackinto the field container'sheader, dropping the hand-tuned 48pt leading inset. The chip row hugs its content height viafixedSize(vertical:)so the bubble grows by exactly the chip row height (not greedily).Scope / testing
L10n.stringcalls, none added or changed).ChatComposerView'sattachmentStriphas a related floating-chip layout and can now adopt the same sharedheaderslot.Demo Video
Visual verification was performed for the original UI fix from the tagged debug build noted in the PR description. No public demo video is attached because this is an iOS app composer alignment fix.
Review Trigger
$autoreview --mode branch.Checklist
🤖 Generated with Claude Code
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by cubic
Nest attachment thumbnails inside the rounded
mobileGlassFieldbubble in the iOS terminal composer (iMessage-style) to fix the floating chip row in #6643. The bubble expands to fit previews; send stays bottom-trailing, and the composer remeasures when the attachment count changes.Bug Fixes
fixedSize(vertical:)so the bubble grows only by the chip height.pendingAttachments.countto cover all staging paths.Refactors
headerslot toMobileComposerFieldContainer, rendered inside the glass above the field; include a header-less convenience initializer with DocC. Existing layouts are unchanged.Written for commit 05901c0. Summary will update on new commits.
Summary by CodeRabbit
New Features
Bug Fixes