Skip to content

refactor: rebuild chat composer on SwiftUI TextField#1076

Merged
datlechin merged 5 commits into
mainfrom
refactor/composer-textfield-axis-vertical
May 7, 2026
Merged

refactor: rebuild chat composer on SwiftUI TextField#1076
datlechin merged 5 commits into
mainfrom
refactor/composer-textfield-axis-vertical

Conversation

@datlechin

Copy link
Copy Markdown
Member

Summary

PR B of the chat panel redesign tracked in docs/refactor/ai-chat-redesign.md. Drops the 292-LOC ChatComposerTextView (NSViewRepresentable around NSTextView + NSScrollView + manual NSLayoutManager caret math + NSPopover + NSHostingController) and rebuilds the composer on pure SwiftUI primitives.

What changed

  • ChatComposerView (new, 189 LOC): TextField(text:, axis: .vertical) + .lineLimit(1...5) + .onSubmit + .onKeyPress(.upArrow / .downArrow / .tab / .escape) + native SwiftUI .popover. Pill-shaped Capsule background. Apple Intelligence focus glow on @FocusState change.
  • Apple Intelligence shimmer (~70 LOC, inline private types): 4 layered angular-gradient strokes (lineWidths 1.5/3/5/7, blurs 0/3/8/12, opacities 1.0/0.7/0.45/0.25) with stops randomized every 400ms and per-layer animation durations of 0.5/0.6/0.8/1.0s. Color palette is Apple's documented Intelligence pastel set (BC82F3 purple, F5B9EA pink, 8D9FFF blue, FF6778 red, FFBA71 orange, C686FF lavender). Respects accessibilityReduceMotion.
  • Chat actions move to inspector header: conversation history (clock) and new-conversation (square.and.pencil) move from the composer footer to the inspector header bar, trailing the Details / AI Chat segmented picker. Composer footer is now a single row of 5 actions: @, /, mode, model, send.
  • Empty state uses the project's EmptyStateView (which wraps macOS 14 ContentUnavailableView) for consistency with every other empty state in the app.
  • Drops ChatComposerTextView.swift (292 LOC), the NSTextView subclass, the NSScrollView container, the manual intrinsicContentSize math, and the deprecated TextKit 1 NSLayoutManager.glyphIndexForCharacter / boundingRect(forGlyphRange:) caret math.

Mention popover

The old composer anchored the mention popover at the caret using NSLayoutManager glyph rects. The new composer anchors it at the bottom of the composer (.popover(attachmentAnchor: .point(.bottom), arrowEdge: .top)). This matches Slack, Discord, Apple Mail address-autofill, and removes the only TextKit 1 dependency. MentionDetector, MentionPopoverState, and MentionSuggestionListView are unchanged.

Net code

  • 292 LOC deleted (ChatComposerTextView.swift)
  • 189 LOC added (ChatComposerView.swift, including the inline shimmer)
  • ~80 LOC moved (history + new-conversation: composer footer → inspector header)
  • 0 lines of NSViewRepresentable, 0 lines of TextKit 1, 0 lines of manual NSPopover

Test plan

  • Build the app, open a connection.
  • Switch the inspector to AI Chat. Confirm the inspector header shows Details | AI Chat on the left and clock | square.and.pencil on the right.
  • Click the composer. Confirm the pill border picks up an animated multi-color glow that morphs (not a static rainbow, not a mechanical rotation).
  • System Settings → Accessibility → Display → Reduce Motion → on. Click the composer. Confirm the glow is static (no animation).
  • Type 5+ lines of text. Confirm the composer grows up to 5 lines then scrolls.
  • Press Return. Confirm the message sends.
  • Press Shift+Return. Confirm a newline is inserted.
  • Type @. Confirm the mention popover opens anchored to the bottom of the composer.
  • Up/Down arrows navigate; Return or Tab inserts; Escape dismisses.
  • Click the clock icon in the inspector header. Confirm the history menu appears with recent conversations and a "Clear Recents" entry.
  • Click the new-conversation icon. Confirm a fresh conversation starts.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@datlechin datlechin merged commit 591dfa5 into main May 7, 2026
2 checks passed
@datlechin datlechin deleted the refactor/composer-textfield-axis-vertical branch May 7, 2026 12:17
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