Skip to content

feat: add message pining to macOS#48

Merged
sirily11 merged 1 commit into
mainfrom
desktop-list
May 22, 2026
Merged

feat: add message pining to macOS#48
sirily11 merged 1 commit into
mainfrom
desktop-list

Conversation

@sirily11

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings May 22, 2026 07:07
@sirily11 sirily11 enabled auto-merge (squash) May 22, 2026 07:07
@autopilot-project-manager autopilot-project-manager Bot added the enhancement New feature or request label May 22, 2026
@vercel

vercel Bot commented May 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rxcode Ready Ready Preview, Comment May 22, 2026 7:10am

Request Review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds “pin latest user message to top” behavior to the macOS chat transcript, mirroring the existing mobile flow so freshly-sent turns stay stable while streaming/layout settles.

Changes:

  • Replaces macOS MessageListView’s List implementation with a ScrollView/LazyVStack and introduces active-turn pin-to-top + dynamic tail spacer logic.
  • Adds ChatBridge.sendRequestID + markUserSendRequested() and wires it from input-bar send actions to clear/prepare scroll state before the next user row appears.
  • Adjusts chatMessageListRowStyle() to apply padding on macOS, and aligns mobile/macOS pin animation timing constants.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
RxCodeMobile/Views/MobileChatView.swift Tweaks pin-to-top timing constants and the pin settle loop on mobile.
Packages/Sources/RxCodeChatKit/MessageListView.swift Implements macOS pin-to-top behavior, dynamic tail spacer measurement, and replaces List with ScrollView/LazyVStack.
Packages/Sources/RxCodeChatKit/InputBarView+Queue.swift Marks “send requested” for queued-send actions.
Packages/Sources/RxCodeChatKit/InputBarView.swift Marks “send requested” for normal send + certain slash command sends.
Packages/Sources/RxCodeChatKit/ChatMessageListView.swift Adds macOS padding to row styling to work outside of List.
Packages/Sources/RxCodeChatKit/ChatBridge.swift Adds sendRequestID and markUserSendRequested() hook for message containers.
Comments suppressed due to low confidence (1)

Packages/Sources/RxCodeChatKit/MessageListView.swift:530

  • logScrollState is called from high-frequency paths (scroll geometry updates and geometry-change callbacks) but logs at .info, which can generate a very large volume of logs during normal scrolling/streaming. This can impact performance and produce noisy production logs. Consider downgrading this to .debug and/or gating it behind #if DEBUG or a runtime flag, keeping .info for coarse lifecycle events only.
    private func logScrollState(_ label: String, extra: String = "") {
        let active = activeTurnUserMessageID?.uuidString ?? "<nil>"
        let latestTurnHeight = max(0, tailSpacerMinY - latestUserMinY) + pendingIndicatorSpacerReduction
        let extraSpacer = pinTailSpacerExtraHeight
        let suffix = extra.isEmpty ? "" : " \(extra)"
        Self.log.info(
            "[ScrollPin] \(label, privacy: .public) sid=\(windowState.currentSessionId ?? "<nil>", privacy: .public) active=\(active, privacy: .public) pinning=\(isPinningLatestTurnToTop) releaseArmed=\(canReleasePinnedTurnByScroll) userDriven=\(isUserDrivenScroll) stream=\(chatBridge.isStreaming) scrollH=\(Double(scrollViewHeight), privacy: .public) userY=\(Double(latestUserMinY), privacy: .public) tailY=\(Double(tailSpacerMinY), privacy: .public) turnH=\(Double(latestTurnHeight), privacy: .public) minTail=\(Double(minTailSpacer), privacy: .public) extraSpacer=\(Double(extraSpacer), privacy: .public) pendingReduce=\(Double(pendingIndicatorSpacerReduction), privacy: .public)\(suffix, privacy: .public)"
        )

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

Comment on lines +71 to +73
public func markUserSendRequested() {
sendRequestID = UUID()
}
Comment on lines +49 to +51
private static let streamingIndicatorEstimatedHeight: CGFloat = 36
private static let pinToTopAnimationDuration: Duration = .milliseconds(320)
private static let pinToTopAnimationSeconds: Double = 0.32
Comment on lines +118 to +119
private static let pinToTopAnimationDuration: Duration = .milliseconds(320)
private static let pinToTopAnimationSeconds: Double = 0.32
@sirily11 sirily11 merged commit 944a1c0 into main May 22, 2026
14 checks passed
@sirily11 sirily11 deleted the desktop-list branch May 22, 2026 07:16
@sirily11

Copy link
Copy Markdown
Contributor Author

🎉 This PR is included in version 1.10.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Labels

enhancement New feature or request released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants